[programmer/prog-plugin.tex] \section{Introduction} A multi purpose DAQ system like \dabc~ requires to develop user specific code and adopt this into the general framework. A common object oriented technique to realize such extensibility consists in the definition of base classes as interfaces for dedicated purposes. The programmer may implement subclasses for these interfaces as \strong{Plug-Ins} with the extended functionality that matches the data format, hardware, or other boundary conditions of the data-taking experiment. Moreover, the \dabc~ core itself applies such powerful plug-in mechanism to provide generic services in a flexible and maintainable manner. This chapter gives a brief description of all interface classes for the data acquisition processing itself. This covers the processing \strong{Modules}, the \strong{Transport} and \strong{Device} objects that move data between the DAQ components, and the \strong{Application} that is responsible for the node set-up and run control. A \strong{Factory} pattern is used to introduce new classes to the framework and let them be available by name at runtime. \section{Modules} \dabc~ provides \class{dabc::Module} class, which plays role of data processing entity in framework. In this class necessary components like pool handles, ports, parameters, timers are organised. Class \class{dabc::Module} has two subclasses - \class{dabc::ModuleSync} and \class{dabc::ModuleAsync}, which provides two different paradigms of data processing: within explicit main loop, and via event processing, respectively. Before we discuss these two kinds of modules, let's consider components which can be used with both types of the module. \subsection{Pool handles} Class \class{dabc::PoolHandle} should be used in any module to communicate with \class{dabc::MemoryPool}. By creating a pool handle with method \func{CreatePoolHandle()}, the module declares that it wants to use buffers from the memory pool as specified by name. More than one pool handles can be used in one module. A pool handle can be accessed with method \func{dabc::Module::FindPool()} via name, or with method \func{dabc::Module::Pool()} via handle number (started from 0). If a pool of the given name does not exist, it will be created automatically at the time of the first request. When pool created automatically, parameters taken from configuration file or from default values. \subsection{Ports} Class \class{dabc::Port} is the only legal way to transport buffers from/to the module. Class \class{dabc::Module} provides following methods for working with ports: \begin{tabular}{|l|l|ll|l|} \hline kind & Create & Count & Access & Search \\ \hline input & \func{CreateInput(name, ...)} & \func{NumInputs()} & \func{Input(unsigned)} & \func{InputNumber()} \\ output & \func{CreateOutput(name, ...)} & \func{NumOutputs()} & \func{Output(unsigned)} & \func{OutputNumber()} \\ \hline \end{tabular} A port usually should be created in the module constructor. As first argument in the creation methods a unique port name should be specified. As second argument, the pool handle should be specified; this defines the memory pool where necessary memory can be fetched for the transports associated with the port. The length of input or (and) output queue defines how many buffers can be kept in corresponding queue. One also can specify the size of user header, which is expected to be transported over the port - it is important for further transport configurations. Any kind of port can be found by name with \func{FindPort()} method. But this is not the fastest way to work with ports, because string search is not very efficient. One better should use in code methods like \func{NumInputs()} and \func{Input(unsigned)} (for input ports), where the port id number (i.~e.~ the sequence number of port creation) is used. Class \class{dabc::Port} provides methods \func{Send()} and \func{Recv()} to send or receive buffers. While these are non-blocking methods, one should use \func{CanSend()} and \func{CanRecv()} methods before one can call transfer operations. \subsection{Parameters and configurations} Parameters are used in module for configuration, controlling and monitoring. More information about parameters handling see in chapter \ref{prog_setup}. \subsection{Commands processing} There is the possibility in \dabc~ to execute user-defined commands in a module context. Virtual method \func{ExecuteCommand()} is called every time when a command is submitted to the module. The command is \strong{always} executed in the module thread, disregarding from which thread the command was submitted. Therefore it is not necessary to protect command execution code against module function code by means of thread locks. Most actions in \dabc~ are performed with help of commands. Here is an example how command execution can look like: \begin{small} \begin{verbatim} int UserModule::ExecuteCommand(dabc::Command cmd) { if (cmd.IsName("UserPrint")) { DOUT1("Printout from UserModule"); return dabc::cmd_true; } return dabc::ModuleSync::ExecuteCommand(cmd); } \end{verbatim} \end{small} This is invoked somewhere in the code of another component: \begin{small} \begin{verbatim} ... dabc::ModuleRef m = dabc::mgr.FindModule("MyModule"); dabc::Command cmd("UserPrint"); m.Execute(cmd); // again, but in short form m.Execute("UserPrint"); ... \end{verbatim} \end{small} After command execution has finished, method \func{Execute()} returns \keyw{true} or \keyw{false}, depending on the success. The \class{dabc::Command} object is deleted automatically after execution. In the module constructor, one can register a command for the control system by means of a corresponding \class{dabc::CommandDefinition} object. In this case the command and its arguments are known remotely and can be invoked from a controls GUI: \begin{small} \begin{verbatim} UserModule::UserModule(const char* name) : dabc::ModuleSync(name) { ... CreateCmdDef("UserPrint").AddArg("Level", "int", false); // optional argument } \end{verbatim} \end{small} \subsection{ModuleSync} \index{Core classes !dabc::ModuleSync} \label{plugin_module_sync} Data processing functionality in a most intuitive way can be implemented by subclassing the \\ \class{dabc::ModuleSync} base class, which defines the interface for a synchronous module that is allowed to block its dedicated execution thread. This class provides a number of methods which will block until the expected action can be performed. \begin{tabular}{ll} Method & Description \\ \hline \func{Recv()} & Receive buffer from specified input port \\ \func{Send()} & Send buffers over output port \\ \func{RecvFromAny()} & Receive buffer from any of specified port \\ \func{WaitInput()} & Waits until required number of buffers is queued in input port \\ \func{TakeBuffer()} & Get buffer of specified size from memory pool \\ \func{WaitConnect()} & Waits until port is connected \\ \hline \end{tabular} In all these methods a timeout value as last argument can be specified. Method \func{SetTmoutExcept()} defines if a \class{dabc::Exception} exception with timeout kind is thrown when the timeout is expired. By default, these blocking methods just return \keyw{false} in case of timeout. Data processing should be implemented in \func{MainLoop()} method. It usually contains a \strong{while()} loop where \func{ModuleWorking()} method is used to check if execution of module code shall be continued. This method will also execute the queued commands, if {\em synchronous command execution} was specified before by method \func{SetSyncCommands()}. By default, a command can be executed in any place of the code. Let's consider a simple example of a module which has one input and two output ports, and delivers buffers from input to one or another output sequentially. Implementation of such class will look like: \begin{small} \begin{verbatim} #include "dabc/ModuleSync.h" class RepeaterSync : public dabc::ModuleSync { public: RepeaterSync(const char* name) : dabc::ModuleSync(name) { CreatePoolHandle("Pool"); CreateInput("Input", Pool(), 5); CreateOutput("Output0", Pool(), 5); CreateOutput("Output1", Pool(), 5); } virtual void MainLoop() { unsigned cnt(0); while (ModuleWorking()) { dabc::Buffer* buf = Recv(Input()); if (cnt++ % 2 == 0) Send(Output(0), buf); else Send(Output(1), buf); } }; \end{verbatim} \end{small} In constructor one sees creation of pool handle and input and output ports. Method \func{MainLoop()} has a simple {\tt while()} loop, that receives a buffer from the input and then sends it alternatingly to the first or the second output. \subsection{ModuleAsync} \index{Core classes !dabc::ModuleAsync} \label{plugin_module_async} In contrast to data processing in \class{dabc::ModuleSync} main loop, class \class{dabc::ModuleAsync} provides a number of callbacks routines which are executed only if dedicated \dabc~ events occur. For instance, when any input port gets new buffer, virtual method \func{ProcessInputEvent()} will be called. User should reimplement this method to react on the event. One should use \class{dabc::ModuleAsync} for situations, when simple main loop approach is not possible - for instance, one cannot decide on which input next data is exepected. Also the main advantage of such approach is that the thread is not blocked and several \class{dabc::ModuleAsync} modules can run within same working thread. At the same time, using such programming technique may require additional bookkeeping, as it is not allowed to block the callback routine while waiting for some resource to be available. Class \class{dabc::ModuleSync} provides number of methods for handling different events: \begin{tabular}{ll} Method & Description \\ \hline \func{ProcessInputEvent()} & new buffer in input queue, it can be read with \func{port->Recv()} \\ \func{ProcessOutputEvent()} & new space in output queue is available, one can use \func{port->Send()} \\ \func{ProcessConnectEvent()} & port is connected/disconnected to transport \\ \func{ProcessPoolEvent()} & requested buffer can be read with \func{handle->TakeRequestedBuffer()} \\ \func{ProcessTimerEvent()} & timer has fired an event \\ \end{tabular} By reimplementing some of these methods one can react on corresponding events. Actually, all events are dispatched to the methods mentioned above by method \func{ProcessItemEvent()}. This method is called by the working thread whenever {\bf any} event for this module shall be processed. However, this virtual method may also directly be re-implemented in the user subclass if one wants to treat all events centrally. As arguments one gets the pointer to the relevant component (port, timer, ...) and a number describing the event type (dabc::evntInput, dabc::evntOutput, ...) Class \class{dabc::ModuleAsync} has no methods which can block. Nevertheless the user should avoid any kind of polling loops, waiting for some other resource (buffer, output queue and so on) - the callbacks should \strong{return} as soon as possible. In such situation, processing must be continued in another callback that is invoked when the required resource is available. This might require an own bookkeeping of such situations (kind of state transition logic). Let's consider as an example the same repeater module, but implemented as asynchronous module: \begin{small} \begin{verbatim} #include "dabc/ModuleAsync.h" class RepeaterAsync : public dabc::ModuleAsync { unsigned fCnt; public: RepeaterAsync(const char* name) : dabc::ModuleAsync(name) { EnsurePorts(1, 2); fCnt = 0; } virtual bool ProcessRecv(unsigned port) { if (!CanSend(fCnt % 2)) return false; dabc::Buffer buf = Recv(port); Send(fCnt++ % 2, buf); return true; } virtual bool ProcessSend(unsigned port) { if (!CanRecv() || (port != fCnt % 2)) return false; dabc::Buffer buf = Recv(); Send(fCnt++ % 2, buf); return true; } }; \end{verbatim} \end{small} The constructor of this module has absolutely the same components as in previous example. One should add \member{fCnt} member to count direction for output of next buffer. Value of \member{fCnt} in some sense defines current state of the module. Instead of the {\tt MainLoop()} one can see two virtual methods for input and output event processing. In each methods one sees same code, with while loop inside. In the loop one checks that input and current output are ready and retransmit buffer. When any port (input or output) has no more possibility to transmit data, method will be returned. One needs a \keyw{while()} loop here because not every input event and not every output events leads to buffer transports. If input queue is empty (\func{CanRecv()} returns false), or output queue is full (\func{CanSend()} returns false), one cannot transfer a buffer from input to output; thus the callback must be returned. But when the event processing routine is called the next time, one should tranfer several buffers at once. Since methods \func{Send()} and \func{Recv()} cannot block, such \keyw{while()} loop will not block either. But in any case one should avoid such \strong{wrong} code: \begin{small} \begin{verbatim} virtual void ProcessInputEvent(unsigned port) { // this kind of waiting is WRONG!!! while(!CanSend(fCnt % 2)) usleep(10); dabc::Buffer buf = Recv(indx); Output(fCnt++ % 2)->Send(buf); } \end{verbatim} \end{small} Here the \keyw{while()} loop can wait for an infinite time until the output port will accept a new buffer, and during this time the complete thread will be blocked. As both processing methods are the same in the example, one can implement central \func{ProcessItemEvent()} method instead: \begin{small} \begin{verbatim} virtual void ProcessItemEvent(dabc::ModuleItem*, uint16_t) { while (Input()->CanRecv() && Output(fCnt % 2)->CanSend()) { dabc::Buffer* buf = Input()->Recv(); Output(fCnt++ % 2)->Send(buf); } } \end{verbatim} \end{small} To introduce time-dependent actions in \class{dabc::ModuleAsync}, one should use timers. Timer objects can be created with method \func{CreateTimer()}. It delivers a timer event with specified intervals, which can be processed in \func{ProcessTimerEvent()} method. One can modify the previous example to display the number of transported buffers every 5 seconds. \begin{small} \begin{verbatim} RepeaterAsync(const char* name) : dabc::ModuleAsync(name) { ... CreateTimer("Timer1", 5.); } virtual void ProcessItemEvent(dabc::ModuleItem* item, uint16_t evnt) { ... if (evnt == dabc::evntTimeout) DOUT1("Buffers count = %d", fCnt); } \end{verbatim} \end{small} \subsection{Special modules} For special set ups (e.g. Bnet), the framework provides \class{dabc::Module} subclasses with generic functionality (e.g. \class{bnet::BuilderModule}, \class{bnet::FilterModule}). In this case, the user specific parts like data formats are implemented by subclassing these special module classes. \begin{compactenum} \item Instead of implementing \func{MainLoop()} (or \func{ProcessItemEvent()}, resp.) other virtual methods (e.g. \func{DoBuildEvent()}, \func{TestBuffer()}) may be implemented that are implicitly called by the superclass \func{MainLoop()} (or by the appropriate event callbacks, resp.). \item The special base classes may provide additional methods to be used for data processing. \end{compactenum} \section{Device and transport} \label{prog_plugin_device} All data transport functionality is implemented by subclassing \class{dabc::Device} and \class{dabc::Transport} base classes. \subsection{Transport} Actual transport of \class{Buffers} from/to a \class{Port} is done by a \class{dabc::Transport} implementation. During connection time each module port gets the pointer to a transport object which provides a number of methods for buffer transfer. As the \class{Transport} object typically runs in another thread than the module, the transmission of a buffer does not happen immediately when calling \func{dabc::Port::Send()} or \func{dabc::Port::Recv()} methods, but the buffer is at first kept in a queue which must be provided by the \class{Transport} implementation. \subsection{Device} \label{prog_plugin_device_device} Class \class{dabc::Device} usually (but not always) represents some physical device (like a network or a PCIe card) and has the role of a management unit for the \class{Transports} which belong to that device. The \class{Device} is always the owner of its \class{Transport} objects, i.~e.~ it creates, keeps, and deletes them. A \class{Device} is typically created in the user application by: \begin{small} \begin{verbatim} ... dabc::mgr()->CreateDevice("roc::Device", "ROC"); ... \end{verbatim} \end{small} Later one can find this device with \func{dabc::Manager::FindDevice()} method. Each \class{dabc::Device} implementation should define the virtual method \func{CreateTransport()} such, that an appropriate \class{Transport} instance is created and connected to the specified \class{Port}. This factory method is invoked by the framework when the device is connected to a module port. This is usually specified in the user application by calls of\\ {\tt dabc::mgr.CreateTransport()}, or {\tt dabc::mgr.Connect()}, resp. Similar to the \class{Module} functionality, the \class{Device} class may export configuration \class{Parameters}. It may also define \class{Commands} which are handled by extending the virtual method \func{ExecuteCommand()} with a device specific implementation. \subsection{Local transport} \class{dabc::LocalTransport} implements the connection between two "local" ports, i.~e.~ the ports are on the same node with a common memory address space. It organizes a queue which is shared between both connected ports, and performs the movement of \class{dabc::Buffer} pointer through this queue. If corresponding modules run in the same thread, \class{LocalTransport} works without any mutex locking. To connect two local ports, one should call: \begin{small} \begin{verbatim} ... dabc::mgr()->ConnectPorts("Module1/Output", "Module2/Input"); ... \end{verbatim} \end{small} \subsection{Network transport} This is a kind of \class{Transport} which is used to connect \class{Ports} on different nodes. Abstract base class \class{dabc::NetworkTransport} introduces such kind of functionality: this transport is locally connected to one port only, and all buffer transfer is done via network connections with the remote node. For the moment \dabc~ has two implementations of network transports: for socket and {\em InfiniBand verbs}. To use \class{NetworkTransport} on the nodes, one should follow a two step strategy. At the first step, on all nodes the necessary \class{Devices} and \class{modules} should be created: \begin{small} \begin{verbatim} ... dabc::mgr()->CreateDevice(dabc::typeSocketDevice, "UserDev"); dabc::mgr()->CreateModule("UserModule", "MyModule"); ... \end{verbatim} \end{small} Then during the second step, on the "master" node (where \keyw{dabc::mgr()->IsMainManager()} is \keyw{true}, see section \paref{prog_manager_controls_manager}) one should call: \begin{small} \begin{verbatim} ... dabc::mgr()->ConnectPorts("Node0$MyModule/Input", "Node1$MyModule/Output", "UserDev"); ... \end{verbatim} \end{small} Such call starts an elaborated sequence: at first a server socket will be opened by \class{Device} "UserDev" on node "Node0"; then \class{Device} "UserDev" on "Node1" will try to connect to that server socket; finally, on both nodes appropriate \class{NetworkTransports} will be created, using these negotiated sockets, and connected to the ports "MyModule/Input", and "MyModule/Output", resp. Exactly for this kind of actions the \dabc~ state machine has two transition commands "DoConfigure" and "DoEnable" - first command used to create necessary components and second to connect them together. Class \class{dabc::Application} has method \func{CreateAppModules()}, where modules should be created and connections should be configured. During second step requested connections will be created (by connection manager) (see \ref{prog_plugin_applicaton}). \subsection{Data transport} \label{prog_plugin_device_datatransport} In general, to implement a user-specific transport one should subclass from \class{dabc::Transport}. But this requires a deeper knowledge about the \dabc~ mechanisms: how threads are working, how one should organize input/output queues, how the transport should request data from a memory pool, and which initialization commands are used by the framework. To simplify transport development and provide all basic services class \class{dabc::DataTransport} was introduced. For a \strong{data input} the user should implement the following virtual methods : \bbul \item [\func{Read\_Size()}] : Should return the required buffer size to read next portion of data from the data source. For instance, many file formats have a header before each portion of data, describing the payload size that follows. This method then should be used to read such header. Method can also return following values: \bdes \item[\keyw{dabc::di\_EndOfStream}] - end of stream, normal close of the input \item[\keyw{dabc::di\_Repeat}] - nothing to read now, call again as soon as possible \item[\keyw{dabc::di\_RepeatTimeout}] - nothing to read now, try again after timeout \item[\keyw{dabc::di\_Error}] - error, close transport \edes \item [\func{Read\_Timeout()}] : Defines timeout (in seconds) for operation like \func{Read\_Size()} \item [\func{Read\_Start()}] : Starts reading of buffer. Should return: \bdes \item[\keyw{dabc::di\_Ok}] - normal case, call of \func{Read\_Complete()} will follow \item[\keyw{dabc::di\_Error}] - error, skip buffer, starts again from \func{Read\_Size()} \item[\keyw{dabc::di\_CallBack}] - asynchronous readout, user should call \func{Read\_CallBack()} \edes If \keyw{di\_CallBack} returned, processing of this transport is suspended until user calls \func{Read\_CallBack()} method, providing the result of reading: \keyw{di\_Ok} or \keyw{di\_Error}. This mode is only possible if the device driver has its own thread (or DMA engine, resp.) that can perform the readout and then can call \dabc~ methods. The big advantage of such mode: the data transport thread is not blocked by waiting for a result from the device, therefore several \class{DataTransports} can share the same thread. \item [\func{Read\_Complete()}] : Finish reading of the buffer. Can return: \bdes \item[\keyw{dabc::di\_Ok}] - normal, buffer will be delivered to port \item[\keyw{dabc::di\_Error}] - error, close transport \item[\keyw{dabc::di\_EndOfStream}] - end of stream, normal close of the transport \item[\keyw{dabc::di\_SkipBuffer}] - normal, but buffer will not be delivered to the port \item[\keyw{dabc::di\_Repeat}] - not ready, call again as soon as possible \item[\keyw{dabc::di\_RepeatTimeout}] - not ready, call again after timeout \edes In the simple case, actual reading of data is directly performed in this method. Otherwise one may wait here until another thread or a DMA transfer, initiated before by \func{Read\_Start()}, has filled the buffer. In this case one should be carefull and not block thread forever - it is better to return with \keyw{dabc::di\_Repeat}, so the thread can continue its event loop and handle other workers. \ebul For \strong{data output}, the user should just implement virtual method \func{WriteBuffer()} . In some cases user may redefine \func{ProcessPoolChanged()} which is called when memory pool changes its layout - new buffers were allocated or released. It may be required for DMA operations, where each buffer from a memory pool should be initialised once before it can be used for data transport. % Instantiation of user written \class{DataTransport} should be done via factory method % \func{CreateTransport()} (see \ref{prog_plugin_factory}). It is not necessary to create a user-specific \class{Device} for a user written \class{DataTransport}. However, some user implementations of \class{DataTransport} may require services of a corresponding \class{Device} though. In this case, the user should implement a \class{Device} that provides the factory method \func{CreateTransport()} (see section \ref{prog_plugin_device_device}). This can instantiate the \class{DataTransport} with a back reference to the responsible \class{Device}. \subsection{Input/output objects} Besides the \class{Transports}, \dabc~ provides an interface for implementing a simple input/output by means of base classes \class{dabc::DataInput} and \class{dabc::DataOutput}. The interface is similar to that of \class{dabc::DataTransport}, but these classes are not depending on any other components (threads, devices, etc.), and therefore can be applied without the \dabc~ data flow engine. The only feature which is not supported by \class{dabc::DataInput} is the \keyw{CallBack} mode. In addition, methods \func{dabc::DataInput::Read\_Init()} and \func{dabc::DataOutput::Write\_Init()} can be implemented to get configuration parameters from the port object to which the i/o object is assigned to. A typical use case of input/output objects is the file I/O. For instance, {\tt "*.lmd"} file handling is implemented using these classes. To instantiate such classes, user should inplement factories methods \func{CreateDataInput()} and \func{CreateDataOutput()} (see \ref{prog_plugin_factory}). \section[The DABC application]{The \dabc\ Application} \label{prog_plugin_applicaton} The specific application controlling code is defined in the \class{dabc::Application}. On startup time, the \class{dabc::Application} is instantiated by means of a factory method \func{CreateApplication()}. As argument the factories get the application class name, provided from the configuration file. Thus, to use his/her application implementation, the user must provide a \class{dabc::Factory} that defines such method. The manager has exactly one application object - the name of this object is always "App". The application singleton can be accessed from everywhere via \func{dabc::mgr()->GetApp()} call. The application may register parameters that define the application's configuration. These parameters can be set at runtime from the configuration file or by controls system. The application class implements the user-specific actions during the state machine transitions. The application has virtual method \func{DoStateTransition()} which is called from the state machine during state change. As argument, name of state transition command is delivered. There are the following state machine commands: \bdes \item[\keyw{dabc::Manager::stcmdDoConfigure}] - creates all necessary application components: devices, modules, memory pools \item[\keyw{dabc::Manager::stcmdDoEnable}] - connects local and (or) remote nodes together (if necessary) \item[\keyw{dabc::Manager::stcmdDoStart}] - starts execution of user modules \item[\keyw{dabc::Manager::stcmdDoStop}] - stop execution of user modules \item[\keyw{dabc::Manager::stcmdDoHalt}] - destroy all components, created during configure \item[\keyw{dabc::Manager::stcmdDoError}] - react on error, which happened during other commands \edes Class \class{dabc::Application} already has default implementation for \func{DoStateTransition()} method, where some virtual methods are called: \bdes \item[\func{CreateAppModules()}] - creates all necessary application components \item[\func{BeforeAppModulesStarted()}] - optional activity before modules are started \item[\func{AfterAppModulesStopped()}] - optional activity after modules are stopped \item[\func{BeforeAppModulesDestroyed()}] - optional call before modules are destroyed \edes Actually, for a single-node application it is enough to implement \func{CreateAppModules()}, since all other methods have meaningfull implementation for that case. In simplest case one can just implememnt C-function, which is called instead \func{CreateAppModules()} method of application (name of with function should be specified in configuration file in "Run/func" node). For special DAQ topologies (e.g. Bnet), the framework offers implementations of the \class{dabc::Application} containing the generic functionality (e.~g.~ \class{bnet::WorkerApplication}, \class{bnet::ClusterApplication}). In this case, the user specific parts are implemented by subclassing and implementing additional virtual methods (e.~g.~ \func{CreateReadout()}). \section{Factories} \label{prog_plugin_factory} The creation of the application specific objects is done by \class{dabc::Factory} subclasses. The user must define a \class{dabc::Factory} subclass to add own classes to the system. The user factory should already be instantiated as global stack object in its class implementation code - this will create the factory immediately after the user library has been loaded. On creation time, a factory is registered automatically to the \class{dabc::Manager} instance. The user factory may implement such methods: \bdes \item [\func{CreateModule()}] : Instantiate a \class{dabc::Module} of specified class. \item [\func{CreateDevice()}] : Instantiate a \class{dabc::Device} of specified class. \item [\func{CreateThread()}] : Instantiate a \class{dabc::WorkingThread} of specified class. \item [\func{CreateApplication()}] : Instantiate a \class{dabc::Application} of specified class. \item [\func{CreateTransport()}] : Instantiate a \class{dabc::Transport} of specified class. This method is used when transport does not requires specific device functionality (like \class{dabc::DataTransport}). Typically transport objects created by the \class{dabc::Device} methods. \item [\func{CreateDataInput()}] : Instantiate a \class{dabc::DataInput} of specified type. Initialisation of object will be done by \func{Read\_Init()} call. \item [\func{CreateDataOutput()}] : Instantiate a \class{dabc::DataOutput} of specified type. Initialisation of object will be done by \func{Write\_Init()} call. \edes Since all factories are registered and kept in the global \dabc~ manager, all methods mentioned here have equivalent methods in class \class{dabc::Manager}. The manager simply iterates over all factories and executes the appropriate factory method until an object of the requested class is created. For instance, to create a module, one should do: \begin{small} \begin{verbatim} ... dabc::mgr()->CreateModule("mbs::GeneratorModule", "Generator"); ... \end{verbatim} \end{small} Invocation of these methods in manager is implemented via corresponding commands (for instance, \comm{CmdCreateModule} for module creation). These command classes should be used directly, if one wants to deliver extra configuration parameters to the object's constructor (most factories methods gets this command as optional argument). For instance: \begin{small} \begin{verbatim} ... dabc::CmdCreateModule cmd("mbs::GeneratorModule", "Generator"); cmd.SetInt("NumSubevents", 5); cmd.SetInt("SubeventSize", 64); dabc::mgr.Execute(cmd); ... \end{verbatim} \end{small} The \dabc~ framework provides several factories for predefined implementations (e.~g.~ \class{bnet::SenderModule}, \class{verbs::Device})