neuray API Programmer's Manual

Example for User-defined classes

[Previous] [Next] [Up]

This example demonstrates the implementation and usage of user-defined classes to be used in conjunction with the neuray API. In this example the new class is defined in and used by the main application. In contrast, the next example demonstrate how to provide additional functionality with user-defined classes via plugins.

A simple class called My_class with a corresponding interface class IMy_class will be used in this example to demonstrate the required steps.

New Topics

  • Definition of the interface of a user-defined class

  • Implementation of a user-defined class

  • Registration and usage of a user-defined class

Detailed Description

Defining the interface of a user-defined class

To define user-defined classes you need to provide an interface with the public methods of your class. The interface is an abstract base class which contains only pure virtual methods. The interface must be (directly or indirectly) derived from mi::neuraylib::IUser_class.

The easiest way to define such an interface is by deriving from the mixin class mi::base::Interface_declare. The first eleven template parameters are used to construct the mi::base::Uuid (which must be unique). The last template parameter denotes the actual interface to derive from (should be mi::neuraylib::IUser_class, or another interface (directly or indirectly) derived from mi::neuraylib::IUser_class).

This definition of the interface is required by the applications (or other plugins) in which the user-defined class is supposed to be used.

Implementation of a user-defined class

You need to implement the interface defined in IMy_class.

Deriving your implementation from the mixin mi::neuraylib::User_class is required to ensure that your implementation class works together with the class framework, including features like creation, serialization and deserialization. Note that if you derive your implementation class directly from your interface or indirectly via mi::base::Interface_implement it will not correctly work together with the class framework.

To make serialization and deserialization work, you need to implement INVALID_DOXYREF and INVALID_DOXYREF. In this example it is sufficient to write the single member m_foo to the serializer and to read it from the deserializer, respectively. Furthermore, you need to implement mi::neuraylib::IUser_class::copy() which has to create a copy of a given object.

Registration and usage of a user-defined class

Finally the example demonstrates how to use the user-defined class. Before using the new class it is necessary to register it with the neuray API. This can be accomplished by mi::neuraylib::IExtension_api::register_class().

Using the user-defined class works the same way as for all other classes. You can use mi::neuraylib::ITransaction::create() to create new instances; you can store them in the database and retrieve them from the database. Here, the example just does a simply test of the serialization and deserialization functionality.

Example Source

Source Code Location: example/imy_class.h

‎/******************************************************************************
 * Copyright 1986, 2011 NVIDIA Corporation. All rights reserved.
 *****************************************************************************/

#ifndef IMY_CLASS_H
#define IMY_CLASS_H

#include <mi/neuraylib.h>

// The interface for the user-defined class.
//
// The class has getter and setter for an artificial property "foo" to demonstrate
// basic features like serialization and deserialization
class IMy_class : public
    mi::base::Interface_declare<0x7274f2a1,0xb7e1,0x4fc7,0x8c,0xe4,0xef,0x2d,0xd0,0x9b,0x75,0x52,
                                mi::neuraylib::IUser_class>
{
public:
    // Sets property foo
    virtual void set_foo( mi::Sint32 foo) = 0;

    // Gets property foo
    virtual mi::Sint32 get_foo() const = 0;
};

#endif // IMY_CLASS_H

Source Code Location: example/my_class.h

‎/******************************************************************************
 * Copyright 1986, 2011 NVIDIA Corporation. All rights reserved.
 *****************************************************************************/

#ifndef MY_CLASS_H
#define MY_CLASS_H

#include <mi/neuraylib.h>
#include "imy_class.h"

