Writing a Flip Class Part 1
This chapter and the next chapter will describe how to write a Flip Class as well as writing convention which should be followed to make it future proof.
In the following, we will show the step by step construction of an hypothetic MyClass class.
This chapter will assume that your company is called ACME making the application “Product”.
Declaring the Class
Every class managed by flip will need to inherit from ohm::flip::Object , so the first thing is to inherit from it. Since the base class needs a document to operate on, we will pass it to the constructor. It is important that every flip class constructor follows the same exact prototype.
We will also need to declare the class before we can use it, so that we will add a declare member.
#include "ohm/flip/Object.h" |
class MyClass |
: public ohm::flip::Object |
{ |
public: |
static void declare (); |
MyClass (ohm::flip::DocumentBase & document); |
virtual ~MyClass () {} |
[...] |
}; |
The function declare will declare this class to the Flip framework.
void MyClass::declare () |
{ |
using namespace ohm::flip; |
ClassDescription <MyClass>::use ().set_name ("acme.product.MyClass"); // 1. |
ClassDescManager::declare (ClassDescription <MyClass>::use ()); // 2. |
} |
- This line will link your class with a name given as the string. This string will be used when writing the document
- This line will add this class to the set of Flip managed classes
The constructor will pass the document to its base class.
MyClass::MyClass (ohm::flip::DocumentBase & document) |
: ohm::flip::Object (document) |
{ |
} |
Then we will add the class in the global declare function in fnc.cpp
void declare () |
{ |
flip::ClassDescManager::use_instance ().declare_basic_types (); |
MyClass::declare (); |
flip::EnumDescManager::use_instance ().post_check (); |
flip::ClassDescManager::use_instance ().post_check (); |
} |
Note:If you forget to declare a class, an assert will trigger on runtime, with a comment next to it to remind you to declare the class
Inheritance
The Flip framework has a limited while being sufficient support for inheritance : It does not support multiple inheritance.
To make MySubClass inherit from MyClass we will make it inherit in the C++ code and declare the inheritience in the declare function.
class MySubClass |
: public MyClass |
{ |
public: |
static void declare (); |
[...] |
}; |
The function declare will declare this class to the Flip framework.
void MySubClass::declare () |
{ |
using namespace ohm::flip; |
ClassDescription <MySubClass>::use ().set_name ("acme.product.MySubClass"); |
ClassDescription <MySubClass>::use ().inherit <MyClass> (); |
ClassDescManager::declare (ClassDescription <MySubClass>::use ()); |
} |
Then we will add the class in the global declare function in fnc.cpp and make sure that the base class is declared before our class.
void declare () |
{ |
flip::ClassDescManager::use_instance ().declare_basic_types (); |
MyClass::declare (); |
MySubClass::declare (); |
flip::EnumDescManager::use_instance ().post_check (); |
flip::ClassDescManager::use_instance ().post_check (); |
} |
Adding Flip Members
Every class managed by flip may contain an illimited number of either Flip basic types or your own custom Flip classes.
Flip offers, three categories of basic types :
- Value types that hold a value
- Enumerate types based on an enum
- Containers
- Signaling type

