[programmer/prog-manager.tex] \section{Introduction} %this chapter covers the manager API description \index{Core classes !dabc::Manager} The \class{dabc::Manager} is the central singleton object of the \dabc~ framework. It combines a number of different roles, such as: \bcir \item objects manager; \item memory pools manager; \item threads manager; \item commands dispatcher; \item run control state manager; \item plug-in manager for factories and application; \item implementation of control and configuration system \ecir Although these functionalities internally could as well be treated in separate classes, \class{dabc::Manager} class defines the common application programmer's interface to access most of these features. Since the manager is a singleton, these methods are available everywhere in the user code by means of the static handle \func{dabc::mgr()->}. The following section \ref{prog_manager_framework} describes such interface methods to be used by the programmer of the \class{Module}, \class{Transport}, \class{Device}, and \class{Application} classes. In contrast to this, section \ref{prog_manager_controls} gives a guide how to re-implement the \class{Manager} class itself for a different control and configuration system. This should be seldomly necessary for the common DAQ designer, but is added here as a reference and as useful insight into the \dabc~ mechanisms. \section{Framework interface} \label{prog_manager_framework} %here description of mostly used methods to be called from application, modules, etc. \subsection{General object management} \label{prog_manager_framework_objects} All objects are organized in a folder structure and can be accessed by the full path name. However, for most purposes it is recommended to rather use higher level \class{Manager} methods to cause some action(e.~g.~ \func{StartModule()}) than to work directly with the primitive objects. \begin{description} \item[\em Module* FindModule\small (const char* name)] : Access to a \class{Module} by name. Returns $0$ if module does not exist. \item[\em Port* FindPort\small (const char* name)]: Access to a \class{Port} by name. Returns $0$ if port does not exist. \item[\em Device* FindDevice\small (const char* name)] : Access to a \class{Device} by name. Returns $0$ if device does not exist. \item[\em Device* FindLocalDevice()] : Shortcut to get the "local device" that is responsible for basic transport mechanisms like transport of buffers through the local memory. \item[\em Factory* FindFactory\small (const char* name)] : Access to a \class{Factory} by name. Returns $0$ if factory does not exist. \item[\em WorkingThread* FindThread\small (const char* name, const char* required\_class = 0)] : Access to a \class{WorkingThread} by name. The \func{required\_class} string may be specified to check if the working thread implementation matches the client intentions. Returns $0$ if thread object does not exist, or if it does not fullfill \func{required\_class}. \item[\em Application* GetApp()] : Access to the unique \class{Application} Object of this node. \end{description} \subsection{Factory methods} Since all \dabc~ objects are provided by \class{dabc::Factory} plug-ins, the application programmer needs to invoke corresponding factory methods to instantiate them. However, the factories themselves should not be accessed by the user code (although the \class{Manager} offers a getter method, see section \ref{prog_manager_framework_objects}). Instead, creation and registration of the key objects, like \class{Module} or \class{Device}, is done transparently by the \class{Manager} within specific creation methods. These will scan over all existing factories whether the corresponding factory method can provide an object of the requested class name. In this case the object is created, kept in the object manager, and may be addressed by its full name later. \begin{description} \item[\em bool CreateModule\small (const char* classname, const char* modulename, const char* thrdname = 0)] : \index{Manager interface !CreateModule()} Instantiate a \class{Module} of class \func{classname} with the object name \func{modulename}. Optionally, the name of the working thread \func{thrdname} may be specified that shall run this module. If a thread of this name is already exisiting, it will be also applied for the new module; otherwise, a new thread of the name will be created. If \func{thrdname} is not defined, \dabc~ will use module name for it. Returns \keyw{true} or \keyw{false} depending on the instantiation success. \item[\em bool CreateDevice\small (const char* classname, const char* devname)]: \index{Manager interface !CreateDevice()} Instantiate a \class{Device} of class \func{classname} with the object name \func{devname}. Returns \keyw{true} or \keyw{false} depending on the instantiation success. % \item[\em WorkingThread* CreateThread(const char* thrdname, const char* classname = 0, unsigned startmode = 0, const char* devname = 0, Command* cmd = 0)] : \item[\em bool CreateTransport\small (const char* portname, const char* transportkind, const char* thrdname = 0)] : \index{Manager interface !CreateTransport()} Instantiate a \class{Transport} of the specified kind \func{transportkind} (e.~g.~ "mbs::ServerTransport") and connect it to the port of full name \func{portname} (e.~g.~ "Readout/Input1"). Kind can specify device name, which than create appropriate transport instance. Optionally the name of the working thread \func{thrdname} may be specified that shall run this transport. If a thread of this name is already exisiting, it will be also applied for the new transport; otherwise, a new thread of the name will be created. If \func{thrdname} is not defined, \dabc~ will use a new thread automatically with an internal name. Returns \keyw{true} or \keyw{false} depending on the instantiation success. % \item[\em FileIO* CreateFileIO\small (const char* typ, const char* name, int option)] : % \index{Manager interface !CreateFileIO()} % Returns a new \class{FileIO} of type \func{typ} (e.~g.~ "posix") with name % \func{name}. The \func{option} value may define the file access option, % e.~g.~ \keyw{ReadOnly}, \keyw{ReadWrite}, \keyw{WriteOnly}, \keyw{Create}, and % \keyw{Recreate}. Current standard implementation is \\ % \class{dabc::PosixFileIO} % which is provided in the manager by default. % Returns $0$ if instantiation of desired type fails. \item[\em bool CreateApplication\small (const char* classname = 0, const char* appthrd = 0)] : \index{Manager interface !CreateApplication()} Instantiate the \class{Application} of class \func{classname}. Optionally the name \func{appthrd} of the main application thread may be specified. Used in the \func{main()} function of the \dabc~ runtime executable on inititialization time. \end{description} \subsection{Module manipulation} \begin{description} \item[\em void StartModule\small (const char* modulename)] : \index{Manager interface !StartModule()} Enables the module of name \func{modulename} for processing. Depending on the \class{Module} type (synchronous or asynchronous, see section \ref{prog_overview_modules}), this will start execution of the \func{MainLoop()}, or activate processing of the queued events belonging to this module, resp. \item[\em void StopModule\small (const char* modulename)] : \index{Manager interface !StopModule()} Disables processing for the module of name \func{modulename}. \item[\em bool StartAllModules\small (int appid = 0)] : \index{Manager interface !StartAllModules()} Enables processing for all modules with apllication identifier number \func{appid}. The optional identifier may be set in the \func{Module} definition to select different kinds of modules here. By default, this method will start all exisiting modules on this node. Returns \keyw{true} of \keyw{false} depending on success. \item[\em bool StopAllModules\small (int appid = 0)] : \index{Manager interface !StopAllModules()} Disables processing for all modules with application identifier number \func{appid}. The optional identifier may be set in the \func{Module} definition to select different kinds of modules here. By default, this method will stop all exisiting modules on this node. Returns \keyw{true} of \keyw{false} depending on success. \item[\em bool DeleteModule\small (const char* modulename)] : \index{Manager interface !DeleteModule()} Deletes the module of name \func{modulename}. Returns \keyw{true} of \keyw{false} depending on the deletion success. \item[\em bool IsModuleRunning\small (const char* modulename)] : \index{Manager interface !IsModuleRunning()} Method returns \keyw{true} if module of name \func{modulename} is running, i.~e.~ its processing is enabled. If module does not exist or is not active, \keyw{false} is returned. \item[\em bool IsAnyModuleRunning()] : \index{Manager interface !IsAnyModuleRunning()} Method returns \keyw{false} if \strong{no} exisiting module is running anymore. Otherwise returns \keyw{true}. \item[\em bool ConnectPorts\small (const char* port1name, const char* port2name, const char* devname=0)] : \index{Manager interface !ConnectPorts()} \\ Connects module \class{Port} of full name \func{port1name} with another module \class{Port} of full name \func{port2name}. A full port name consists of the module name and a local port name, separated by forward slash, e.~g.~ "Readout3/Output", "CombinerModule/Input2". Optionally the \class{Device} name for the connection may be defined with argument \func{devname}. By default, the ports are connected with a FIFO-like transport of queued \class{Buffer} references in local memory, as managed by \class{dabc::LocalDevice}. \end{description} \subsection{Thread management} \begin{description} \item[\em bool MakeThreadForModule\small (Module* m, const char* thrdname = 0) ] : \index{Manager interface !MakeThreadForModule()} \\ Creates a thread for module \func{m} and assigns module to this thread. If thread name \func{thrdname} is not specified, module name is used. Returns \keyw{true} of \keyw{false} depending on success. \item[\em bool MakeThreadFor\small (WorkingProcessor* proc, const char* thrdname = 0, unsigned startmode = 0) ] : \index{Manager interface !MakeThreadFor()} Creates thread for processor \func{proc} and assigns processor to this thread. If thread name \func{thrdname} is not specified, a default name is used. Value of \func{startmode} specifies initial run state of the thread (currently, thread is started if $startmode>0$). %Thread name must be specified \end{description} \subsection{Command submission} \label{prog_manager_framework_commands} \begin{description} \item[\em bool Submit\small (Command* cmd)] : \index{Manager interface !Submit()} This method generally submits a command \func{cmd} for execution. The command is put in the queue of its command receiver working thread and is then asynchronously executed there. The \class{Manager} will either forward the command to its receiver, if such is specified as command parameter; or the \class{Manager} working thread itself will execute the command. Thus method does not block and returns \keyw{true} if it accepts the command for execution, otherwise \keyw{false}. Manager commands queue can also be used to submit command not only direct for manager, but also for any other object on local or remote node. For that one from several following functions \func{SetCmdReceiver} should be used. \item[\em Command* SetCmdReceiver\small (Command* cmd, const char* itemname)] : \item[\em Command* SetCmdReceiver\small (Command* cmd, Basic* rcv)] : \item[\em Command* SetCmdReceiver\small (Command* cmd, const char* nodename, const char* itemname)] : \item[\em Command* SetCmdReceiver\small (Command* cmd, int nodeid, const char* itemname)] : \index{Manager interface !SetCmdReceiver()} Set receiver attribute of command \func{cmd}. The \func{itemname} is item name of the local node like "Module1". One can also specify \func{nodename} or \func{nodeid} of the node, to which command should be submitted. Returns pointer on the command itself. One can use \func{SetCmdReceiver} to submit command like: \begin{small} \begin{verbatim} dabc::mgr()->Submit(dabc::SetCmdReceiver(cmd, "Module1")); dabc::mgr()->Submit(dabc::SetCmdReceiver(cmd, "Node1", "Module1")); dabc::mgr()->Submit(cli.Assign(dabc::SetCmdReceiver(cmd, 0, "Module1"))); \end{verbatim} \end{small} \end{description} \subsection{Memory pool management} \begin{description} \item[\em bool CreateMemoryPool] {\small \bf\em (} \\ {\small \bf\em const char* poolname, unsigned buffersize, unsigned numbuffers, \\ unsigned numincrement, unsigned headersize, unsigned numsegments)} : \index{Manager interface !CreateMemoryPool()} Instantiates a \class{dabc::MemoryPool} of name \func{poolname}, with \func{numbuffers} buffers of size \func{buffersize}. If a pool of this name already exists, it will be extended. The \func{numincrement} value specifies with how many buffers at once the memory pool can optionally be extended on the fly. Optional arguments \func{headersize} and \func{numsegments} may define the buffer header size, and the partition of the buffer segments, resp. The \class{MemoryPool} mechanisms are discussed in detail in section \ref{prog_services_memory}. Method returns true or false depending on success. \item[\em MemoryPool* FindPool\small (const char* name)] : \index{Manager interface !FindPool()} Access to memory pool by name \func{name}. Returns 0 if not found. \item[\em bool DeletePool\small (const char* name)] : \index{Manager interface !DeletePool()} Delete memory pool of name \func{name}. Returns true or false depending on success. \end{description} \subsection{Miscellaneous methods} \begin{description} \item[\em bool CleanupManager\small (int appid = 0) ] : \index{Manager interface !CleanupManager()} Safely deletes all modules, memory pools and devices with specified application id \func{appid}. The default id 0 effects on all user components. In the end all unused threads are also destroyed. \item[\em virtual void DestroyObject\small (Basic* obj)] : \index{Manager interface !DestroyObject()} Deletes the referenced object \func{obj} in manager thread. Useful as safe replacement for call "delete this". \item[\em void Print()] : \index{Manager interface !Print()} Displays list of running threads and modules on \keyw{stdout}. \end{description} \section{Control system plug-in} \label{prog_manager_controls} For the common \dabc~ usage, the provided standard control and configuration system, featuring DIM protocol \cite{DIM}, XML setup files, and a generic Java GUI, will probably be sufficient. However, if e.~g.~ an experiment control system is already existing and the data acquisition shall be handled with the same means, it might be necessary to adjust \dabc~ to another controls and configuration framework. Moreover, future developments may replace the current standard control system by a more powerful, or a more convenient one. Because of this, the connection between the \dabc~ core system and the control system implementation was designed with a clear plug-in interface. Again the \class{dabc::Manager} class plays here a key role. This section covers all methods and mechanisms for the control system plug-in. As an example, part \ref{prog_manager_controls_DIM} describes in detail the standard implementation as delivered with the \dabc~ distribution . \subsection{Factory} \label{prog_manager_controls_factory} A new control system plug-in is added into \dabc~ by means of a \class{dabc::Factory} subclass that defines the method \func{bool CreateManagerInstance(const char* kind, dabc::Configuration* cfg)}. This method should create the appropriate \class{dabc::Manager} instance and return \keyw{true} if the name \func{kind}, as specified by the runtime environment, matches the implementation. The default \dabc~ runtime executable will also pass a configuration object \func{cfg} read from an XML file which may be passed to the constructor of the \class{Manager}. As it's mandatory for other \dabc~ factories, the \class{dabc::Factory} for the manager must be instantiated as global object in the code that implements it. This assures that the factory exists in the system on loading the corresponding library. \subsection{Manager} \label{prog_manager_controls_manager} Besides its role as a central singleton to access framework functionalities, the \class{dabc::Manager} is also the interface base class for the control and configuration system that is applied with \dabc~. \subsubsection{Virtual methods} The \class{dabc::Manager} defines several virtual methods concerning the {\em finite state machine}, the registration and subscription of parameters, the command communication in-between nodes, and the management of a DAQ cluster, resp. These methods have to be implemented for differrent kinds of control systems in an appropriate subclass and are described as follows: %\begin{compactdesc} \begin{description} \item[\em Manager(const char* managername, bool usecurrentprocess, Configuration* cfg)] : The constructor of the subclass. The recommended parameters are passed from the manager factory (see section \ref{prog_manager_controls_factory}) to the baseclass constructor, such as the object name of the manager; optionally a flag indicating to use either the main process or another thread for manager command execution; and an optional configuration object \func{cfg}. \begin{compactenum} \item The constructor should initialize the control system implementation. \item If the default state machine module of the \dabc~ core is used, the constructor should invoke method \func{InitSMmodule()}. Otherwise, the constructor must initialize an external state machine of the control system, following the state and transition names defined as static constants in {\tt dabc/Manager.h}. \item The constructor must call method \func{init()} to initialize the base functionalities and parameters. This should be done {\em after} the control system is ready for handling parameters and commands, and {\em after} the optional \func{InitSMmodule()} call. \end{compactenum} \item[\em\~{~}Manager()] : The destructor of the subclass. It should cleanup and remove the control system implementation. It must call method \func{destroy()} at the end. \item[\em bool InvokeStateTransition(const char* state\_transition\_name, Command* cmd)] : \index{Manager interface !InvokeStateTransition()} This should initiate the state transition for the given \func{state\_transition\_name}. This \strong{must} be an asynchronous function that does not block the calling thread, possibliy the main manager thread if the state transition is triggered by a command from a remote "master" state machine node. Thus the actual state transition should be performed in a dedicated state-machine thread, calling the synchronous method \func{DoStateTransition(const char*)} of the base class (see section \ref{prog_manager_controls_base}). Synchronization of the state with the invoking client is done by the passed command object reference \func{cmd}. This should be used as handle in the static call \func{dabc::Command::Reply(cmd,true)} when the state transition is completed, or \func{dabc::Command::Reply(cmd,false)} when the transition has been failed, resp. Note that base class \class{dabc::Manager} already implements this method for the \dabc~ default state machine module which is activated in the manager constructor with \func{InitSMmodule()}. \strong{It needs a re-implementation only if an external state machine shall be used.} \item[\em void ParameterEvent(dabc::Parameter* par, int event)] : \index{Manager interface !ParameterEvent()} Is invoked by the framework when any \class{Parameter} is created (argument value $event=parCreated=0$), changed ($event=parModified=1$), or destroyed ($event=parDestroy=2$), resp. Pointer \func{par} should be used to access parameter name and value for export to the control system. \item[\em void CommandRegistration(dabc::Module* m, dabc::CommandDefinition* def, bool reg)] : \index{Manager interface !CommandRegistration()} Is invoked by the framework when any module exports (argument \func{reg} \keyw{true}), or unexports (argument \func{reg} \keyw{false}) a command definition object to, or from the control system, resp. This allows to invoke such commands via the controls connection from a remote node. The command definition object \func{def} contains a description of possible command parameters; pointer \func{m} should be used to access the owning module and get its name. This information may be used to represent the command within the controls implementation. \item[\em bool Subscribe(dabc::Parameter* par, int remnode, const char* remname)] : \index{Manager interface !Subscribe()} This method shall link the value of a local parameter \func{par} to a remote parameter of name \func{remname} that exists on node number \func{remnode} of the DAQ cluster. Control system implementation may use a publisher-subscriber mechanism here to update the local subscription whenever the remote parameter changes its value. The actual update handler must call method \func{InvokeChange(const char* val)} of the local \func {dabc::Parameter* par} then. The new value \func{val} is passed to the parameter which will change itself appropriately. This decouples the parameter change from the invoking control system callback in a thread-safe manner. \item[\em bool Unsubscribe(dabc::Parameter* par)] : \index{Manager interface !Unsubscribe()} The subscription of a local parameter \func{par} to a remote paramter by a formerly called \func{Subscribe()} is removed from the control system. \item[\em bool IsMainManager()] : \index{Manager interface !IsMainManager()} Should return \keyw{true} if this node is the single master controller node of the DAQ cluster. This node will define the master state machine that rules the states of all other nodes. Otherwise (returns \keyw{false}) this node is a simple worker node. The node properties should be taken from the configuration. \item[\em bool HasClusterInfo()]: \index{Manager interface !HasClusterInfo()} Returns \keyw{true} if this node has complete information of the DAQ cluster. \item[\em int NumNodes()] : \index{Manager interface !NumNodes()} Returns the number of all DAQ nodes in the cluster. This may be taken from a configuration database, e.~g.~ an XML file, but may also test the real number of running nodes each time it's called. \item[\em int NodeId() const] : \index{Manager interface !NodeId()} Returns the unique id number of this node in the DAQ cluster. This should be taken from the cluster configuration. \item[\em bool IsNodeActive(int num)] : \index{Manager interface !IsNodeActive()} Returns \keyw{true} if DAQ cluster node of id number \func{num} is currently active, otherwise \keyw{false}. This may allow to check on runtime if some of the configured nodes are not available and should be excluded from the DAQ setup. \item[\em const char* GetNodeName(int num)] : \index{Manager interface !GetNodeName()} For each DAQ cluster node of id number \func{num}, this method must define a unique name representation. The name should represent the node in a human readable way, e.~g.~ by means of URL and a functional node description ("daq01.gsi.de-readout"). It should match the description in the cluster configuration. Note: \strong{This name must match the local name of the manager object on each node}. \item[\em bool SendOverCommandChannel(const char* managername, const char* cmddata)] : \index{Manager interface !SendOverCommandChannel()} \\ This method sends a \class{dabc::Command} as a streamed text representation \func{cmddata} to a remote DAQ cluster node of name \func{managername}. The \func{managername} argument must match one of the names defined in \func{GetNodeName(int num)}. The implementation should use transport mechanisms of the control system to transfer the command string to the remote site (e.~g.~ native control commands that wrap \func{cmddata}). The receiver of such commands on the target node should call base class method \func{RecvOverCommandChannel(const char* cmddata)} to forward the command representation to the core system, which will reconstruct and execute the \class{dabc::Command} object. \item[\em bool CanSendCmdToManager(const char* mgrname)] : \index{Manager interface !CanSendCmdToManager()} Returns \keyw{true} if it is possible to send a remote command to the manager on DAQ cluster node of name \func{mgrname}, otherwise \keyw{false}. The node name argument must match one of the names defined in \func{GetNodeName(int num)}. This method may implement to forbid the sending of commands on some nodes. \item[\em int ExecuteCommand(dabc::Command* cmd)] : \index{Manager interface !ExecuteCommand()} This method executes synchronously any \dabc~ command that is submitted to this manager itself. It will run in the scope of the manager thread (depending on constructor argument \func{usecurrentprocess}, this is either the main process thread, or a dedicated manager thread). It may be re-implemented to add new commands required for the controls implementation. The \dabc~ mechanism of methods \func{SubmitCommand()} and \func{ExecuteCommand()} may allow to decouple control system callbacks from their execution thread. \end{description} %\end{compactdesc} \subsubsection{Baseclass methods} \label{prog_manager_controls_base} In addition to the virtual methods to be implemented in the manager subclass, there is a number of \class{dabc::Manager} base class methods that should be called from the control system to perform actions of the framework: \begin{description} \item[\em bool DoStateTransition(const char* state\_transition\_cmd)] : \index{Manager interface !DoStateTransition()} Performs the state machine transition of name \func{state\_transition\_cmd}. This method is synchronous and returns no sooner than the transition actions are completed (\keyw{true}) or an error is detected (\keyw{false}). Note that the real transition actions are still user defined in methods of the \class{dabc::Application} implementation. \item[\em bool IsStateTransitionAllowed(const char* state\_transition\_cmd, bool errout)] : \index{Manager interface !IsStateTransitionAllowed()} Checks if state transition of name \func{state\_transition\_cmd} is allowed for the default state machine implementation (which should be reproduced exactly by any external SM implementation) and returns \keyw{true} or \keyw{false}, resp. Argument \func{errout} may specify if error messages shall be printed to {\tt stdout}. \item[\em void RecvOverCommandChannel(const char* cmddata)] : \index{Manager interface !RecvOverCommandChannel()} Receives a \dabc~ command as text stream \func{cmddata} from a remote node. Usually this function should be called in a receiving callback of the control system communication layer, passing the received command representation to the core system. Here the command object is unstreamed again, forwarded to its receiver and executed. This is the pendant to virtual method \func{SendOverCommandChannel()} which should implement the \strong{sending} of a streamed command from the core to a remote manager by transport mechanisms of the control system. \end{description} \subsection{Default implementation for DIM} \label{prog_manager_controls_DIM} The \dabc~ default controls and configuration system is based on the DIM library \cite{DIM} and is marked by namespace \class{dimc::} (for "DIM Control"). % It features the DIM publisher-subscriber mechanism with \dabc~ process records and uses state machine module and XML parser as provided by the \dabc~core system. The main classes are described in the following: \subsubsection{\class{dimc::Manager}} \label{prog_manager_controls_DIM_manager} \index{DIM Control classes ! dimc::Manager} Implements the control system interface of \class{dabc::Manager} as described above. \begin{compactenum} \item It uses the \strong{default state machine module} of the \dabc~ core system. This is activated in the constructor by calling \func{InitSMmodule()}. Thus virtual method \func{InvokeStateTransition()} is \strong{not} re-implemented here. \item It exports a dedicated \class{dabc::StatusParameter} that is synchronized with the value of the core state machine in \func{ParameterEvent()}. This parameter is required to display the state of the node on the generic Java GUI. \item It applies the generic \class{dabc::Configuration} for setting up the node properties. The standard executable \decl{dabc\_run} will create this object from parsing an XML file. \item The other interface functionalities use one component of class \class{dimc::Registry}. \end{compactenum} \subsubsection{\class{dimc::Registry}} \label{prog_manager_controls_DIM_registry} \index{DIM Control classes ! dimc::Registry} The main component of the \class{dimc::Manager} that offers service methods really implementing the manager interface. It registers all parameters, commands, and subscriptions; and it defines the allowed access methods for the DIM server itself. \begin{compactenum} \item The \strong{DIM server} is instantiated in the constructor as \class{dimc:Server} singleton. Methods \func{StartDIMServer()} and \func{StopDIMServer()} actually initiate and terminate the service. \item \strong{Naming of nodes and services:} Method \func{GetNodeName(int num)} of \class{dimc::Manager} uses \func{CreateDIMPrefix(num)} of \class{dimc::Registry}. This evaluates the unique name for node number \func{num} from the \class{dabc::Configuration} object: It consists of a global prefix ("DABC"), the configuration \func{NodeName()}, and the \func{ContextName()} property of the node id, all separated by forward slashes ("/"). The node name is also taken as prefix for the helper methods \func{BuildDIMName()} (\func{ReduceDIMName()}, resp.) that transform local \dabc~ parameter and command names into unique DIM names (and back, resp.). Moreover, methods \func{CreateFullParameterName()} (\func{ParseFullParameterName()}, resp.) define how the local parameter name itself is composed (decomposed, resp.) from the names of its parent module and its internal variable name. They utilize corresponding static methods of class \class{dimc::nameParser} in a thread-safe way. \item \strong{Parameter export:} \func{dimc::Manager::ParameterEvent()} uses methods \func{RegisterParameter()} (and \func{UnregisterParameter()}, resp.) to declare (undeclare, resp.) a corresponding DIM service. Here the \class{dimc::Registry} keeps auxiliary objects of class \class{dimc::ServiceEntry} that link the \class{DimService} with the \class{dabc::Parameter} (see section \ref{prog_manager_controls_DIM_servicentry}). On parameter change, method \func{ParameterUpdated()} will initiate an update of the corresponding DIM service. \item \strong{Control system commands:} Method \func{DefineDIMCommand(const char* name)} creates and registers simple (char array) \class{DimCommand} objects that may be executed on this node. The \class{dimc::Registry} constructor defines commands for all state machine transitions, such as Configure, Enable, Halt, Start, Stop. Additionally, there are DIM commands for shutting down the node, setting a parameter value, and wrapping a \dabc~ command as string representation ({\em "ManagerCommand"} for \func{SendOverCommandChannel()}, see section \ref{prog_manager_controls_manager}), resp. Moreover, a \dabc~ module may register a \class{dabc::Command} as new control system command on the fly. In this case \class{dimc::Manager} method \func{CommandRegistration()} will use \func{RegisterModuleCommand()} of \class{dimc::Registry}. This will both define a \class{DimCommand}, and publish a corresponding command descriptor as DIM service to announce the command structure to the generic Java GUI. Method \func{UnRegisterModuleCommand()} may remove command and descriptor service again. When the DIM server receives a remote command, method \func{HandleDIMCommand()} checks if this command is registered; then \func{OnDIMCommand()} will transform the \class{DimCommand} into a \class{dabc::Command} and \func{Submit()} this to the Manager. The actual command execution will thus happen in re-implemented method \func{ExecuteCommand()} of \class{dimc::Manager}. Thus the command action runs independent of the DIM commandhandler thread. \item \strong{Parameter subscription:} Method \func{Subscribe()} (\func{Unsubscribe()}, resp.) of \class{dimc::Manager} are forwarded to \func{SubscribeParameter()} (UnsubscribeParameter() , resp. ) of \class{dimc::Registry}. These implement it by means of the \class{DimService} update mechanism. Subscriptions are kept as vector of \class{dimc::DimParameterInfo} objects (see section \ref{prog_manager_controls_DIM_parinfo}). \item \strong{Remote command execution:} Method \func{SendOverCommandChannel()} of \class{dimc::Manager} is forwarded to \func{SendDimCommand()} of \class{dimc::Registry}. The streamed \class{dabc::Command} is wrapped as text argument into the DIM {\em ManagerCommand} and send to the destination by node name via \func{DimClient::sendCommand()}. \end{compactenum} \subsubsection{\class{dimc::Server}} \label{prog_manager_controls_DIM_server} \index{DIM Control classes ! dimc::Server} Subclass of DIM class \class{DimServer}, implementing command handler, error handler, and exit handlers for client and server exit events. \begin{compactenum} \item Because most DIM server actions are invoked by static methods of \class{DimServer}, it is reasonable to have only one instance of \class{dimc::Server}; thus this class is designed as \strong{singleton pattern}. Access and initial creation is provided by method \func{Instance()}. A safe cleanup is granted by \func{Delete()} (ctors and dtors are private and cannot be invoked directly). \item The \class{dimc::Registry} is set as "owner" of \class{dimc::Server} by means of a back pointer. All handler methods of the \class{DimServer} are implemented as forward calls to corresponding methods of the \class{dimc::Registry} and treated there, such as: \bcir \item \func{commandHandler()} to \func{HandleDIMCommand()} \item \func{errorHandler()} to \func{OnErrorDIMServer()} \item \func{clientExitHandler()} to \func{OnExitDIMClient()} \item \func{exitHandler()} to \func{OnExitDIMServer()} \ecir \end{compactenum} \subsubsection{\class{dimc::ServiceEntry}} \label{prog_manager_controls_DIM_servicentry} \index{DIM Control classes ! dimc::ServiceEntry} This is a container to keep the \class{DimService} together with the corresponding \class{dabc::Parameter} object and some extra properties. The \class{dimc::ServiceEntry} objects are managed by the \class{dimc::Registry} and applied for the \func{RegisterParameter()} method. \begin{compactenum} \item For \class{std::string} parameters an internal \class{char*} array is used as buffer which is actually exported as DIM service. \item Method \func{UpdateBuffer()} updates the DIM service; it optionally may copy the parameter contents to the buffer before. \item Method \func{SetValue()} sets the \class{dabc::Parameter} to a new value, as defined by a string expression. \end{compactenum} \subsubsection{\class{dimc::ParameterInfo}} \label{prog_manager_controls_DIM_parinfo} \index{DIM Control classes ! dimc::ParameterInfo} A subclass of DIM class \class{DimStampedInfo} which subscribes to be informed if a remote DIM service changes its value. The \class{dimc::ParameterInfo} objects are managed by the \class{dimc::Registry} and applied for the \func{Subscribe()} method. \begin{compactenum} \item The \class{dimc::ParameterInfo} has a reference to a local \class{dabc::Parameter} object that shall be updated if the subscribed service changes. \item Depending on the subscribing \class{dabc::Parameter} type (integer, double, string,...), the constructor will instantiate an appropriate \class{DimStampedInfo} type. \item Method \func{infoHandler()} of \class{DimStampedInfo} is implemented to update the parameter to the new value by means of an \func{InvokeChange()} call. \end{compactenum}