// The implementation of the IMy_class interface
class My_class : public
    mi::neuraylib::User_class<0x0650d689,0xef50,0x433f,0xb3,0xae,0xae,0x83,0xa9,0xf2,0xf2,0xa6,
                              IMy_class>
{
public:
    // Constructor
    My_class() { m_foo = 0; }
    
    // Destructor
    ~My_class() { }

    // Sets property foo
    void set_foo( mi::Sint32 foo) { m_foo = foo; }

    // Gets property foo
    mi::Sint32 get_foo() const { return m_foo; }

    // Serializes an instance of My_class
    void serialize( INVALID_DOXYREFmi::ISerializer* serializer) const
    {
        serializer->INVALID_DOXYREF( &m_foo, 1);
    }

    // Deserializes an instance of My_class
    void deserialize( INVALID_DOXYREFmi::IDeserializer* deserializer)
    {
        deserializer->INVALID_DOXYREF( &m_foo, 1);
    }

    // Creates a copy of the object
    mi::neuraylib::IUser_class* copy () const
    {
        My_class* copy = new My_class( *this);
        return copy;
    }

    // Returns a human readable class name
    const char* get_class_name() const
    {
        return "My_class";
    }

    // Returns the list of elements referenced by this elements, none in this example.
    mi::IArray* get_references( mi::neuraylib::ITransaction* transaction) const
    {
        return 0;
    }
    
private:
    // Member to realize property foo
    mi::Sint32 m_foo;
};

#endif // MY_CLASS_H

Source Code Location: examples/example_user_defined_classes.cpp

‎/******************************************************************************
 * Copyright 1986, 2011 NVIDIA Corporation. All rights reserved.
 *****************************************************************************/

// examples/example_user_defined_classes.cpp
//
// Demonstrates implementation and usage of user-defined classes

#include <mi/neuraylib.h>

// Include code shared by all examples.
#include "example_shared.h"
// Include header file for the interface of the user-defined class.
#include "imy_class.h"
// Include header file for the implementation of the user-defined class.
#include "my_class.h"

void configuration( mi::base::Handle< mi::neuraylib::INeuray> neuray)
{
    // Register the user-defined class.
    mi::base::Handle< mi::neuraylib::IExtension_api> extension_api(
        neuray->get_api_component<mi::neuraylib::IExtension_api>());
    check_success( extension_api.is_valid_interface());
    check_success( extension_api->register_class<My_class>( "My_class") == 0);
}
    
void test_plugin( mi::base::Handle< mi::neuraylib::INeuray> neuray)
{
    // Get the database, the global scope, which is the root for all transactions,
    // and create a transaction.
    mi::base::Handle< mi::neuraylib::IDatabase> database(
        neuray->get_api_component<mi::neuraylib::IDatabase>());
    check_success( database.is_valid_interface());
    mi::base::Handle< mi::neuraylib::IScope> scope(
        database->get_global_scope());
    mi::base::Handle< mi::neuraylib::ITransaction> transaction(
        scope->create_transaction());
    check_success( transaction.is_valid_interface());

    // Create instance of My_class and call a method on it.
    mi::base::Handle< IMy_class> my_class( transaction->create<IMy_class>( "My_class"));
    check_success( my_class.is_valid_interface());
    my_class->set_foo( 42);

    // Store instance of My_class in the database and release the handle
    check_success( transaction->store( my_class.get(), "some_name") == 0);
    my_class = 0;

    // Get the instance of My_class from the database again and change the property
    my_class = transaction->edit<IMy_class>( "some_name");
    check_success( my_class.is_valid_interface());
    check_success( my_class->get_foo() == 42);
    my_class->set_foo( 43);
    my_class = 0;

    // All transactions need to get committed or aborted, not really important in this example.
    transaction->commit();
}

int main( int argc, char* argv[])
{
    // Access the neuray library
    mi::base::Handle< mi::neuraylib::INeuray> neuray( load_and_get_ineuray());
    check_success( neuray.is_valid_interface());

    // Configure the neuray library
    configuration( neuray);

    // Start the neuray library
    check_success( neuray->start( true) == 0);

    // Load and interact with the plugin
    test_plugin( neuray);

    // Shut down the neuray library
    check_success( neuray->shutdown() == 0);
    neuray = 0;

    // Unload the neuray library
    check_success( unload());

    return EXIT_SUCCESS;
}

[Previous] [Next] [Up]