![]() |
VR-Forces Developer's Guide
|
This section describes the plan classes, and how to extend the planning features provided with VR-Forces.
A plan is a set of tasks, set data requests, and global commands that a simulation object carries out in order. The plan for a simulation object is maintained by its DtVrfObjectPlanManager (vrfObjPlanMgr.h).
The DtVrfObjectManager for each back-end has a DtVrfObjectPlanAdministrator. This class reads and writes the plan (.pln) files when scenarios are loaded and saved. It also acts as a dispatcher, forwarding plan messages such as Abandon Plan to the DtVrfObjectPlanManager for the recipient of the message.
It is likely that you are reading this chapter for one of the following reasons:
Each DtLocalObject has a DtVrfObjectPlanManager, which is responsible for maintaining the DtPlan for that object. When the DtVrfObject is ticked, it ticks its DtVrfObjectPlanManager, which ticks the DtPlan.
The Plan Manager acts as an interface between the plan and the Task Manager. When the Task Manager is ready to execute a task, it calls DtPlan::awaitingTask() through the Plan Manager. Whenever the Task Manager executes a task that is not a subtask, it calls DtVrfObjectPlanManager::taskExecuted(). This allows the Plan Manager to determine if the plan should be abandoned due to an immediate task issued by the front-end, or a task issued from a global plan.
The Plan Manager responds to plan-related commands from front-end applications that are forwarded from the DtVrfPlanAdministrator.
Plan Managers get created in a factory. For details about how Plan Managers get created, please see Creating an Object's Subcomponents.
To look up the plan for an object, use the DtVrfObjectPlanManager::plan() accessor. If the object has not been assigned a plan, a NULL pointer is returned. For example, given a pointer to a DtVrfObject "myObject", the following code prints a message if the plan is complete. For information about accessing a certain DtVrfObject, please see Looking Up Individual Objects.
The DtLocalObjectManager class has an instance of a DtVrfObjectPlanAdministrator. Therefore there is one DtVrfObjectPlanAdministrator in each VR-Forces back-end application.
The DtVrfObjectPlanAdministrator::writePlanFile() member function is used by the DtCgf to create plan files when a scenario is saved and DtVrfObjectPlanAdministrator::readPlanFile() is used to load them when the scenario is loaded.
It is also used by the DtCgf during scenario save and load to control the execution state of plans. DtVrfObjectPlanAdministrator::disablePlanExecutionState() goes through each local object in the DtVrfObjectManager and calls disableExecutionState() for the DtPlan owned by the object’s DtVrfObjectPlanManager. DtVrfObjectPlanAdministrator::enablePlanExecutionState() works the same way to enable plan execution.
The DtVrfObjectPlanAdministrator also acts as a dispatcher to read plan messages sent by a DtVrfRemoteController and forward them to the proper DtVrfObjectPlanManager based on the recipient of the message. It handles the following message types:
To load a plan file into the Plan Manager, call DtVrfObjectPlanAdministrator::readPlanFile(). This instantiates a DtPlan object for each plan in the file and assigns it to the object’s DtVrfObjectPlanManager. This is call should generally only be made from DtCgf::loadScenario().
To save the plans to file, call DtVrfObjectPlanAdministrator::writePlanFile(). This call should generally only be made from DtCgf::saveScenario(). When you save a scenario, a plan file is one of the files that gets saved as part of the scenario. The name of the plan file is referenced in the scenario file.
The Simple Plan (simplePlan) example demonstrates how to create and assign a plan to a simulation object.
To create a new DtPlan, you should use the DtPlanBuilder helper class. This has fucntions for adding statements and contitional expressions. It returns a fully formed DtPlan instance.
Plan statements are the individual items that get executed in a DtPlan. Statements represent tasks for the simulation object to perform, set data requests, or control-flow statements such as if-then-else and trigger. They are derived from the DtSimStatement class. In the simplePlan example, we create task and set data request statements. To create these kinds of statements, we first created the content for the statement (a derived type of DtSimTask or DtSetDataRequest), and then assigned it to a newly created corresponding DtTaskStmt or DtSetDataRequestStmt class.
A DtPlan contains a DtPlanBlock, which is the list of DtSimStatements in a plan. To add our new statements to the plan, we first obtained a pointer to the DtPlan’s main block of statements, and then added the statements to it. Because the plan assumes responsibility for deleting the memory associated with the plan statements, we cloned in the statements before adding them.
Using a DtPlanBlockBuilder in conjuction with the DtPlanBuilder is the easiest way to construct plans in the API, and does much of the memory and statement management for you.
Once you have created a DtPlan, you need to assign it to a particular DtVrfObject. The DtCgf::assignPlanByUUID() function associates the given DtPlan with the given DtLocalObject. The DtPlan will get executed as its DtVrfObjectPlanManager for this object gets ticked.