AlUserCommand
Encapsulates the user defined interface to command history.
Synopsis
#include <AlUserCommand.h>
class AlOutput
virtual statusCode output( const void *data, int size );
virtual statusCode declareObject( AlObject *obj );
class AlInput
virtual statusCode input( void *data, int size );
virtual int inputRemaining() const;
virtual AlObject* resolveObject( AlObject *obj );
class AlUserCommand
// overloaded user functions
// do not call these directly or the command history may not be correctly
// maintained
//
virtual ~AlUserCommand();
virtual int isValid();
virtual int execute();
virtual int declareReferences();
virtual int instanceDag( AlDagNode *oldDag, AlDagNode *newDag );
virtual int undo();
virtual int dagModified( AlDagNode *dag );
virtual int geometryModified( AlDagNode *dag );
virtual int curveOnSurfaceModified( AlCurveOnSurface *surf );
virtual int listModifiedDagNodes( const AlNotifyDagNode *dagMod, AlObject *obj );
virtual int debug( const char *prefix );
virtual void * asDerivedPtr();
virtual statusCode storeWire( AlOutput *output );
virtual statusCode storeSDL( ofstream &outputSDL );
virtual statusCode retrieveWire( AlInput *input );
virtual statusCode resolveWire( AlInput *input );
// for your own use
virtual int type();
// general utility functions
const char * name() const;
AlCommand * command() const;
// declare utility functions
AlCommandRef* firstConstructorRef();
statusCode addConstructorRef( AlDagNode * );
statusCode addConstructorRef( AlCurveOnSurface *);
statusCode addConstructorContact( AlDagNode *, AlContact * );
AlCommandRef* firstTargetRef();
statusCode addTargetRef( AlDagNode * );
statusCode addTargetRef( AlCurveOnSurface * );
statusCode addTargetContact( AlDagNode *, AlContact * );
statusCode deleteAllReferences();
boolean isDagNodeAConstructor( AlDagNode * ) const;
boolean isDagNodeATarget( AlDagNode *, boolean includeCOS = FALSE ) const;
boolean isCurveOnSurfaceAConstructor( AlCurveOnSurface *) const;
boolean isCurveOnSurfaceATarget( AlCurveOnSurface *) const;
Description
This class contains the definitions required to define a user command history command. The developer will be implementing many of these functions and must follow the return value conventions of this class.
statusCode AlOutput::declareObject( AlObject *objectPtr )
Description
Used by the calling routine to declare that it references an AlObject pointer in its private data so that it can use the AlInput::relocateObject to relocate an object on the retrieve.
Arguments
< objectPtr - the pointer that is referenced
Return Codes
sSuccess - the method worked
sFailure - the method failed.
AlData* resolveData( int type, int typeId )
AlObject *resolveObject()
Description
This method is used by the AlUserCommand class to resolve pointers to AlObjects. Object resolution must be performed in the same order as object declaration. This preserves the object types that will be saved in the command.
AlCommand *AlUserCommand::command() const
Description
Returns the parent command object. This may not be possible when the command is being initialized.
AlUserCommand::AlUserCommand()
Description
Default constructor for the user data for a command.
AlUserCommand::~AlUserCommand()
Description
A default destructor for the user command. This method is called whenever the command is about to be freed. It is the responsibility of this function to free all of the data contained in the command, including lists and geometry used locally. Care should be taken not to free data that is referenced elsewhere; for instance, in the DAG. This routine should only free data that is not referenced elsewhere.
int AlUserCommand::isValid()
Description
Used to determine if a command is valid by returning a value. Examples of a command being invalid are: essential DAG pointers becoming NULL, input out of range or the geometry that this command depends on being modified in such a way that this command is no longer valid (for example, curve CVs are deleted until there are fewer than one span). The function returns 0 if the command is valid; otherwise, a non zero value indicates what is wrong with it. These values are defined by the specific command. An invalid command is freed when it is executed during an update of the construction history list. It can be freed when executing it explicitly if the execute function is told to do so.
int AlUserCommand::execute()
Description
Called when the command should be executed. Before this function is executed, the isValid() method is called to ensure that the command is valid. Invalid commands are not executed. Most commands may behave differently if they are being called for the first time. For example, the fillet command saves a reference to a DAG node on the first call. If the command is re-executed, the previous DAG node pointer is used instead of the new one. This method returns 0 on success and non-zero on failure.
int AlUserCommand::undo()
Description
Undoes what is done by the execution of the command. This may require the original execution of the command to record the state of the model before execution. It is valid not to define this method. This method returns 0 on success and non-zero on failure.
int AlUserCommand::declareReferences()
Description
Appends constructor and target references to the command for each reference that it makes to the geometry in the model. Use the command() method to find the parent command. From the parent command, use the addTargetRef() and addConstructorRef() methods to create references to the geometry. The command system may dynamically free all references and ask the declareReferences() method to rebuild the list. It is very important that every reference be declared. Failing to do so may result in unpredictable behaviour in the user interface. This method returns 0 on success and non-zero on failure.
int AlUserCommand::instanceDag( AlDagNode *oldDag, AlDagNode *newDag )
Description
Changes all references to oldDag to newDag. This may involve walking the reference list for this command and changing the DAG node pointers to point to the new DAG node. This method returns 0 on success and non-zero on failure.
Arguments
< oldDag - the old DAG node to look for
< newDag - the new DAG node to replace it with
int AlUserCommand::dagModified( AlDagNode *dag )
Description
Called whenever the DAG node passed in is modified. This usually means a transformation in the DAG node has changed. This function will only be called if the DAG node is present in the reference list for the command. Some commands do not need to implement this function, since they may only be required to execute after the DAG is modified. Only implement this command if the command block needs to be updated when the DAG is modified. It is valid not to define this method. This method returns 0 on success and non-zero on failure.
Arguments
< dag - the DAG node to update
int AlUserCommand::geometryModified( AlDagNode *dag )
Description
Called when the geometry beneath the DAG node is modified. An example is moving a CV’s position or deleting a CV. Only implement this function if there is something that must be updated in the command block when the geometry on a DAG node is transformed. An example of this is a command that creates a local copy of the constructor geometry. If the local copy is not updated when the original is, then when the command is re-executed, the correct result will not appear. This method returns 0 on success and non-zero on failure.
int AlUserCommand::curveOnSurfaceModified( AlCurveOnSurface *surf )
Description
Called whenever the system modifies a curve on surface. If this command references the curve on surface parameter "surf", then it should return 1.
Arguments
< surf - the curve on surface to check
int AlUserCommand::listModifiedDagNodes( const AlNotifyDagNode *dagMod, AlObject *obj )
Description
Notifies Alias of any DAG nodes that will be modified if the given object is changed. The code fragment for the function will resemble the following:
int myCmd::listModifiedDagNodes( dagMod, AlObject *obj )
{
for each dag node ’adag’ which will be affected when ’obj’ is modified
{
dagMod->notify( adag );
}
}
It is valid not to define this method. This method returns 0 on success and non-zero on failure.
int AlUserCommand::debug( const char *prefix )
Description
Used for debugging purposes. This method should print out any relevant debugging information for this command and would be called from the implemented methods of AlUserCommand of the construction history plug-in. For each output line, print out the string in ’prefix’ first. It will contain spacing information, and so on. It is valid not to define this method. For example,
int myCmd::debug( const char *prefix )
{
cerr << prefix << "The command contains" << this->myValue << cend;
cerr << prefix << "and the value " << this->myOtherValue << cend;
return 0;
}
This method returns 0 on success and non-zero on failure.
statusCode AlUserCommand::storeWire( AlOutput *output )
Description
Outputs the contents of the command to be stored in the output Wire file. This function returns sSuccess if it was successful. The function is passed a memory stream to write the contents of the command to. OpenAlias will use the name() method to denote the command identifier to label this data chunk with. It is valid to call the AlOutput->output() multiple times. This method must be defined for objects to save correctly. Do not write the AlUserCommand structure out directly to disk. This will also write out virtual table pointers, and so on. First create a private data class which contains the data which will be written out to the wire file. Make your derived object inherit this private data class, then write out its portion instead. For example,
class myCmdData
{
this will enable us to get a pointer to the myCmdData
section of our derived structure
myCmdData *cmdDataPtr() { return this; }
public: .
AlDagNode *dag1;
double value;
};
class myCmd : public AlUserCommand, public myCmdData
{
...
public: .
double MiscData;
}
myCmd:storeWire( AlOutput *wireOut )
{
wireOut->output( cmdDataPtr(), sizeof( myCmdData ) );
wireOut->declareObject( myCmdData->dag1 );
wireOut->output( &MiscData, sizeof( MiscData );
final data is written to disk when we return
}
Arguments
< output - the output method
Return Codes
sFailure - the method did not work
sSuccess - the method worked
statusCode AlUserCommand::retrieveWire( AlInput *input )
Description
Unpacks the current command from the wire file. Returns sSuccess if the method worked. Note that the command() method may return NULL at this point in time. (It will be valid after the entire file has been loaded.) The retrieveWire routine is almost identical to the retrieve routine. For example,
myCmd:retrieveWire( AlInput *wireIn )
{
wireIn->input( cmdDataPtr(), sizeof( myCmdData ) );
wireIn->input( &MiscData, sizeof( MiscData );
Note that we do not worry about AlObject pointers until later
}
Arguments
< data - the block of data for you to unpack
< size - the size of the data block
Return Codes
sFailure - the method did not work
sSuccess - the method worked
statusCode AlUserCommand::storeSDL( ofstream &outputSDL )
Description
Outputs the command to an SDL file. This function is currently unused (it will never be called) and is present for future uses.
Arguments
< outputSDL - the output file stream for the SDL file
Return Codes
sFailure - the method did not work
sSuccess - the method worked
int AlUserCommand::type()
Description
User definable type field to be used with asDerivedPtr()
void *AlUserCommand::asDerivedPtr()
Description
Provided for safe downcasting to your derived type, so no assumptions of the location of the derived data need to be made. Use this method in conjunction with the commandType().
For example,
switch( commandType() )
{
case myCommandType: .
myCommand *cmd = (myCommand *)asDerivedPtr();
....
}
The pointer is declared as follows
void * myDerivedCmd::asDerivedPtr() { return this; }
const char *AlUserCommand::name() const
Description
Returns the name of the command, as specified when it was created.
AlCommandRef* AlUserCommand::firstConstructorRef()
Description
Returns a wrapper to the first constructor reference.
AlCommandRef* AlUserCommand::firstTargetRef()
Description
Returns a wrapper to the first target reference.
statusCode AlUserCommand::addConstructorRef( AlDagNode *dagNode )
Description
Adds a reference to a DAG node to the constructor list. To be used by the declare method.
Arguments
< dagNode - DAG node that is referenced
Return Codes
sSuccess - the reference was added
sInvalidArgument - dagNode was invalid
sFailure - the reference was not added
sInvalidObject - the command was not valid
statusCode AlUserCommand::addConstructorRef( AlCurveOnSurface *curveOnSurface )
Description
Adds a reference to a curve on surface to the constructor list. To be used by the declare method.
Arguments
< curveOnSurface - curve on surface that is referenced
Return Codes
sSuccess - the reference was added
sInvalidArgument - curveOnSurface was invalid
sFailure - the reference was not added
sInvalidObject - the command was not valid
statusCode AlUserCommand::addConstructorContact( AlDagNode *dagNode, AlContact *contact )
Description
Add a contact constructor to the constructor list. To be used by the declare method.
Arguments
< dagNode - DAG node that is referenced
< contact - the contact
Return Codes
sSuccess - the reference was added
sInvalidArgument - dagNode or contact was invalid
sFailure - the reference was not added
sInvalidObject - the command was not valid
statusCode AlUserCommand::addTargetRef( AlDagNode *dagNode )
Description
Adds a reference to a DAG node to the target list. To be used by the declare method.
Arguments
< dagNode - DAG node that is referenced
Return Codes
sSuccess - the reference was added
sInvalidArgument - dagNode was invalid
sFailure - the reference was not added
sInvalidObject - the command was not valid
statusCode AlUserCommand::addTargetRef( AlCurveOnSurface *curveOnSurface )
Description
Adds a reference to a curve on surface to the target list. To be used by the declare method.
Arguments
< curveOnSurface - curve on surface that is referenced
Return Codes
sSuccess - the reference was added
sInvalidArgument - curveOnSurface was invalid
sFailure - the reference was not added
sInvalidObject - the command was not valid
statusCode AlUserCommand::addTargetContact( AlDagNode *dagNode, AlContact *contact )
Description
Adds a contact target to the target list. To be used by the declare method.
Arguments
< dagNode - DAG node that is referenced
< contact - the contact
Return Codes
sSuccess - the reference was added
sInvalidArgument - dagNode or contact was invalid
sFailure - the reference was not added
sInvalidObject - the command was not valid
statusCode AlUserCommand::deleteAllReferences()
Description
Deletes all reference from this command.
Return Codes
sSuccess - the command worked
sInvalidObject - the current command is not valid
boolean AlUserCommand::isDagNodeAConstructor( AlDagNode* dagNode ) const
Description
Returns TRUE if the given DAG node is a constructor of this command.
Arguments
< dagNode - the DAG node in question
boolean AlUserCommand::isDagNodeATarget( AlDagNode* dagNode, boolean includeCoS ) const
Description
Returns TRUE if the given DAG node is a target of this command.
Arguments
< dagNode - the DAG node in question
< includeCoS - if TRUE, also consider curves on surface which are children of the DAG node to be part of the DAG node
boolean AlUserCommand::isCurveOnSurfaceAConstructor( AlCurveOnSurface* curveOnSurface ) const
Description
Returns TRUE if the given curve on surface is a constructor of this command.
Arguments
< curveOnSurface - the curve on surface in question
boolean AlUserCommand::isCurveOnSurfaceATarget( AlCurveOnSurface* curveOnSurface ) const
Description
Returns TRUE if the given curve on surface is a target of this command.
Arguments
< curveOnSurface - the curve on surface in question