Open Search
    Factories

    About

    The maxon::Factory template is used to create factory functions for a given interface. Such factory functions allow to safely create new, initialized instances of that interface.

    Declaration

    Based on the maxon::Factory template, a factory is typically declared as a published object using MAXON_DECLARATION.

    // This example shows the decalaration of a factory creating a StringHashRef object from a given maxon::String argument.
    // StringHashInterface is a custom interface.
    using StringHashFactoryType = maxon::Factory<StringHashRef(maxon::String)>;
    MAXON_DECLARATION(StringHashFactoryType, StringHashFromStringFactory, "net.maxonexample.factory.stringhashfromstring");
    Definition: string.h:1237
    maxon::Factory< StringHashRef(maxon::String)> StringHashFactoryType
    [factory_example_declaration]
    Definition: factoryexamples.h:34
    #define MAXON_DECLARATION(T, Name, id,...)
    Definition: module.h:937

    Implementation

    The published object containing the new factory must be defined in a source code file using MAXON_DECLARATION_REGISTER. The behaviour of the factory depends on a referenced function that is invoked by the factory:

    • maxon::Factory::CreateFactory(): References a static function for creation of the desired object.
    • maxon::Factory::CreateObjectFactory(): References a member function of a specific implementation. This function will create an instance and will call that member function.

    Examples

    This example shows a simple interface that just provides read-only access to its data.

    // This example shows a simple interface that stores the hash value of a string.
    // The hash of a given string can be compared to this stored hash value.
    // ---------------------------------------------------------------------
    // Class to store a string's hash value.
    // ---------------------------------------------------------------------
    class StringHashInterface : MAXON_INTERFACE_BASES(maxon::ObjectInterface)
    {
    public:
    //----------------------------------------------------------------------------------------
    // Compares the hash value of the given string with the stored hash value.
    // @return True if the hashes are identical. May return an error if no hash value could be calculated.
    //----------------------------------------------------------------------------------------
    };
    [factory_example_interface]
    Definition: factoryexamples.h:15
    MAXON_INTERFACE(StringHashInterface, MAXON_REFERENCE_NORMAL, "net.maxonexample.stringhash")
    MAXON_METHOD maxon::Result< maxon::Bool > IsStringEqual(maxon::String str) const
    Definition: resultbase.h:766
    void * str
    Definition: bytesobject.h:77
    #define MAXON_REFERENCE_NORMAL(FREEIMPL)
    Definition: interfacebase.h:1184
    #define MAXON_METHOD
    Definition: interfacebase.h:1012
    #define MAXON_INTERFACE_BASES(...)
    Definition: objectbase.h:1049

    The implementation can look like this:

    // This example shows the implementation of a simple interface. The public functions only give
    // indirect access to the internally stored data. The data must be set when an instance is created.
    // implementation of StringHashInterface
    class SecretStringHashImplementation : public maxon::Component<SecretStringHashImplementation, StringHashInterface>
    {
    public:
    {
    // create hash value of the given string
    const maxon::String hash = maxon::GetPasswordHash(str, maxon::StreamConversions::HashSHA256()) iferr_return;
    // compare
    return _hash.IsEqual(hash);
    }
    // initializes the object with the given hash value
    maxon::Result<void> InitFromHash(const maxon::String& hash)
    {
    if (_hash.IsPopulated())
    return maxon::IllegalStateError(MAXON_SOURCE_LOCATION, "SecretStringHash is already initialized."_s);
    if (hash.GetLength() != 64)
    return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION, "Invalid hash size."_s);
    _hash = hash;
    return maxon::OK;
    }
    // initializes the object with the given string
    maxon::Result<void> InitFromString(maxon::String& string)
    {
    // create hash value of the given string
    const maxon::String hash = maxon::GetPasswordHash(string, maxon::StreamConversions::HashSHA256()) iferr_return;
    // init
    return InitFromHash(hash);
    }
    // Factory method to be used with Factory::CreateObjectFactory()
    maxon::Result<void> FactoryInit(maxon::FactoryInterface::ConstPtr, maxon::String string)
    {
    InitFromString(string) iferr_return;
    return maxon::OK;
    }
    private:
    maxon::String _hash;
    };
    Definition: c4d_string.h:41
    Definition: objectbase.h:2655
    PyObject Py_hash_t hash
    Definition: dictobject.h:35
    Result< String > GetPasswordHash(const String &password, const StreamConversionFactory &hashClass, const DataDictionary &settings=DataDictionary())
    return OK
    Definition: apibase.h:2735
    MAXON_ATTRIBUTE_FORCE_INLINE Bool IsEqual(PREDICATE &&predicate, const T1 &a, const T2 &b)
    Definition: collection.h:102
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:67
    #define MAXON_COMPONENT(KIND,...)
    Definition: objectbase.h:2212
    The maxon namespace contains all declarations of the MAXON API.
    Definition: autoweight.h:14
    #define iferr_scope
    Definition: resultbase.h:1389
    #define iferr_return
    Definition: resultbase.h:1524

    Since it should not be possible to change the internal data of an existing instance, the internal data must be set when the object is created. Within a header file a factory can be defined as a published object.

    // This example shows the decalaration of a factory creating a StringHashRef object from a given maxon::String argument.
    // StringHashInterface is a custom interface.
    using StringHashFactoryType = maxon::Factory<StringHashRef(maxon::String)>;
    MAXON_DECLARATION(StringHashFactoryType, StringHashFromStringFactory, "net.maxonexample.factory.stringhashfromstring");

    A factory can call a static function that in return will create a new instance with the given arguments:

    // This example shows a static function that is defined in the same source code file as the implementation.
    // This static function creates a new instance and configures it by accessing an internal implementation function.
    // The factory below creates the new instance by calling this static function.
    static maxon::Result<StringHashRef> MakeSecretStringFromHash(maxon::FactoryInterface::ConstPtr factory, maxon::String hash)
    {
    // create new instance
    StringHashRef res = SecretStringHashImplementation::GetClass().Create() iferr_return;
    // get implementation class instance
    SecretStringHashImplementation* const implementation = SecretStringHashImplementation::Get(res);
    // configure instance
    implementation->InitFromHash(hash) iferr_return;
    return res;
    }
    MAXON_DECLARATION_REGISTER(StringHashFromHashFactory)
    {
    return StringHashFactoryType::CreateFactory(&MakeSecretStringFromHash);
    }
    Py_UCS4 * res
    Definition: unicodeobject.h:1113
    #define MAXON_DECLARATION_REGISTER(...)
    Definition: module.h:1006
    const Class< R > & Get(const Id &cls)
    Definition: objectbase.h:2073

    A different factory can invoke a member function of the implementation class. Then it will create an instance of that specific implementation automatically:

    // This example shows the registration of a published object defining a factory.
    // CreateObjectFactory() is calling a member function of the implementation class.
    // It will create a new instance of this implementation and then call the given member function.
    MAXON_DECLARATION_REGISTER(StringHashFromStringFactory)
    {
    return StringHashFactoryType::CreateObjectFactory(&SecretStringHashImplementation::FactoryInit);
    }

    The factory is then used as any other published object:

    // This example creates a new instance of StringHashInterface using a factory.
    // create new instance
    const StringHashRef stringHash = StringHashFromStringFactory().Create(secretText) iferr_return;
    // use new instance
    const maxon::Bool equal = stringHash.IsStringEqual("Hello World"_s) iferr_return;
    if (equal)
    DiagnosticOutput("The given string is equal to the secret string.");
    bool Bool
    boolean type, possible values are only false/true, 8 bit
    Definition: apibase.h:195
    #define DiagnosticOutput(formatString,...)
    Definition: debugdiagnostics.h:170

    Further Reading