RifPlugin
Splitting .cpp and .h Files


return to main index



Introduction

The source code for a RifPlugin is generally written as a single .cpp file. Such files contain both the declarations of the methods and instance variables (the "interface") of a rif plugin class AND the implementations of it's methods. For example, listing 1 shows the code for a simple rif named BBones. The red double line shown in bold indicates the division where declarations end (the upper part of the file) and where method implementations begin (the lower half of the file).


Listing 1 (BBones.cpp)


#include <RifPlugin.h>
  
class BBones : public RifPlugin {
    public:  
             BBones();
    virtual ~BBones() { }
    
    // Having used RifPluginManufacture() to get an instance of
    // the plugin, PRMan can access BBones custom filter(s).
    virtual RifFilter &GetFilter() { return m_filter; }
    
    private:
        RifFilter       m_filter; 
        static RtVoid    attribute(RtToken name, RtInt nvals, RtToken tokens[], RtPointer params[]);
    };
    
//===========================================================
    
// PRMan calls this function in order to get an instance of
// the rif plugin implemented by BBones.
RifPlugin *RifPluginManufacture(int argc, char **argv) {
    return new BBones();
    }
  
// Constructor. Our attribute() method will be used by PRMan
// instead of the default AttributeV() method supplied by the
// RifPlugin base class.    
BBones::BBones() {
    m_filter.AttributeV = attribute;
    }
  
// The barebones class does nothing fancy in this method.
RtVoid BBones::attribute(RtToken name, RtInt nvals, RtToken tokens[], RtPointer params[]) {
    RiArchiveRecord(RI_COMMENT, name);
    RiAttributeV(name, nvals, tokens, params);
    }


Occasionaly it is beneficial to divide a single C++ file into two files. One file contains the interface declarations of a class and the other file contains the implementations of the class methods.


Two Source Code Files

This page provides an example of how the source of a rif plugin is divided in to an interface (.h) and an implementation file (.cpp). The rif plugin, implemented in the first listing, echoes the type of each Attribute it processes (filters) as a commented line of text. For example, if an unfiltered rib contains these lines,

    Attribute "identifier" "string name" ["pSphereShape1"]
    Attribute "identifier" "float id" [1]

Then the same rib after rif'ing by BBones would have these lines,

    #identifier
    Attribute "identifier" "string name" ["pSphereShape1"]
    #identifier
    Attribute "identifier" "float id" [1]

Not a very useful plugin but adequate for the purposes of this tutorial. Listings 2 and 3 gives the code for the interface file (.h) and a separate implementation file (.cpp). Notice the contents of the .h file are "wrapped" in a ifndef/endif block to ensure that BBones.h cannot be included more once when it is referenced by one or more .cpp files.


Listing 2 (BBones.h - interface file)


#ifndef BBONES_H
#define BBONES_H
  
#include <RifPlugin.h>
  
class BBones : public RifPlugin {
    public:
             BBones();
    virtual ~BBones();
    virtual RifFilter &GetFilter();
    
    private:
        RifFilter       m_filters; 
        static RtVoid   attribute(RtToken name, RtInt nvals, RtToken tokens[], RtPointer params[]);
    };
#endif


The next listing is very similar to original code show in listing 1. However, it contains only the implementations of the class methods.


Listing 3 (BBones.cpp - implementation file)


#include "BBones.h"
  
// PRMan calls this function in order to get an instance of
// the rif plugin implemented by BBones.
RifPlugin *RifPluginManufacture(int argc, char **argv) {
    return new BBones();
    }
        
// Constructor. Our attribute() method will be used by PRMan
// instead of the default AttributeV() method supplied by the
// RifPlugin base class.    
BBones::BBones() {
    m_filters.AttributeV = attribute;
    }
    
// Destructor
BBones::~BBones() { }    
  
// Having used RifPluginManufacture() to get an instance of
// the plugin, PRMan can access BBones custom filter(s).
RifFilter& BBones::GetFilter() { 
    return m_filters; 
    }
  
// The barebones class does nothing fancy in this method.
RtVoid BBones::attribute(RtToken name, RtInt nvals, RtToken tokens[], RtPointer params[]) {
    RiArchiveRecord(RI_COMMENT, name);
    RiAttributeV(name, nvals, tokens, params);
    }



© 2002- Malcolm Kesson. All rights reserved.