Value Types
Value types are limited to 3 types :
- ohm::flip::Bool
- ohm::flip::Int64
- ohm::flip::Float64
ohm::flip::Bool will hold a boolean value, ohm::flip::Int64 will hold a 64 bits integer value and ohm::flip::Float64 will hold a 64 bits floating point value.
They are defined respectively in ohm/flip/Bool.h , ohm/flip/Int64.h and ohm/flip/Float64.h
Enumeration Types
The ohm::flip::Enum type will hold an enumeration based on a C++ enum.
It is defined in ohm/flip/Enum.h
Opaque Data Type
The ohm::flip::Blob type will hold an opaque dynamic-sized blob of data.
It is defined in ohm/flip/Blob.h
Containers
Container types are limited to 2 types :
- ohm::flip::Array
- ohm::flip::Collection
ohm::flip::Array will hold an explicit ordered list of object. ohm::flip::Colletion will hold an implicit orderer list or an unordered list of object.
They are defined respectively in ohm/flip/Array.h and ohm/flip/Colletion.h
Reference Type
Flip offers a Reference type, named ohm::flip::ObjectRef that allows to reference another Flip object in the model tree.
Signaling Type
The Flip framework contains one signaling type, named ohm::flip::Cue that allows to signal other users with data that is not persistent (that is not written in the document)
It is defined in ohm/flip/Cue.h
Using Types
Adding a Flip member consists of adding it to the Flip class and declaring it to the Flip framework.
#include "ohm/flip/Object.h" |
#include "ohm/flip/Bool.h" |
#include "ohm/flip/Int64.h" |
#include "ohm/flip/Float64.h" |
#include "ohm/flip/Enum.h" |
#include "ohm/flip/Array.h" |
#include "ohm/flip/Collection.h" |
#include "ohm/flip/Cue.h" |
class MyClass |
: public ohm::flip::Object |
{ |
public: |
enum MyEnum |
{ |
MyEnum_FOO = 0, |
MyEnum_BAR, |
MyEnum_NBR_ELT |
} |
static void declare (); |
MyClass (ohm::flip::DocumentBase & document); |
virtual ~MyClass () {} |
private: |
ohm::flip::Bool _my_bool; |
ohm::flip::Int64 _my_int; |
ohm::flip::Float64 _my_float; |
ohm::flip::Enum <MyEnum, MyEnum_FOO, MyEnum_NBR_ELT> |
_my_enum; |
ohm::flip::Blob _my_blob; |
ohm::flip::Array <MyElementClass> |
_my_array; |
ohm::flip::Collection <MyElementClass> |
_my_collection; |
ohm::flip::Cue _my_cue; |
}; |
The function declare will declare those members to the Flip framework.
void MyClass::declare () |
{ |
using namespace ohm::flip; |
EnumDescription <MyEnum>::use ().set_name ("acme.product.MyClass.MyEnum"); |
EnumDescription <MyEnum>::use ().push_enum_desc (MyEnum_FOO, "MyEnum_FOO"); |
EnumDescription <MyEnum>::use ().push_enum_desc (MyEnum_BAR, "MyEnum_BAR"); |
EnumDescManager::declare (EnumDescription <MyEnum>::use ()); |
ClassDescription <MyClass>::use ().set_name ("acme.product.MyClass"); |
ClassDescription <MyClass>::use ().push_var_desc (&MyClass::_my_bool, "_my_bool"); |
ClassDescription <MyClass>::use ().push_var_desc (&MyClass::_my_int, "_my_int"); |
ClassDescription <MyClass>::use ().push_var_desc (&MyClass::_my_float, "_my_float"); |
ClassDescription <MyClass>::use ().push_var_desc (&MyClass::_my_enum, "_my_enum"); |
ClassDescription <MyClass>::use ().push_var_desc (&MyClass::_my_blob, "_my_blob"); |
ClassDescription <MyClass>::use ().push_var_desc (&MyClass::_my_array, "_my_array"); |
ClassDescription <MyClass>::use ().push_var_desc (&MyClass::_my_collection, "_my_collection"); |
ClassDescription <MyClass>::use ().push_var_desc (&MyClass::_my_cue, "_my_cue"); |
ClassDescManager::declare (ClassDescription <MyClass>::use ()); |
} |
In the above code, the enum is declared first before the member using the enum is declared. The code will assign a name to the enums and members and will be used when saving the document.
The constructor will pass the document to its members.
MyClass::MyClass (ohm::flip::DocumentBase & document) |
: ohm::flip::Object (document) |
, _my_bool (document) |
, _my_int (document) |
, _my_float (document) |
, _my_enum (document) |
, _my_blob (document) |
, _my_array (document) |
, _my_collection (document) |
, _my_cue (document) |
{ |
} |
Now that we have declared the model, the next step will be to manipulate it, which we will show in the next chapter. However all the above code is essentially what is used by the server.