-
Notifications
You must be signed in to change notification settings - Fork 260
Target Manager Programming Discussion
The ATF Target Manager Sample uses TargetEnumerationService and related components to manage targets. Targets are created by applications and are network endpoints, such as IP addresses, PS3™ and PS4™ DevKits, and PlayStation®Vita DevKits.
Target providers, such as TcpIpTargetProvider, discover and report targets of their specific type and these targets' parameters. Once found, you can edit and, in some cases, add and remove, targets, of that type with the provider. TargetEnumerationService enumerates all available target providers, combining the targets' information into a list view for displaying and editing.
TargetManager has very little code of its own, and relies on interfaces and classes in the Sce.Atf.Applications.NetworkTargetServices namespace for its operation. However, TargetManager does not use all of the interfaces and classes in this namespace. This namespace also supports creating and servicing targets, which TargetManager does not do. This article focuses on the items used by TargetManager in this namespace.
Several applications based on ATF create their own target managers similar to the TargetManager sample. These applications include the StateMachine and Scream tools.
TargetManager simply imports target related components to build the application. These components reside in the Sce.Atf.Applications.NetworkTargetServices namespace, which also contains an interface and classes that serve building targets.
Targets are classified by the type of the communication protocol used to communicate with the target. There are two protocols: TCP for x86, PS3™, and PS4™ targets, and Deci4p for PlayStation®Vita DevKits, and these describe the two types.
The classes and interfaces used can be divided into consumers and providers. Consumers use information from the providers, which compile a list of targets of each type. ITargetConsumer handles updating the target list user interface and provides a target list for the consumer. ITargetProvider enumerates targets for the particular provider and adds and removes targets.
The consumer is TargetEnumerationService, implementing ITargetConsumer. This component creates a ListView control for the targets and their information, embodied in the TargetInfo class.
The providers are TcpIpTargetProvider and Deci4pTargetProvider, both implementing ITargetProvider. These manage the list of targets: editing, and for TcpIpTargetProvider, adding, and removing them. TCP targets are added by users; Deci4p are discovered by the provider. These classes inform the user when changes occur so the target display list can be updated.
TargetCommands creates the context menu commands on the ListView control and is their command client.
There is one interface for target consumers, another for providers.
ITargetConsumer is for classes that consume network target information, such as TargetEnumerationService, which implements this interface. Such classes usually provide a user interface to view and edit targets. ITargetConsumer consists of the following:
-
TargetsChanged(): Updates changed targets for a given provider. -
SelectedTargets: Gets or sets an enumeration of the selected targets in the consumer, if any, as anIEnumerable<TargetInfo>. TheTargetInfoclass describes target information. For details, see TargetInfo Class. -
AllTargets: Gets all targets in the consumer as anIEnumerable<TargetInfo>
ITargetProvider provides information about a particular kind of target available on the network, such as a TCP accessible device. Its methods and properties access the providers of this type:
-
Name: Get the provider name. -
GetTargets(): Get an enumeration of theTargetInfofor all the targets. -
CanCreateNew: Get whether a new target can be created. -
CreateNew(): Create a new target, returning itsTargetInfo. -
AddTarget(): Add a new target with the givenTargetInfo. -
Remove(): Remove the target with the givenTargetInfo.
TargetEnumerationService is a MEF component that does the following:
- Imports the available target providers created by the host application.
- Creates a
ListViewwith target information. - Acts as control host client for this
ListViewcontrol. For details, see Control Host Client. - Implements
ITargetConsumer.
TargetEnumerationService imports all components implementing ITargetProvider, so that it can display their information:
[ImportMany]
private IEnumerable<ITargetProvider> m_targetProviders= null;The field m_targetProviders is get or set in the TargetProviders property.
Providers implemented in the ATF framework include the Deci4pTargetProvider and TcpIpTargetProvider components. More such providers could be added. For the discussion of target providers, see Target Provider Classes.
The component's IInitializable.Initialize() method calls SetUpTargetsView() to create a targets display control, which can be used as a docked control or a stand alone dialog:
void IInitializable.Initialize()
{
// force creation of the window handles on the GUI thread
// see http://forums.msdn.microsoft.com/en-US/clr/thread/fa033425-0149-4b9a-9c8b-bcd2196d5471/
var handle = MainForm.Handle;
var control = SetUpTargetsView();
if (!ShowAsDialog)
{
m_controlHostService.RegisterControl(
control,
new ControlInfo(
"Targets".Localize(),
"Controls for managing targets.".Localize(),
StandardControlGroup.Bottom),
this);
}
if (m_settingsService != null)
{
m_settingsService.RegisterSettings(this,
new BoundPropertyDescriptor(this, () => PersistedUISettings, "UI Settings".Localize(), null, null));
m_settingsService.RegisterSettings(this,
new BoundPropertyDescriptor(this, () => PersistedSelectedTargets, "Selected Targets".Localize(), null, null));
}
}SetUpTargetsView() creates and configures a DataBoundListView, which extends ListView with data binding and cell editing functionality. If the control is not a dialog, it's registered with the Control Host Service. Settings in the control that persist between sessions are registered with the Settings Service. The properties PersistedUISettings and PersistedSelectedTargets get and set persistent values.
TargetEnumerationService also imports context menu providers for its context menu:
[ImportMany]
private IEnumerable<Lazy<IContextMenuCommandProvider>> m_contextMenuCommandProviders;Menu items for the control are provided by the TargetCommands component, which implements IContextMenuCommandProvider. For details, see TargetCommands Component.
The bulk of the code in TargetEnumerationService creates the DataBoundListView control and handles its events. For example, the CellValidating event is raised when one of the cells of the DataBoundListView changes; the listView_CellValidating() event handler validates the change.
This client is very simple. The only method that does anything is Activate(), which brings focus to the DataBoundListView control to interactively select and edit targets.
The ITargetConsumer.TargetsChanged() method updates the target view in the DataBoundListView control. All target providers call TargetsChanged() when a target is added, removed, or changed so the target display stays current.
The properties SelectedTargets and AllTargets get known targets as an IEnumerable<TargetInfo>. SelectedTargets can also set the target selection.
Target providers manage targets that are using a given type of communications protocol. Deci4p is a proprietary protocol handling the PlayStation®Vita DevKit. Everything else, x86, PS3™, and PS4™, is handled by TCP.
This section discusses the target provider components and their auxiliary classes.
TargetInfo encapsulates target information in its gettable and settable properties, which are all string values except for Scope:
-
Name: Target name. -
Platform: Type of platform the target can run on, such as as "Ps3" or "Vita". -
Endpoint: Network endpoint in string format; an IP address for TCP. -
Protocol: Type of protocol the target can use. Currently, this is either "Tcp" or "Deci4p". -
Scope:TargetScopeenumeration indicating how the target is persisted for applications that use TargetManager:-
PerApp: Save target data for the current application. All users on this computer see this target when they run this application. Other applications that use TargetManager do not see this target. This is the default value for TCP targets. -
PerUser: Save target data for the current user. Other applications that use the TargetManager can see this target for this user; other users won't see this target in any application. -
AllUsers: Save the target data for all users and applications, so this target is visible for all users in any application that uses the TargetManager framework.
-
TargetInfo implements INotifyPropertyChanged, which contains one event, PropertyChanged. It has the method OnPropertyChanged() that simply raises this event.
TargetInfo has two ATF classes that derive from it, described in the next sections.
TcpIpTargetInfo describes TCP target information, and is used by TcpIpTargetProvider. TcpIpTargetInfo contains methods to verify that the IP address provided is valid. Its Validate() method checks this, as well as the other properties, and is called by TargetEnumerationService when any properties change in a TCP target listed.
TcpIpTargetInfo also has derived classes:
-
X86TargetInfo: X86 target information. -
Ps3TargetInfo: PS3™ target information. -
Ps4TargetInfo: PS4™ target information.
Ps3TargetInfo:
public Ps3TargetInfo()
: base()
{
Name = "Ps3Host";
Platform = PlatformName;
Endpoint = "10.89.0.0:1338";
}Deci4pTargetInfo holds information about a Deci4p target and is used by Deci4pTargetProvider in its process of finding active targets of this type.
TargetManager imports the TcpIpTargetProvider component, which is one of the two providers implementing ITargetProvider.
TCP targets are not found; they are added by users. The list of targets is persisted using the Setting Service to save the list between sessions. This requires using the Setting Service to set the saved values when a target changes and to read the saved values when the application starts. The PersistedTargets property gets and sets the persisted targets list.
The ITargetProvider implementation manipulates the target list. For instance, GetTargets() retrieves objects from the targets list in m_targets:
public IEnumerable<TargetInfo> GetTargets(ITargetConsumer targetConsumer)
{
foreach (var target in m_targets)
yield return target;
}CreateNew() returns a new TcpIpTargetInfo:
public virtual TargetInfo CreateNew()
{
var newTarget = new TcpIpTargetInfo();
return newTarget;
}AddTarget() adds the given target to the list and calls TargetsChanged() to inform each target consumer so its lists can be updated:
public bool AddTarget(TargetInfo target)
{
if (target is TcpIpTargetInfo && !m_targets.Contains(target))
{
m_targets.Add(target);
foreach (var targetConsumer in TargetConsumers)
targetConsumer.TargetsChanged(this, m_targets);
return true;
}
return false;
}TcpIpTargetProvider imports as many ITargetConsumer implementers as it can find to populate its TargetConsumers property, which is used in AddTarget():
[ImportMany]
protected IEnumerable<ITargetConsumer> TargetConsumers { get; set; }Finally, TcpIpTargetProvider has its own derived classes to match up with TcpIpTargetInfo's derived classes:
-
X86TargetProvider: X86 target provider. -
Ps3TargetProvider: PS3™ target provider. -
Ps4TargetProvider: PS4™ target provider.
Ps3TargetProvider has two gettable string properties and a CreateNew() method that constructs and returns a Ps3TargetInfo:
public class Ps3TargetProvider : TcpIpTargetProvider
{
/// <summary>
/// Gets the provider's user-readable name</summary>
public override string Name { get { return "PS3 Target".Localize(); } }
/// <summary>
/// Gets the the identifier of the provider</summary>
/// <returns>A string that contains the identifier.</returns>
public override string Id { get { return @"Sce.Atf.Ps3TcpIpTargetProvider"; } }
/// <summary>
/// Creates a new target</summary>
/// <remarks>Creates and returns a TargetInfo, but does not add it to the watched list</remarks>
/// <returns>TargetInfo for new target</returns>
public override TargetInfo CreateNew()
{
var newTarget = new Ps3TargetInfo();
return newTarget;
}
}TargetManager also imports the Deci4pTargetProvider component, one of the two providers implementing ITargetProvider. This supports only the PlayStation®Vita platform.
Unlike TCP targets, you can't create targets — PlayStation®Vita targets can only be discovered. Its IInitializable.Initialize() method starts a background task in another thread to attempt to find these targets with its FindTargets() method, adding them to a list as they are found. FindTargets() only works if you have installed the PlayStation®Vita SDK on your local computer.
This limitation makes ITargetProvider's implementation rudimentary. Name always gets "Vita Target". CanCreateNew gets false. CreateNew() throws an exception. Both AddTarget() and Remove() do nothing but return false. GetTargets() does return the list of targets found.
Deci4pTargetProvider also imports as many ITargetConsumer implementers as it can find to update the target display of each consumer:
[ImportMany(typeof(ITargetConsumer))]
protected IEnumerable<ITargetConsumer> TargetConsumers { get; set; }TargetCommands adds the context menu commands for the targets list control, providing the command client for these commands, so it implements ICommandClient:
public class TargetCommands : ICommandClient, IContextMenuCommandProvider, IInitializableTo create the right commands, TargetCommands needs to know which target providers are available. It does so by importing all exported ITargetProvider and accessing them with TargetProviders:
[ImportMany]
private IEnumerable<ITargetProvider> m_targetProviders = null;
/// <summary>
/// Gets or sets the target providers</summary>
public IEnumerable<ITargetProvider> TargetProviders
{
get { return m_targetProviders; }
set { m_targetProviders = value; }
}TargetCommands's IInitializable.Initialize() creates the commands, based on available targets:
void IInitializable.Initialize()
{
if (CommandService == null)
return;
if (Deci4pTargetProvider.SdkInstalled)
{
var cmdInfo = new CommandInfo(
CommandTag.VitaNeighborhood,
null,
null,
"Edit Vita Target in Neighborhood".Localize(),
"Edit Vita Target in Neighborhood".Localize());
cmdInfo.ShortcutsEditable = false;
CommandService.RegisterCommand(cmdInfo, this);
}
foreach (var targetProvider in TargetProviders)
{
if (targetProvider.CanCreateNew)
{
string addCmdTag = AddNewString.Localize() + targetProvider.Name;
CommandService.RegisterCommand(
new CommandInfo(
addCmdTag,
null,
null,
addCmdTag,
"Creates a new target".Localize()),
this);
m_addTargetsCmdTags.Add(addCmdTag);
string remCmdTag = "Remove ".Localize() + targetProvider.Name;
CommandService.RegisterCommand(
new CommandInfo(
remCmdTag,
null,
null,
remCmdTag,
"Remove selected target".Localize()),
this);
m_removeTargetsCmdTags.Add(remCmdTag);
}
}
}Deci4p target providers are treated differently than TCP target providers. First, the method checks that a PlayStation®Vita SDK is installed with the Deci4pTargetProvider.SdkInstalled property. If present, it adds a command to edit PlayStation®Vita targets.
Next, Initialize() iterates through TargetProviders to create commands to add and remove targets for each provider. It first checks the CanCreateNew for the provider to make sure that new targets can be created; they can't for PlayStation®Vita, because Deci4pTargetProvider's property is this:
public bool CanCreateNew { get { return false; } }As a result, Add and Remove commands are created only for TcpIpTargetProvider. The general loop is used, so other types of providers can be added easily.
This interface provides a method to get commands that apply to a given context:
IEnumerable<object> IContextMenuCommandProvider.GetCommands(object context, object selectedTargets)
{
m_selectedTargets = null;
if (context.Is<ITargetConsumer>())
{
m_targetConsumer = context.Cast<ITargetConsumer>();
m_selectedTargets = selectedTargets as IEnumerable<TargetInfo>;
foreach (var cmdTag in m_addTargetsCmdTags)
yield return cmdTag;
if (m_selectedTargets != null && m_selectedTargets.Any())
foreach (var cmdTag in m_removeTargetsCmdTags)
yield return cmdTag;
yield return CommandTag.VitaNeighborhood;
}
}The commands are available only for the target list control provided by TargetEnumerationService, the only implementer of ITargetConsumer, so the method first checks that the given context can be adapted to ITargetConsumer. If so, it proceeds and saves this context adapted to ITargetConsumer in m_targetConsumer, where it is used later to test whether a command can be performed.
Next, the selected objects are adapted to IEnumerable<TargetInfo> and saved in the field m_selectedTargets, which is used to test whether commands can be performed and to perform commands. Targets are treated as TargetInfo objects in TargetManager, so this adaptation works.
Finally, GetCommands() iterates through the lists m_addTargetsCmdTags and m_removeTargetsCmdTags of commands created in Initialize(). Remove commands are only returned when there are targets selected, hence the m_selectedTargets \!= null && m_selectedTargets.Any() test.
The ICommandClient implementation uses the TargetProviders property and field values like m_addTargetsCmdTags, already set up by Initialize() and IContextMenuCommandProvider.GetCommands(). For example, here's DoCommand():
void ICommandClient.DoCommand(object commandTag)
{
if (CommandTag.VitaNeighborhood.Equals(commandTag))
{
// Invoke "Edit Vita Target in Neighborhood" command merely launches the PSP2 Neighborhood app that comes with Vita SDK installer,
// as if you double click "Neighborhood for PlayStation(R)Vita" on your desktop icon.
// This is intended just for a convenience helper to allow users directly bring up the PSP2 app without a detour to desktop first,
// as PSP2 Neighborhood app can reboot, power off, and do much more for the Vita kit.
// {BA414141-28C6-7F3C-45FF-14C28C11EE88} is the registered Neighborhood for PlayStation(R)Vita Shell extension
System.Diagnostics.Process.Start("Explorer.exe", @"/e,/root,::{BA414141-28C6-7F3C-45FF-14C28C11EE88}");
}
else if (m_addTargetsCmdTags.Contains(commandTag))
{
foreach (var targetProvider in TargetProviders)
{
string addCmdTag = AddNewString.Localize() + targetProvider.Name;
if (addCmdTag.Equals(commandTag))
{
targetProvider.AddTarget(targetProvider.CreateNew());
break;
}
}
}
else if (m_removeTargetsCmdTags.Contains(commandTag))
{
foreach (var item in m_selectedTargets)
foreach (var provider in TargetProviders)
provider.Remove(item);
}
}The commandTag parameter is matched against existing commands in the command lists, and if a match is found, the corresponding command is executed. The Add command logic does additional processing to find the right target provider for the command and uses the target provider's AddTarget() method to add the target. The Remove processing tries to remove each selected target with each target provider's Remove() method, relying on it to do the right thing. Deci4pTargetProvider.Remove() does nothing — PlayStation®Vita targets can't be added or removed, only discovered — so that's not a problem. And TcpIpTargetProvider.Remove() checks that the target is one of the TCP targets, so that works also.
- Circuit Editor Programming Discussion: Learn how ATF handles graphs, and provides editors for kinds of graphs, such as circuits.
- Code Editor Programming Discussion: Shows how to interface third party software to an ATF application: the ActiproSoftware SyntaxEditor.
- Diagram Editor Programming Discussion: Very simply combines components from the CircuitEditor, FsmEditor, and StateChartEditor samples into one application, with the abilities of all three, showing the power of components.
-
DOM Property Editor Programming Discussion: Shows how to use the ATF DOM with an XML Schema to define application data with a large variety of attribute types, whose values can be viewed and edited using the ATF
PropertyEditorcomponent, using various value editors to view and edit attributes. - DOM Tree Editor Programming Discussion: Shows how to edit DOM data using a tree control and display properties in a variety of value editors.
- File Explorer Programming Discussion: Discusses the ATF File Explorer Sample using list and tree controls with adapters.
- FSM Editor Programming Discussion: Tells you about how the ATF FSM Editor Sample edits simple graphs for state machines, using DOM adapters for contexts and validation.
-
Model Viewer Programming Discussion: Shows how the ATF Model Viewer Sample is written, discussing how ATGI and Collada model data is handled, using rendering components, and using a
DesignControlas a canvas for rendering. -
Simple DOM Editor Programming Discussion: Programming the ATF Simple DOM Editor Sample, creating a palette, using DOM adapters and contexts, editing application data, and searching
DomNodes. - Simple DOM Editor WPF Programming Discussion: Programming the ATF Simple DOM Editor WPF Sample, which is similar to ATF Simple DOM Editor Sample, but implemented using ATF's WPF framework.
- Simple DOM No XML Editor Programming Discussion: Programming the ATF Simple DOM No XML Editor Sample, which is very similar to ATF Simple DOM Editor Sample, except that it doesn't use XML for either its data model or persisting application data.
- State Chart Editor Programming Discussion: Shows using ATF graph and other classes to create a statechart editor, using DOM adapters, documents, contexts, and validators.
- Target Manager Programming Discussion: Description of how a target manager is implemented using ATF components to manage target devices, such as PlayStation®Vita or PS3™ consoles. A target manager is used in other tools, such as the StateMachine tool.
- Timeline Editor Programming Discussion: Discusses how to create a fairly full-featured timeline editor using the ATF timeline facilities, such as the timeline renderer and the timeline control and its manipulators.
-
Tree List Control Programming Discussion: Demonstrates using the
TreeListControlandTreeListItemRendererclasses to display and edit hierarchical data in a tree view with details in columns. -
Tree List Editor Programming Discussion: Demonstrates how to use the ATF tree controls
TreeListViewand its enhancement,TreeListViewEditor.TreeListViewusesTreeListViewAdapter, which adaptsTreeListViewto display data in a tree. - Using Dom Programming Discussion: Shows how to use the various parts of the ATF DOM: an XML Schema, a schema metadata class file generated by DomGen, DOM adapters for the data types, a schema loader, and saving application data to an XML file.
- Home
- Getting Started
- Features & Benefits
- Requirements & Dependencies
- Gallery
- Technology & Samples
- Adoption
- News
- Release Notes
- ATF Community
- Searching Documentation
- Using Documentation
- Videos
- Tutorials
- How To
- Programmer's Guide
- Reference
- Code Samples
- Documentation Files
© 2014-2015, Sony Computer Entertainment America LLC