Creation.cpp
// Creation.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2009
@import "Ceda/cxPython/cxPython.h"
@import "Ceda/cxObject/Object.h"
@import "Ceda/cxObject/WCSpace.h"
#include "Ceda/cxUtils/TracerUtils.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Creation 1
----------
If X is the name of a reflected class with a reflected default constructor, then X()
can be used within Python to bind to a heap allocated instance of an X that is
automatically deleted when the associated PyObject reference count falls to zero.
This is regardless of whether X implements IObject.
For classes that implement IObject, X.new() is equivalent to $new X. The instance is instead
owned by the CSpace, which must have been set in thread local storage.
In the following example there is no memory leak.
*/
namespace Creation1
{
$struct+ X1
{
X1() : m_x(100)
{
Tracer() << "X1()\n";
}
~X1()
{
Tracer() << "~X1()\n";
}
$ceda::int32 m_x;
};
void Run()
{
ceda::TraceGroup g("Creation example 1");
PyRun_SimpleString(
@strx
(
print 'rootnamespace.Creation1.X1 = ' + `rootnamespace.Creation1.X1`
print 'type(rootnamespace.Creation1.X1) = ' + `type(rootnamespace.Creation1.X1)`
x = rootnamespace.Creation1.X1()
print 'x = ' + `x`
print 'type(x) = ' + `type(x)`
));
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Creation 2
----------
If X is the name of a reflected class implementing IObject and with a reflected default
constructor, then X.new() can be used within Python to bind to a heap allocated instance
of an X that is registered with the affiliated CSpace in thread local storage.
The object is deleted by the CSpace, not by the associated PyObject. Furthermore the
associated PyObject doesn't contribute to the reachability from the roots for the purpose
of garbage collection by the CSpace.
In the following example there is no memory leak.
*/
namespace Creation2
{
$struct+ X2 isa ceda::IObject
{
X2() : m_x(100)
{
Tracer() << "X2()\n";
}
~X2()
{
Tracer() << "~X2()\n";
}
$ceda::int32 m_x;
};
void Run()
{
ceda::TraceGroup g("Creation example 2");
ceda::CSpaceCreator cspace;
ceda::CSpaceLock lock(ceda::ECSpaceLockMode::Exclusive);
PyRun_SimpleString(
@strx
(
# Registered in the CSpace
x = rootnamespace.Creation2.X2.new()
print 'x = ' + `x`
print 'type(x) = ' + `type(x)`
print 'type(x.m_x) = ' + `type(x.m_x)`
# Not registered in the CSpace
y = rootnamespace.Creation2.X2()
print 'y = ' + `y`
));
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Creation 3
----------
Similar to Creation2 example, except we now use a datasource.
*/
namespace Creation3
{
$struct+ X3 isa ceda::IObject :
model
{
ceda::int32 v;
$dropped
{
ceda::int32 w;
}
$schema
{
1: +v +w
2: -w
}
}
{
X3()
{
Tracer() << "X3()\n";
v = 20;
}
~X3()
{
Tracer() << "~X3()\n";
}
};
void Run()
{
ceda::TraceGroup g("Creation example 3");
//ceda::CSpaceCreator cspace;
//ceda::CSpaceLock lock;
PyRun_SimpleString(
@strx
(
ceda = rootnamespace.ceda
print `dir(ceda)`
cs = ceda.CreateCSpace2(1000)
print 'GC every ' + `cs.GetMilliSecsPerGc()` + ' msec'
print 'Eviction threshold ' + `cs.GetEvictionThreshold()` + ' bytes'
ceda.SetThreadCSpace(cs)
cs.Lock(ceda.ECSpaceLockMode.Exclusive)
x = rootnamespace.Creation3.X3.new()
print 'x = ' + `x`
print 'x.v = ' + `x.v`
x.v = 100;
print 'x = ' + `x`
print 'x.v = ' + `x.v`
cs.Unlock()
cs.Destroy()
));
}
}
/*
namespace Creation4
{
$struct X4 isa ceda::IObject :
model
{
ceda::int32 v;
}
{
X4()
{
v = 20;
}
};
void Run()
{
ceda::CSpaceCreator cspace;
ceda::CSpaceLock lock(ceda::ECSpaceLockMode::Exclusive);
X4* x = $new X4;
x->v = 100;
}
}
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
namespace Creation
{
void Run()
{
Creation1::Run();
Creation2::Run();
Creation3::Run();
}
}