ClassMemberVariables.cpp

// ClassMemberVariables.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2007

@import "Ceda/cxPython/cxPython.h"
#include "Ceda/cxUtils/TracerUtils.h"

///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Class member variables
----------------------

Reflected class member variables can be directly accessed using Python.  This includes member 
variables that are themselves class variables.
*/
namespace ClassMemberVariables1
{
    $struct+ X
    {
        X() : a(0),b(1.5) {}
        
        $ceda::int32 a;
        $ceda::float64 b;
    };

    $struct+ Y
    {
        Y() : c(false) {}
        
        $X x;
        $bool c;
    };

    $function+ Y CreateY()
    {
        return Y();
    }

    void Run()
    {
        ceda::TraceGroup g("Class member variables example 1");

        PyRun_SimpleString(
            @strx
            (
                @def mPrint(v) = print @str(v = ) + `v`

                ClassMemberVariables1 = rootnamespace.ClassMemberVariables1
                y = ClassMemberVariables1.CreateY()
                
                # Read access to members
                mPrint(y.c)
                mPrint(y.x.a)
                mPrint(y.x.b)
                mPrint(y)
                mPrint(y.x)

                # Write access to members
                y.x.a = 10;
                mPrint(y)

                # dir() on a reflected class
                mPrint(dir(y))
            ));
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
/*
A member variable of a class that is itself a class variable can be assigned in a single 
statement (ie without the need to assign each member separately

In the following example the Python code is able to assign entire Point structs in a single 
assignment statement.

The framework is able to achieve this using the assignment function available in the reflected
class for Point.  It doesn't actually require all members of Point to be reflected in order to
do the assignment.
*/
namespace ClassMemberVariables2
{
    $struct+ Point <<os>>
    {
        Point(ceda::int32 _x,ceda::int32 _y) : x(_x), y(_y) {}
        ceda::int32 x;
        ceda::int32 y;
        
        void Write(ceda::xostream& os) const { os << '(' << x << ',' << y << ')'; }
    };
    
    $struct+ Line <<os>>
    {
        Line(ceda::int32 x1,ceda::int32 y1,ceda::int32 x2,ceda::int32 y2) : p1(x1,y1), p2(x2,y2) {}
        $Point p1;
        $Point p2;
        
        void Write(ceda::xostream& os) const { os << p1 << '-' << p2; }
    };

	$function+ Line CreateLine(ceda::int32 x1,ceda::int32 y1,ceda::int32 x2,ceda::int32 y2)
	{
	    return Line(x1,y1,x2,y2);
	}
	
	void Run()
	{
		ceda::TraceGroup g("Class member variables example 2");
		
        PyRun_SimpleString(
            @strx
            (
		        @def mPrint(v) = print @str(v = ) + `v`
        
                ClassMemberVariables2 = rootnamespace.ClassMemberVariables2
                
                line1 = ClassMemberVariables2.CreateLine(10,20,30,40)
                line2 = ClassMemberVariables2.CreateLine(100,200,300,400)
                
                mPrint(line1)
                mPrint(line2)

                line1.p1 = line2.p2
                mPrint(line1)
            ));
	}	
}

///////////////////////////////////////////////////////////////////////////////////////////////////
namespace ClassMemberVariables
{
    void Run()
    {
        ClassMemberVariables1::Run();
        ClassMemberVariables2::Run();
    }
}