Developer Documentation

Type Interface

This interface is used to register new types in OpenFlipper. The type plugins are loaded before all other plugins. They have only the registerType function which registers the type to the core and a function to create objects of the new type. The type itself has to be defined in the ObjectTypes subdirectory.

# Example using custom data types

Adding a custom data type to OpenFlipper needs the following requirements in order to work:

- The definition of the typeId constant, e.g.:
  #define DATA_MY_DATA typeId("MyDataType")
  Note: Your data type is then referenced as DATA_MY_DATA during runtime.
- The specification of an object class for your object type that is derived from BaseObjectData.
- The specification of helper functions (usually within the PluginFunctions namespace) allowing the casting from BaseObjectData to your object type class.

See detailed examples for each of the three points for already existing data types in OpenFlipperRoot/ObjectTypes.

Once the object class is specified, the type plugin will be responsible for its handling including

- Adding new objects to the scenegraph
- Setting the initial name of an object
- Etc.

So, type plugins usually consist of only few lines of code. Here an example of a type plugin handling an example object data type as mentioned above:

bool MyDataTypePlugin::registerType() {
addDataType("MyDataType",tr("MyDataType"));
setTypeIcon( "MyDataType", "myDataType.png");
return true;
}
int MyDataTypePlugin::addEmpty() {
// Create new object
MyObject* object = new MyObject();
object->setName( QString("My Object %1.mob").arg(objectCount) );
object->update();
object->show();
// Tell core that an object has been added
emit emptyObjectAdded ( object->id() );
return object->id();
}

Now, each time a plugin emits addEmptyObject(DATA_MY_DATA), the addEmpty() function will add the object to the scenegraph and return the newly created object's id.

# Backups

Backups are very specific to the underlying data structures of certain types. Therefore the type plugins also manage backups. Backups itself are managed by perObjectData objects based on the BackupData class. When the slot gets called, we first have to check, if an BackupData is already available. If not, we create one. Than the backup is generated and passed to the backup data attached to the object.

You have to derive your backups from the BaseBackup class, where you only need to implement the apply function and your constructor. In the following example, this class is named TriMeshBackup.

void TypeTriangleMeshPlugin::generateBackup( int _id, QString _name, UpdateType _type ){
// Get the object corresponding to the id
BaseObjectData* object = 0;
PluginFunctions::getObject(_id, object);
TriMeshObject* meshObj = PluginFunctions::triMeshObject(object);
// Safety check
if ( meshObj != 0 ){
//get backup object data
BackupData* backupData = 0;
// If a backup data has already been attached, get it, otherwise create it.
if ( object->hasObjectData( OBJECT_BACKUPS ) )
backupData = dynamic_cast< BackupData* >(object->objectData(OBJECT_BACKUPS));
else{
//add backup data
backupData = new BackupData(object);
object->setObjectData(OBJECT_BACKUPS, backupData);
}
// Create a new backup
TriMeshBackup* backup = new TriMeshBackup(meshObj, _name, _type);
// Store it in the backup data
backupData->storeBackup( backup );
}
}

To use the TypeInterface:

- include TypeInterface.hh in your plugins header file
- derive your plugin from the class TypeInterface
- add Q_INTERFACES(TypeInterface) to your plugin class
- Implement all slots of this Interface