Open Search
    Entity Creation

    About

    To utilize features of the MAXON API it is typically needed to allocate an object that provides access to data and functions. These objects can either be simple C++ structures and classes or reference classes representing implementations of interfaces.

    Object Creation

    Simple objects can be allocated using the following memory management tools of the MAXON API. If it is necessary to allocate objects directly, these functions should always be used instead of the standard C++ allocators.

    • NewObj(): Creates an object of the given type with the given parameters. For handling the returned error see Error Handling.
    • DeleteObj(): Deletes the given object.
    Note
    If possible, one should always use reference counting. See References.

    For allocation of low-level memory see Memory Allocation.

    // This example shows a C++ custom class.
    //----------------------------------------------------------------------------------------
    // A simple class storing an integer value.
    //----------------------------------------------------------------------------------------
    class ExampleClass
    {
    public:
    //----------------------------------------------------------------------------------------
    // Constructor.
    // @param[in] number The number to store.
    //----------------------------------------------------------------------------------------
    MAXON_IMPLICIT ExampleClass(maxon::Int number)
    {
    _number = number;
    }
    //----------------------------------------------------------------------------------------
    // Constructor. The internal number is set to 0.
    //----------------------------------------------------------------------------------------
    MAXON_IMPLICIT ExampleClass()
    {
    _number = 0;
    }
    //----------------------------------------------------------------------------------------
    // Returns the stored number.
    // @return The number.
    //----------------------------------------------------------------------------------------
    maxon::Int GetNumber()
    {
    return _number;
    }
    //----------------------------------------------------------------------------------------
    // Sets the stored number.
    // @param[in] number The number to store.
    //----------------------------------------------------------------------------------------
    void SetNumber(maxon::Int number)
    {
    _number = number;
    }
    private:
    maxon::Int _number;
    };
    Int64 Int
    signed 32/64 bit int, size depends on the platform
    Definition: apibase.h:188
    #define MAXON_IMPLICIT
    Definition: apibase.h:172
    // This example creates a new instance of the example class using NewObj().
    // create the new object
    ExampleClass* exampleObject = NewObj(ExampleClass, 100) iferr_return;
    // use the object
    const maxon::Int number = exampleObject->GetNumber();
    DiagnosticOutput("Number: @", number);
    // delete the object
    DeleteObj(exampleObject);
    maxon::Int Int
    Definition: ge_sys_math.h:64
    #define DiagnosticOutput(formatString,...)
    Definition: debugdiagnostics.h:176
    The maxon namespace contains all declarations of the MAXON API.
    Definition: autoweight.h:14
    #define NewObj(T,...)
    Definition: newobj.h:108
    #define iferr_return
    Definition: resultbase.h:1519

    Most complex classes of the MAXON API provide a (static) "Create()" function that can be used to create new instances. It is recommended to add such a "Create()" function also to a custom class if it must be initialized after creation.

    // This example shows a simple class that provides a static Create() function.
    // This Create() function allocates a new instances and initializes it. Only if
    // the creation and initialization were successful, a new object is returned.
    //----------------------------------------------------------------------------------------
    // Class to store an array of ascending integer numbers.
    //----------------------------------------------------------------------------------------
    class AscendingNumbers
    {
    private:
    //----------------------------------------------------------------------------------------
    // Inits the array with elements defined by the given range.
    // @param[in] start The minimum value.
    // @param[in] end The maximum value.
    // @return maxon::OK on success.
    //----------------------------------------------------------------------------------------
    {
    // clear array
    _numbers.Flush();
    if (end < start)
    return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    // fill array with ascending integer values
    for (maxon::Int i = start; i <= end; i++)
    {
    _numbers.Append(i) iferr_return;
    }
    return maxon::OK;
    }
    private:
    public:
    //----------------------------------------------------------------------------------------
    // Static function to create a new AscendingNumbers instance.
    // @param[in] start The minimum value.
    // @param[in] end The maximum value.
    // @return The new AscendingNumbers instance. The caller owns the object.
    //----------------------------------------------------------------------------------------
    {
    // create object
    AscendingNumbers* const numbers = NewObj(AscendingNumbers) iferr_return;
    // take ownership to ensure memory clean-up in case of an error
    using AscendingNumbersRef = maxon::UniqueRef<AscendingNumbers>;
    AscendingNumbersRef ref(numbers);
    // init array
    numbers->Init(start, end) iferr_return;
    // release and return
    return ref.Disconnect();
    }
    //----------------------------------------------------------------------------------------
    // Returns the number of stored elements.
    // @return The number of stored elements.
    //----------------------------------------------------------------------------------------
    {
    return _numbers.GetCount();
    }
    //----------------------------------------------------------------------------------------
    // Returns the number at the given index.
    // @param[in] index The index position of the number to access.
    // @return The number at the given index.
    //----------------------------------------------------------------------------------------
    {
    // range check
    const maxon::Bool undershoot = index < 0;
    const maxon::Bool overshoot = index >= _numbers.GetCount();
    if (undershoot || overshoot)
    return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    return _numbers[index];
    }
    //----------------------------------------------------------------------------------------
    // Copies the data of the given AscendingNumbers object. Will delete all previously stored data.
    // @param[in] src Source AscendingNumbers-object to copy from.
    // @return maxon::OK on success.
    //----------------------------------------------------------------------------------------
    maxon::Result<void> CopyFrom(const AscendingNumbers& src)
    {
    return _numbers.CopyFrom(src._numbers);
    }
    };
    Py_ssize_t i
    Definition: abstract.h:645
    Definition: basearray.h:412
    MAXON_ATTRIBUTE_FORCE_INLINE Int GetCount() const
    Definition: basearray.h:573
    MAXON_ATTRIBUTE_FORCE_INLINE Result< void > CopyFrom(COLLECTION2 &&other, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::FIT_TO_SIZE)
    Definition: collection.h:261
    Definition: baseref.h:62
    PyObject PyObject Py_ssize_t start
    Definition: complexobject.h:62
    PyObject PyObject Py_ssize_t Py_ssize_t end
    Definition: complexobject.h:63
    Py_ssize_t * index
    Definition: abstract.h:374
    PyObject * src
    Definition: abstract.h:305
    bool Bool
    boolean type, possible values are only false/true, 8 bit
    Definition: apibase.h:181
    static auto Create(ARGS &&... args)
    Definition: apibase.h:2773
    return OK
    Definition: apibase.h:2690
    Int GetCount(const ITERABLE &iterable)
    Definition: collection.h:37
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:67
    #define iferr_scope
    Definition: resultbase.h:1384
    // This example shows how to use the static Create() function to allocate a new instance.
    // create new instance
    AscendingNumbers* const numbers = AscendingNumbers::Create(10, 20) iferr_return;
    // defining a StrongRef alias to store the new instance
    using AscendingNumbersRef = maxon::StrongRef<AscendingNumbers>;
    // reference takes ownership to ensure memory clean-up
    AscendingNumbersRef ref(numbers);
    // use object
    const maxon::Int count = numbers->GetCount();
    for (maxon::Int i = 0; i < count; ++i)
    {
    const maxon::Int number = numbers->GetNumber(i) iferr_return;
    DiagnosticOutput("Number @", number);
    }
    Py_ssize_t count
    Definition: abstract.h:640
    for(i=0;i< length;i++)
    Definition: unicodeobject.h:61
    BaseRef< T, StrongRefHandler > StrongRef
    Definition: baseref.h:1002

    Interface References

    A reference object represents an implementation of a given interface. Such a reference object can be created in various ways. For details see Interface Basics and Using Interfaces.

    Note
    References to interfaces with only one implementation can often be allocated on the stack e.g. maxon::String.

    This example shows how a reference class instance is created using the maxon::Id of the specific implementation:

    // This example creates an instance of an interface
    // and uses the created instance.
    // define the ID of the component to use
    const maxon::Id id { "net.maxonexample.class.somesimpleclass" };
    // get component class of the given ID from the global maxon::Classes registry
    const maxon::Class<SimpleClassRef>& componentClass = maxon::Classes::Get<SimpleClassRef>(id);
    // create reference
    const SimpleClassRef simpleClass = componentClass.Create() iferr_return;
    // use reference
    simpleClass.SetNumber(123);
    const maxon::Int number = simpleClass.GetNumber();
    DiagnosticOutput("Number: @", number);
    Definition: objectbase.h:709
    Definition: apibaseid.h:253

    This example shows how to obtain a reference class from an implementation that is presented as a published object. See Published Objects Usage.

    // This example creates a reference class from a component
    // registered at the given declaration.
    // create reference
    // The "SomeSimpleClass" published object is declared in a header file.
    // The obtained component is used to create a new instance using Create().
    const SimpleClassRef simpleClass = SomeSimpleClass().Create() iferr_return;
    // use reference
    simpleClass.SetNumber(456);
    const maxon::Int number = simpleClass.GetNumber();
    DiagnosticOutput("Number: @", number);

    Interface implementations can also be registered at registries. From these registries the reference class is obtained using the specific maxon::Id of the registered implementation. See Registry Usage.

    // This example creates a reference object from the registry with the given ID.
    // get the class with the given Id from the registry "ColorClasses"
    const maxon::Id redID { "net.maxonexample.class.colors.red" };
    const maxon::Class<ColorRef>* const componentClass = ColorClasses::Find(redID);
    if (componentClass == nullptr)
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION, "Could not get color."_s);
    // create reference object
    const ColorRef color = componentClass->Create() iferr_return;
    // use reference object
    const maxon::String colorName = color.GetName();
    const maxon::Color32 colorRGB = color.GetRGB();
    DiagnosticOutput("Color Name: @", colorName);
    DiagnosticOutput("Color RGB: @", colorRGB);
    Definition: string.h:1235
    A color consisting of three components R, G and B.
    Definition: col.h:16

    Interfaces support inheritance. This means a given reference object of a base class can be cast into the reference class of a derived interface. If the cast is not possible a nullptr is returned.

    • maxon::Cast(): Casts the object into the given interface type.
    • maxon::AssertCast(): Casts the object into the given interface type. Checks only, if the object is really an instance of the interface in debug mode.
    // This example accesses an error and casts it into a maxon::ErrnoError to get the stored error code.
    // perform task
    const maxon::Result<void> res = PerformTaskCheckError();
    // check for failure
    {
    const maxon::Error error = res.GetError();
    if (error.IsInstanceOf<maxon::ErrnoError>())
    {
    // cast into ErrnoError and access error code
    const maxon::ErrnoError errnoError = maxon::Cast<maxon::ErrnoError>(error);
    const maxon::Int errorCode = errnoError.GetErrorCode();
    DiagnosticOutput("Error Code: @", errorCode);
    }
    }
    PyObject * error
    Definition: codecs.h:206
    Py_UCS4 * res
    Definition: unicodeobject.h:1113
    static const ERROR_FAILED FAILED
    Definition: resultbase.h:68

    Further Reading