ImFusion C++ SDK 4.4.0
DataComponent API

Extends ImFusion::Data with custom information in a type-safe fashion. More...

Collaboration diagram for DataComponent API:

Detailed Description

Extends ImFusion::Data with custom information in a type-safe fashion.

Overview

In order to support generic data-specific information (metadata) in a type-safe fashion, the ImFusion library provides the DataComponent API. Data and StreamData are the two main classes that hold a DataComponentList, allowing custom information (for example optional data or configuration settings) to be attached to instances of these classes. DataComponents are meant to be used for information that is bound to a specific Data instance and that can not be represented by the usual ImFusion data types. When implementing DataComponents, you should not implement any heavy evaluation logic. This is the domain of Algorithms or other classes accessing DataComponents.

Overview class diagram of the DataComponent API

DataComponents are stored in DataComponentLists. They are identified by their C++ type, which makes them a type-safe alternative to Properties.

Examples of DataComponent uses in the main ImFusion library include:

You are encouraged to use DataComponents to enrich your data with custom information that would not easily be covered by other ImFusion types. They provide an orthogonal approach to subclassing (classic "composition vs. inheritance" trade-off in software engineering). When the use case consists of storing information while providing little to no functionality, DataComponents should be considered the more lightweight option.

Implementing DataComponents

The DataComponentBase interface consists of 6 pure virtual functions that need to be implemented:

  • The virtual member functions clone(), assign(), and equals() are required so that DataComponents can be stored in a DataComponentList and copied/assigned/compared between multiple data sets.
  • The virtual member functions id(), configure(), and configuration() are required to make DataComponents serializable, so that they can be saved to/restored from workspace or ImFusion files for instance.

Since the manual implementation of this interface is cumbersome and often repetetive, we provide the following specializations:

  • Use the DataComponent<T> interface for types that shall be copiable/assignable/comparable. It exploits the CRTP pattern to forward the DataComponentBase interface to your type's copy constructor, assignment operator and equality-comparison operator. The first two are usually automatically generated by your compiler, so that you only need to provide an implementation for the last one. Here is a simple example:
    class FooComponent : public DataComponent<FooComponent>
    {
    public:
    // copy-constructor and copy-assignment operator are auto-generated by the compiler
    bool operator==(const FooComponent& rhs) const { return rhs.i == i; }
    // you still need to implement these methods to make the DataComponent serializable
    std::string id() const override;
    void configure(const Properties*) override;
    void configuration(Properties*) const override;
    private:
    int i = 0;
    };
  • Use the TemporaryDataComponent interface for types that shall only act as a temporary storage for information and neither be copiable/assignable/comparable nor be serializable. A TemporaryDataComponent will provide an empty implementation for the entire DataComponentBase interface and thereby disable all of its features.
  • There is a third specialization in the form of the LegacyDataComponent, which implements the DataComponentBase interface by fully relying on the Configurable interface in combination with the DataComponentFactory. This is not optimal in terms of performance and may lead to trouble if exact copies are required. As the name implies, this specialization exists for backward compatibility and its use is no longer recommended.

DataComponents and Inheritance

Although technically possible, DataComponent inheritance (as in, subclassing a subclass of one of the base DataComponent types) is no longer supported. If you need to create multiple DataComponent types with overlapping members, consider making use of composition instead.

Serialization of DataComponents

Since DataComponents inherit from the Configurable interface, they come with the serialization functionality included. In order for a DataComponent to be persistent, it must:

  1. implement the Configurable interface, namely the configure() and configuration() methods;
  2. implement the DataComponent::id() method, returning a unique string identifier for your type (to avoid conflicts, make sure to include potential plugin names into this ID);
  3. be registered with the DataComponentFactory. Here is a typical example of DataComponent registration:
    DataComponentFactory::get().registerComponent(
    YourComponentType().id(),
    );
    T make_unique(T... args)

If a DataComponent implements these three methods and is registered, it will be save to and restored from both ImFusion files and Workspace files. Other, non-serializable DataComponents should instead inherit from TemporaryDataComponent.

Classes

class  ImFusion::DataComponentBase
 Data components provide a way to generically attach custom information objects. More...
class  ImFusion::DataComponent< T >
 Main specialization of DataComponentBase for regular types. More...
class  ImFusion::TemporaryDataComponent
 Specialization of DataComponentBase that disables serialization, copying and assignment. More...
class  ImFusion::DataComponentFactory
 Factory singleton for creating DataComponents from string IDs. More...
class  ImFusion::DataComponentList
 Class for holding a collection of DataComponents. More...
class  ImFusion::DataComponentWithParentInterface
 Interface to augment a DataComponent with a parent of type Data. More...
class  ImFusion::ElementwiseDataComponentData
 Class for augmenting Data classes with an ElementwiseDataComponentList. More...
class  ImFusion::ElementwiseDataComponentList
 Class for managing multiple DataComponentLists for individual elements. More...
class  ImFusion::LazyInstantiatedDataComponent< ComponentType, DataType >
 Extended interface for DataComponents that support lazy instantiation / lazy retrieval. More...
Search Tab / S to search, Esc to close