Entity Creation
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.
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.
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; }
// 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);
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. //---------------------------------------------------------------------------------------- maxon::Result<void> Init( maxon::Int start, maxon::Int end ) { iferr_scope ;
// clear array _numbers.Flush();
//---------------------------------------------------------------------------------------- // Returns the number of stored elements. // @return The number of stored elements. //---------------------------------------------------------------------------------------- maxon::Int GetCount () { 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. //---------------------------------------------------------------------------------------- maxon::Result<maxon::Int> GetNumber( maxon::Int 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); } };
// 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); }
A reference object represents an implementation of a given interface. Such a reference object can be created in various ways. For details see 接口基础 and 使用接口 .
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);
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);
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.
// perform task const maxon::Result<void> res = PerformTaskCheckError();
// check for failure if (res == maxon::FAILED ) { 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); } }