From: <z-...@us...> - 2008-01-11 11:15:38
|
Revision: 7505 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=7505&view=rev Author: z-man Date: 2008-01-11 03:15:43 -0800 (Fri, 11 Jan 2008) Log Message: ----------- Adaptions to Io-2008-01-07. Still crashes, but at least it compiles now :) Modified Paths: -------------- private/z-man/clio/classname.hpp private/z-man/clio/dataconversion.hpp private/z-man/clio/dataconversion_extended.cpp private/z-man/clio/dataconversion_extended.hpp private/z-man/clio/functioninfo.hpp private/z-man/clio/gcmarker.cpp private/z-man/clio/gcmarker.hpp private/z-man/clio/iclassinfo.cpp private/z-man/clio/iclassinfo.hpp private/z-man/clio/ifunctioninfo.cpp private/z-man/clio/ifunctioninfo.hpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapper.hpp private/z-man/clio/virtual_helper.cpp Modified: private/z-man/clio/classname.hpp =================================================================== --- private/z-man/clio/classname.hpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/classname.hpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -9,7 +9,8 @@ #include <ostream> #include <sstream> -class IoObject; +//class IoObject; +#include <IoObject_struct.h> namespace clio { Modified: private/z-man/clio/dataconversion.hpp =================================================================== --- private/z-man/clio/dataconversion.hpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/dataconversion.hpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -13,7 +13,8 @@ #include "argumentquality.hpp" // #include "gcpointer.hpp" -struct IoObject; +#include <IoObject_struct.h> +// struct IoObject; struct IoState; #include <IoMessage.h> Modified: private/z-man/clio/dataconversion_extended.cpp =================================================================== --- private/z-man/clio/dataconversion_extended.cpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/dataconversion_extended.cpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -54,7 +54,7 @@ CharProxy * p = new CharProxy( to ); // make the object know to and owned by Io so it gets deleted later - ClassInfo::Get().FetchIoObject( p, (IoState *)from->state, ObjectWrapper::OwnedByIo ); + ClassInfo::Get().FetchIoObject( p, IoObject_state(from), ObjectWrapper::OwnedByIo ); // return its contents return *p; Modified: private/z-man/clio/dataconversion_extended.hpp =================================================================== --- private/z-man/clio/dataconversion_extended.hpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/dataconversion_extended.hpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -3,6 +3,8 @@ #include "dataconversion.hpp" +#include <IoObject_struct.h> + #include <IoNumber.h> #include <IoState.h> @@ -47,7 +49,7 @@ static Converted FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) { // compare object with singletons - IoState * state = (IoState *)from->state; + IoState * state = IoObject_state(from); if ( from == state->ioTrue ) return true; else if ( from == state->ioFalse ) @@ -333,7 +335,7 @@ p->Detach(); // make the object know to and owned by Io so it gets deleted later - ClassInfo::Get().FetchIoObject( p, (IoState *)from->state, ObjectWrapper::OwnedByIo ); + ClassInfo::Get().FetchIoObject( p, IoObject_state(from), ObjectWrapper::OwnedByIo ); // return a refernece to the held data return p->GetTarget(); @@ -361,7 +363,7 @@ static inline IoObject * FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) { - if ( from && from->state && from == ((IoState *) from->state)->ioNil ) + if ( from && IoObject_state(from) && from == IoObject_state(from)->ioNil ) return 0; return from; Modified: private/z-man/clio/functioninfo.hpp =================================================================== --- private/z-man/clio/functioninfo.hpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/functioninfo.hpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -15,7 +15,8 @@ #include "function.hpp" -class IoObject; +#include <IoObject_struct.h> +// class IoObject; namespace clio { Modified: private/z-man/clio/gcmarker.cpp =================================================================== --- private/z-man/clio/gcmarker.cpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/gcmarker.cpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -184,21 +184,21 @@ } } - static TagMarkFunc * oldMarkHook_; + static IoTagMarkFunc * oldMarkHook_; virtual void DoRegister( IoState * state, ExtraInfo const & info ) CLIO_NOTHROW { - IoTag * lobbyTag = state->lobby->tag; + IoTag * lobbyTag = IoObject_tag( IoState_lobby(state) ); // store old mark hook - oldMarkHook_ = lobbyTag->markFunc; + oldMarkHook_ = IoTag_markFunc(lobbyTag); // install replacement - lobbyTag->markFunc = (TagMarkFunc *) & MarkHook; + lobbyTag->markFunc = (IoTagMarkFunc *) & MarkHook; } }; -TagMarkFunc * HookRegistrator::oldMarkHook_ = 0; +IoTagMarkFunc * HookRegistrator::oldMarkHook_ = 0; static HookRegistrator registrator; Modified: private/z-man/clio/gcmarker.hpp =================================================================== --- private/z-man/clio/gcmarker.hpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/gcmarker.hpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -1,9 +1,10 @@ #ifndef CLIO_GCMARKER_H #define CLIO_GCMARKER_H -class IoObject; +// class IoObject; class IoState; +#include <IoObject_struct.h> #include "nocopy.hpp" #include <assert.h> Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/iclassinfo.cpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -173,24 +173,24 @@ if ( !self ) return false; - if ( !self->data.ptr ) + if ( !IoObject_dataPointer(self) ) return false; - IoTag * tag = self->tag; + IoTag * tag = IoObject_tag(self); if ( !tag ) return false; // and the registered deallocation function must be ours. - return ( tag->freeFunc == (TagFreeFunc*) &Free ); + return ( IoTag_freeFunc(tag) == (IoTagFreeFunc*) &Free ); } // returns the wrapper belonging to self. self must be a clio object. ObjectWrapper & IClassInfo::GetObjectWrapper( IoObject * self ) CLIO_NOTHROW { assert( IsClioObject( self ) ); - assert( self->data.ptr ); + assert( IoObject_dataPointer( self ) ); - return *reinterpret_cast<ObjectWrapper*>(self->data.ptr); + return *reinterpret_cast<ObjectWrapper*>( IoObject_dataPointer( self ) ); } // register a base class @@ -208,7 +208,7 @@ IoObject * IClassInfo::CloneIo( IoObject * self ) { assert( self ); - IoState * state = (IoState *)self->state; + IoState * state = IoObject_state( self ); assert( state ); return IoObject_clone( self, IoObject_new( state ), IoMessage_newWithName_( state, IOSYMBOL("clone") ) ); @@ -285,7 +285,7 @@ do { assert( run->GetSelf() ); - if ( run->GetSelf()->state == state ) + if ( IoObject_state( run->GetSelf() ) == state ) { return run; } @@ -444,8 +444,8 @@ { IoObject * self = IoObject_new( state ); - self->tag = Tag( state ); - self->data.ptr = CreatePrototype( self ); + IoObject_tag_( self, Tag( state ) ); + IoObject_setDataPointer_( self, CreatePrototype( self ) ); return self; } @@ -525,9 +525,9 @@ // fill with the various function pointers and the state tag->state = state; - tag->cloneFunc = (TagCloneFunc*) RawClone; - tag->markFunc = (TagMarkFunc*) Mark; - tag->freeFunc = (TagFreeFunc*) Free; + tag->cloneFunc = (IoTagCloneFunc*) RawClone; + tag->markFunc = (IoTagMarkFunc*) Mark; + tag->freeFunc = (IoTagFreeFunc*) Free; // tag->performFunc = (TagPerformFunc*) Perform; // tag->activateFunc = (TagActivateFunc*) Activate; @@ -539,7 +539,7 @@ { try { - CallInfo info( self, (IoState *)self->state ); + CallInfo info( self, IoObject_state( self ) ); // std::cout << "Cloning " << name_ << "\n"; // clone Io part of object @@ -549,7 +549,7 @@ ObjectWrapper & wrapper = GetObjectWrapper( self ); // add C++ payload, either cloned or new - clone->data.ptr = new ObjectWrapper( wrapper, clone ); + IoObject_setDataPointer_( clone, new ObjectWrapper( wrapper, clone ) ); return clone; } @@ -557,13 +557,13 @@ { std::ostringstream error; error << "on trying to clone C++ object '" << IoObject_name( self ) << "'"; - IoState_error_( (IoState *)self->state, NULL, "%s", e.GetDescription( error.str() ).c_str() ); + IoState_error_( IoObject_state( self ), NULL, "%s", e.GetDescription( error.str() ).c_str() ); } catch( ... ) { std::ostringstream error; error << "Unknown error while trying to clone C++ object '" << IoObject_name( self ) << "'"; - IoState_error_( (IoState *)self->state, NULL, "%s", error.str().c_str() ); + IoState_error_( IoObject_state( self ), NULL, "%s", error.str().c_str() ); } return 0; @@ -583,10 +583,10 @@ { assert( run ); assert( run->GetSelf() ); - assert( run->GetSelf()->state ); + assert( IoObject_state( run->GetSelf() ) ); // have them marked, too, if they are managed by the same collector - if ( ( (IoState *)run->GetSelf()->state )->collector == ( (IoState *)wrapper->GetSelf()->state )->collector ) + if ( IoObject_state( run->GetSelf() )->collector == IoObject_state( wrapper )->collector ) IoObject_shouldMark( run->GetSelf() ); run = run->Next(); @@ -601,12 +601,12 @@ // free data IoObject * IClassInfo::Free(IoObject *self) CLIO_NOTHROW { - if (self->data.ptr) + if ( IoObject_dataPointer( self ) ) { - ObjectWrapper * obj = reinterpret_cast<ObjectWrapper *>(self->data.ptr); + ObjectWrapper * obj = reinterpret_cast<ObjectWrapper *>( IoObject_dataPointer( self ) ); if (obj) delete obj; - self->data.ptr = NULL; + IoObject_setDataPointer_( self, NULL ); } return self; @@ -623,7 +623,7 @@ assert( self ); // retrieve its wrapper (cast is safe, the object has just been created ) - ObjectWrapper * wrapper = static_cast< ObjectWrapper * >( self->data.ptr ); + ObjectWrapper * wrapper = static_cast< ObjectWrapper * >( IoObject_dataPointer( self ) ); // register more things (methods) GetClassRegistratorSet().RegisterAll( state, wrapper ); Modified: private/z-man/clio/iclassinfo.hpp =================================================================== --- private/z-man/clio/iclassinfo.hpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/iclassinfo.hpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -11,7 +11,8 @@ #include <vector> #include <string> -class IoObject; +#include <IoObject_struct.h> +// class IoObject; #include <IoState.h> Modified: private/z-man/clio/ifunctioninfo.cpp =================================================================== --- private/z-man/clio/ifunctioninfo.cpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/ifunctioninfo.cpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -77,12 +77,12 @@ { for( std::vector< IoObject * >::const_iterator iter = arguments.begin(); iter != arguments.end(); ++iter ) { - if ( (*iter) && (*iter)->tag && (*iter)->tag->name ) + if ( (*iter) && IoObject_tag(*iter) && IoObject_tag(*iter)->name ) { if ( iter != arguments.begin() ) s << ", "; - s << "'" << (*iter)->tag->name << "'"; + s << "'" << IoObject_tag(*iter)->name << "'"; } } } @@ -151,7 +151,7 @@ assert( self ); // get state - IoState * state = (IoState *)self->state; + IoState * state = IoObject_state( self ); assert( state ); // mark the call as coming from the script @@ -344,7 +344,7 @@ ClioFunctionData *selfData = DATA(self); // get state - IoState * state = (IoState *)self->state; + IoState * state = IoObject_state( self ); // store call info CallInfo callInfo( target, state ); @@ -419,7 +419,7 @@ { IoObject *self = IoObject_rawClonePrimitive(proto); IoObject_setDataPointer_(self, cpalloc(DATA(proto), sizeof(ClioFunctionData))); - self->isActivatable = 1; + IoObject_isActivatable_( self, 1 ); return self; } @@ -427,18 +427,18 @@ { IoTag *tag = IoTag_newWithName_("ClioFunction"); tag->state = state; - tag->cloneFunc = (TagCloneFunc *)ClioFunction_rawClone; - tag->markFunc = (TagMarkFunc *)IoCFunction_mark; - tag->activateFunc = (TagActivateFunc *)ClioFunction_activate; + tag->cloneFunc = (IoTagCloneFunc *)ClioFunction_rawClone; + tag->markFunc = (IoTagMarkFunc *)IoCFunction_mark; + tag->activateFunc = (IoTagActivateFunc *)ClioFunction_activate; // tag->performFunc = (TagPerformFunc *)ClioFunction_performOn; - tag->freeFunc = (TagFreeFunc *)IoCFunction_free; + tag->freeFunc = (IoTagFreeFunc *)IoCFunction_free; return tag; } IoCFunction * ClioFunction_proto(void *state) { IoObject *self = IoObject_new(state); - self->tag = ClioFunction_tag(state); + IoObject_tag_( self, ClioFunction_tag(state) ); IoObject_setDataPointer_(self, calloc(1, sizeof(ClioFunctionData))); DATA(self)->func = IoObject_self; @@ -502,17 +502,17 @@ IoObject * IoObject_addClioMethod_( IoObject *self, IoSymbol *slotName, IFunctionInfo *fp ) { - IoTag *t = self->tag; + IoTag *t = IoObject_tag( self ); IoObject *proto = IoState_protoWithInitFunction_(IOSTATE, IoObject_proto); IoCFunction *f; - if (t == proto->tag) + if (t == IoObject_tag( proto ) ) { t = 0x0; } IoObject * other = IoObject_getSlot_( self, slotName ); - if ( other && other != ((IoState *)other->state)->ioNil && + if ( other && other != IoObject_state(other)->ioNil && IFunctionInfo::IsClioFunction( other ) // Io stuff gets overwritten without mercy ) { @@ -594,7 +594,7 @@ // test whether the given object is a clio function bool IFunctionInfo::IsClioFunction( IoObject * object ) CLIO_NOTHROW { - return object->tag->activateFunc == (TagActivateFunc *)clio::ClioFunction_activate; + return IoObject_tag(object)->activateFunc == (IoTagActivateFunc *)clio::ClioFunction_activate; } // registers a function info for deletion on program exit Modified: private/z-man/clio/ifunctioninfo.hpp =================================================================== --- private/z-man/clio/ifunctioninfo.hpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/ifunctioninfo.hpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -8,7 +8,8 @@ #include <vector> #include <IoMessage.h> -class IoObject; +#include <IoObject_struct.h> +// class IoObject; class ObjectWrapperAware; namespace clio Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/objectwrapper.cpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -29,7 +29,7 @@ // form linked list loop Insert( this ); if ( self ) - markers_.SetState( (IoState*)self->state ); + markers_.SetState( IoObject_state(self) ); } // destructor @@ -38,7 +38,7 @@ // std::cout << "Wrapper destroyed\n"; assert( self_ ); - CallInfo info( self_, (IoState *)self_->state ); + CallInfo info( self_, IoObject_state(self_) ); if ( object_ ) { @@ -92,7 +92,7 @@ if ( !IClassInfo::IsClioObject( self ) ) return NULL; - return static_cast< ObjectWrapper * >( self->data.ptr ); + return static_cast< ObjectWrapper * >( IoObject_dataPointer( self ) ); } // copy constructor for cloning @@ -139,18 +139,18 @@ } if ( self ) - markers_.SetState( (IoState*)self->state ); + markers_.SetState( IoObject_state(self) ); } ObjectWrapperPrototype::ObjectWrapperPrototype( IClassInfo const & classInfo, IoObject * self ) : ObjectWrapper( classInfo, self ) { - ObjectWrapper::GetClassInfo().RegisterPrototype( static_cast< IoState * >( self->state ), this ); + ObjectWrapper::GetClassInfo().RegisterPrototype( IoObject_state(self), this ); } ObjectWrapperPrototype::~ObjectWrapperPrototype() { - ObjectWrapper::GetClassInfo().UnregisterPrototype( static_cast< IoState * >( ObjectWrapper::GetSelf()->state ), this ); + ObjectWrapper::GetClassInfo().UnregisterPrototype( IoObject_state( ObjectWrapper::GetSelf() ), this ); } } Modified: private/z-man/clio/objectwrapper.hpp =================================================================== --- private/z-man/clio/objectwrapper.hpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/objectwrapper.hpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -5,7 +5,8 @@ #include "linkedlist.hpp" #include "gcmarker.hpp" -class IoObject; +#include <IoObject_struct.h> +// dclass IoObject; // implementation Modified: private/z-man/clio/virtual_helper.cpp =================================================================== --- private/z-man/clio/virtual_helper.cpp 2008-01-11 07:26:02 UTC (rev 7504) +++ private/z-man/clio/virtual_helper.cpp 2008-01-11 11:15:43 UTC (rev 7505) @@ -31,7 +31,7 @@ slotName_ = slotName; // get Io state - state_ = (IoState *)self_->state; + state_ = IoObject_state( self ); // find method by the slotname method_ = IoObject_getSlot_( self, slotName ); @@ -115,7 +115,7 @@ { // get state assert( self_ ); - IoState * state = (IoState *)self_->state; + IoState * state = IoObject_state( self_ ); // new message (if needed) CreateMessage(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-01-17 13:33:34
|
Revision: 7531 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=7531&view=rev Author: z-man Date: 2008-01-17 05:33:06 -0800 (Thu, 17 Jan 2008) Log Message: ----------- Fixed new gcc 4.2.2 warnings. Modified Paths: -------------- private/z-man/clio/dataconversion_extended.cpp private/z-man/clio/dataconversion_extended.hpp private/z-man/clio/enum.cpp private/z-man/clio/enum.hpp Modified: private/z-man/clio/dataconversion_extended.cpp =================================================================== --- private/z-man/clio/dataconversion_extended.cpp 2008-01-17 13:26:51 UTC (rev 7530) +++ private/z-man/clio/dataconversion_extended.cpp 2008-01-17 13:33:06 UTC (rev 7531) @@ -34,7 +34,7 @@ } } -char * primitveProxyCode = +char const * primitveProxyCode = "clone := method( get clone )\n" "print := method( get print )\n" "== := method( other, get ==(other) )\n" Modified: private/z-man/clio/dataconversion_extended.hpp =================================================================== --- private/z-man/clio/dataconversion_extended.hpp 2008-01-17 13:26:51 UTC (rev 7530) +++ private/z-man/clio/dataconversion_extended.hpp 2008-01-17 13:33:06 UTC (rev 7531) @@ -244,7 +244,7 @@ {} }; -extern char * primitveProxyCode; +extern char const * primitveProxyCode; struct PrimitiveProxyNoMaster{}; Modified: private/z-man/clio/enum.cpp =================================================================== --- private/z-man/clio/enum.cpp 2008-01-17 13:26:51 UTC (rev 7530) +++ private/z-man/clio/enum.cpp 2008-01-17 13:33:06 UTC (rev 7531) @@ -2,7 +2,7 @@ namespace clio { - char * enumIoCode = + char const * enumIoCode = "print := method( getName_( self ) print )\n" "toSimpleString := method( getName_( self ) )\n" "toString := method( getName_( self ) )\n" Modified: private/z-man/clio/enum.hpp =================================================================== --- private/z-man/clio/enum.hpp 2008-01-17 13:26:51 UTC (rev 7530) +++ private/z-man/clio/enum.hpp 2008-01-17 13:33:06 UTC (rev 7531) @@ -52,7 +52,7 @@ static ENUM With( int in ){ return (ENUM)(in); } }; -extern char * enumIoCode; +extern char const * enumIoCode; // overload template factory creation template< class E > struct EnumFactoryCreator This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-19 10:12:51
|
Revision: 7999 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=7999&view=rev Author: z-man Date: 2008-02-19 02:12:53 -0800 (Tue, 19 Feb 2008) Log Message: ----------- Repaired GC smart pointers, they no longer require the hacky sharing of one GC by several states. Downside: they no longer resolve cyclic references across states. Well, Don't Do That, Then. Modified Paths: -------------- private/z-man/clio/gcmarker.cpp private/z-man/clio/gcmarker.hpp private/z-man/clio/iclassinfo.cpp private/z-man/clio/iclassinfo.hpp private/z-man/clio/state.cpp private/z-man/clio/state.hpp private/z-man/clio/stateregistrator.cpp private/z-man/clio/stateregistrator.hpp private/z-man/clio/tests/smartpointer.test/test.cpp Modified: private/z-man/clio/gcmarker.cpp =================================================================== --- private/z-man/clio/gcmarker.cpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/gcmarker.cpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -177,6 +177,11 @@ // mark all orphaned markers GCAutoMarkerBigSet::Get().MarkAll( self ); + // go through all primary wrappers, see if they + // have secondary wrappers, and if yes, mark them. + // this allows cross-vm references. + IStateRegistrator::MarkAll( IOSTATE ); + // call old hook if ( oldMarkHook_ ) { Modified: private/z-man/clio/gcmarker.hpp =================================================================== --- private/z-man/clio/gcmarker.hpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/gcmarker.hpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -136,7 +136,7 @@ }; // a small collection of GC auto markers. It holds the markers that belong -// to the C+= part of a single Io object. +// to the C++ part of a single Io object. class GCAutoMarkerSmallSet: public IGCAutoMarkerSet { public: Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/iclassinfo.cpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -424,7 +424,7 @@ totalBases_ = 0; // recount. Virtual base classes are counted many times, in pathological cases, - // this may make the class count explode. But also the work dynamic_cast has to do, so + // this may make the class count explode. But that is also the work dynamic_cast has to do, so // we don't worry about it happening in real life too much. for ( Casters::const_iterator iter = upcasts_.begin(); iter != upcasts_.end(); ++iter ) { @@ -694,7 +694,26 @@ } } +// marks objects shared by other states +void IClassInfo::OnMark( IoState * state ) CLIO_NOTHROW +{ + // iterate over all wrappers + for ( WrapperMap::iterator i = wrapperMap_.begin(); i != wrapperMap_.end(); ++i ) + { + ObjectWrapper * wrapper = (*i).second; + if ( wrapper ) + { + IoObject * self = wrapper->GetSelf(); + // is the object owned by the given state, and is it shared? + if ( self && IOSTATE == state && wrapper->Next() != wrapper ) + { + IoObject_shouldMark( self ); + } + } + } +} + // clones an Io object derived from T, but instead of cloning the C++ core, the // provided alternative core object is used IoObject * IClassInfo::CloneOverride( IoObject * original, void * override ) CLIO_NOTHROW Modified: private/z-man/clio/iclassinfo.hpp =================================================================== --- private/z-man/clio/iclassinfo.hpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/iclassinfo.hpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -195,6 +195,9 @@ virtual void DoRegister( IoState * state, ExtraInfo const & info ) CLIO_NOTHROW; virtual void DoPreRegister( IoState * state ) CLIO_NOTHROW; virtual void DoPostRegister( IoState * state ) CLIO_NOTHROW; + + // marks all shared objects + virtual void OnMark( IoState * state ) CLIO_NOTHROW; // returns the size of the wrapped object virtual size_t DoGetSize() const CLIO_NOTHROW = 0; Modified: private/z-man/clio/state.cpp =================================================================== --- private/z-man/clio/state.cpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/state.cpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -38,7 +38,7 @@ { if ( originalCollector_ ) { - Collector_freeAllValues( self_->collector ); + // Collector_freeAllValues( self_->collector ); self_->collector = originalCollector_; } Modified: private/z-man/clio/state.hpp =================================================================== --- private/z-man/clio/state.hpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/state.hpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -5,7 +5,7 @@ class IoState; -#include <Collector.h> + #include <Collector.h> namespace clio { @@ -35,15 +35,15 @@ return self_; } - // installs a different garbage collector - void SetCollector( Collector * collector ); - // makes sure state points to a valid and meaningful state static void GetDefaultState( IoState * & state ); // return a default state static IoState * GetDefault(); private: + // installs a different garbage collector(hacky and does not seem to work any more) + void SetCollector( Collector * collector ); + IoState * self_; // the state bool owned_; // flag telling us whether the state is owned by this object Collector * originalCollector_; // the garbage collector that came with the state Modified: private/z-man/clio/stateregistrator.cpp =================================================================== --- private/z-man/clio/stateregistrator.cpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/stateregistrator.cpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -57,7 +57,19 @@ RegisterAll( state, info ); } +// marks all objects owned by the given state if they are shared by another state +void IStateRegistrator::MarkAll( IoState * state ) CLIO_NOTHROW +{ + IStateRegistrator * run = Anchor()->Next(); + while ( run ) + { + run->Mark( state ); + run = run->Next(); + } +} + void IStateRegistrator::DoPreRegister( IoState * state ) CLIO_NOTHROW{} void IStateRegistrator::DoPostRegister( IoState * state ) CLIO_NOTHROW{} +void IStateRegistrator::OnMark( IoState * state ) CLIO_NOTHROW{} } Modified: private/z-man/clio/stateregistrator.hpp =================================================================== --- private/z-man/clio/stateregistrator.hpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/stateregistrator.hpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -26,6 +26,9 @@ static void RegisterAll( IoState * state, ExtraInfo const & info ) CLIO_NOTHROW; static void RegisterAll( IoState * state ) CLIO_NOTHROW; + // marks all objects owned by the given state if they are shared by another state + static void MarkAll( IoState * state ) CLIO_NOTHROW; + // register with a state, decoupling wrapper inline void Register( IoState * state, ExtraInfo const & info ) { @@ -43,6 +46,15 @@ { DoPostRegister( state ); } + + // lacced when the lobby of a state is GC-marked + inline void Mark( IoState * state ) + { + OnMark( state ); + } + +protected: + virtual void OnMark( IoState * state ) CLIO_NOTHROW; private: // register with a state, implementation virtual void DoRegister( IoState * state, ExtraInfo const & info ) CLIO_NOTHROW = 0; Modified: private/z-man/clio/tests/smartpointer.test/test.cpp =================================================================== --- private/z-man/clio/tests/smartpointer.test/test.cpp 2008-02-19 09:11:29 UTC (rev 7998) +++ private/z-man/clio/tests/smartpointer.test/test.cpp 2008-02-19 10:12:53 UTC (rev 7999) @@ -61,7 +61,7 @@ clio::IStateRegistrator::RegisterAll( state ); clio::IStateRegistrator::RegisterAll( state2 ); - state2.SetCollector( state.Self()->collector ); + // state2.SetCollector( state.Self()->collector ); TestString( state, "callGC := method( Range setRange(0,10000,1) foreach(n,n) )" ); TestString( state2, "callGC := method( Range setRange(0,10000,1) foreach(n,n) )" ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-19 12:10:02
|
Revision: 8001 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8001&view=rev Author: z-man Date: 2008-02-19 04:10:08 -0800 (Tue, 19 Feb 2008) Log Message: ----------- Better efficiency for C++ objects shared between states. Modified Paths: -------------- private/z-man/clio/iclassinfo.cpp private/z-man/clio/iclassinfo.hpp private/z-man/clio/objectwrapper.cpp Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-19 11:19:07 UTC (rev 8000) +++ private/z-man/clio/iclassinfo.cpp 2008-02-19 12:10:08 UTC (rev 8001) @@ -694,26 +694,6 @@ } } -// marks objects shared by other states -void IClassInfo::OnMark( IoState * state ) CLIO_NOTHROW -{ - // iterate over all wrappers - for ( WrapperMap::iterator i = wrapperMap_.begin(); i != wrapperMap_.end(); ++i ) - { - ObjectWrapper * wrapper = (*i).second; - - if ( wrapper ) - { - IoObject * self = wrapper->GetSelf(); - // is the object owned by the given state, and is it shared? - if ( self && IOSTATE == state && wrapper->Next() != wrapper ) - { - IoObject_shouldMark( self ); - } - } - } -} - // clones an Io object derived from T, but instead of cloning the C++ core, the // provided alternative core object is used IoObject * IClassInfo::CloneOverride( IoObject * original, void * override ) CLIO_NOTHROW Modified: private/z-man/clio/iclassinfo.hpp =================================================================== --- private/z-man/clio/iclassinfo.hpp 2008-02-19 11:19:07 UTC (rev 8000) +++ private/z-man/clio/iclassinfo.hpp 2008-02-19 12:10:08 UTC (rev 8001) @@ -196,9 +196,6 @@ virtual void DoPreRegister( IoState * state ) CLIO_NOTHROW; virtual void DoPostRegister( IoState * state ) CLIO_NOTHROW; - // marks all shared objects - virtual void OnMark( IoState * state ) CLIO_NOTHROW; - // returns the size of the wrapped object virtual size_t DoGetSize() const CLIO_NOTHROW = 0; Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-19 11:19:07 UTC (rev 8000) +++ private/z-man/clio/objectwrapper.cpp 2008-02-19 12:10:08 UTC (rev 8001) @@ -17,6 +17,48 @@ class IClassInfo; class IClassStateInfo; +// data structures to keep track of main wrappers of objects shared between states +typedef std::set< ObjectWrapper * > WrapperSet; +typedef std::map< IoState *, WrapperSet > WrappersOnState; +static WrappersOnState & GetSharedWrappersOnState(); + +// GC helper class: marks all shared objects of a given state +class SharedObjectMarker: public IStateRegistrator +{ +public: +protected: + virtual void OnMark( IoState * state ) CLIO_NOTHROW + { + // iterate over all primary wrappers belonging to the given state + WrappersOnState & allWrappers = GetSharedWrappersOnState(); + WrapperSet & wrappers = allWrappers[ state ]; + for ( WrapperSet::iterator i = wrappers.begin(); i != wrappers.end(); ++i ) + { + ObjectWrapper * wrapper = (*i); + + assert( wrapper ); + IoObject * self = wrapper->GetSelf(); + assert( self ); + assert( IOSTATE == state ); + + // and mark them + IoObject_shouldMark( self ); + } + } +private: + virtual void DoRegister( IoState * state, ExtraInfo const & info ) CLIO_NOTHROW{}; +}; + +static WrappersOnState & GetSharedWrappersOnState() +{ + // instatiate the shared object marker only if we actually have shared objects + static SharedObjectMarker marker; + + // return the wrapper + static WrappersOnState wrappers; + return wrappers; +} + // constructor ObjectWrapper::ObjectWrapper( IClassInfo const & classInfo, IoObject * self ) : object_( 0 ) @@ -44,7 +86,7 @@ { GetClassInfo().UnregisterWrapper( object_, this ); - if ( GetOwnership() == OwnedByIo ) + if ( GetOwnership() == OwnedByIo && Next() == this ) { markers_.CollectAll(); GetClassInfo().GetFactory().Destroy( object_ ); @@ -58,7 +100,30 @@ object_ = 0; } + // check that we're not registered as a shared wrapper + assert( GetSharedWrappersOnState()[IoObject_state( GetSelf() )].find( this ) == GetSharedWrappersOnState()[IoObject_state( GetSelf() )].end() ); + self_ = 0; + + // store potential other object wrappers pointing to this object + ObjectWrapper * other = Next(); + Remove(); + + // is the other wrapper the last one referencing the object? + if ( other != this && other->Next() == other ) + { + // it is. It was shared until now, but is not any longer. Remove it from + // the list of shared wrappers. + IoState * otherState = IoObject_state( other->GetSelf() ); + WrapperSet & wrappers = GetSharedWrappersOnState()[otherState]; + wrappers.erase( other ); + + // and clear the list itself if the wrapper was the last one. + if ( wrappers.size() == 0 ) + { + GetSharedWrappersOnState().erase( otherState ); + } + } } void ObjectWrapper::ObjectDestroyed() CLIO_NOTHROW @@ -127,6 +192,9 @@ { // no? Add ourselves to the ring Insert( mainWrapper ); + + // and also mark this object as being shared between states + GetSharedWrappersOnState()[IoObject_state( mainWrapper->GetSelf() )].insert( mainWrapper ); } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-19 12:47:13
|
Revision: 8002 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8002&view=rev Author: z-man Date: 2008-02-19 04:47:18 -0800 (Tue, 19 Feb 2008) Log Message: ----------- Better protection against client coding errors. Modified Paths: -------------- private/z-man/clio/classinfo.hpp private/z-man/clio/factory.hpp private/z-man/clio/function_single.hpp private/z-man/clio/objectwrapperaware.cpp private/z-man/clio/objectwrapperaware.hpp Modified: private/z-man/clio/classinfo.hpp =================================================================== --- private/z-man/clio/classinfo.hpp 2008-02-19 12:10:08 UTC (rev 8001) +++ private/z-man/clio/classinfo.hpp 2008-02-19 12:47:18 UTC (rev 8002) @@ -21,7 +21,7 @@ { template< class T > -class ClassInfo: public IClassInfo +class ClassInfo: public IClassInfo, public AwareMaker { public: // this is a singleton class @@ -140,7 +140,7 @@ assert( object ); assert( wrapper ); T * realObject = static_cast< T * >( object ); - clio::MakeObjectWrapperAware( wrapper, realObject ); + MakeObjectWrapperAware( wrapper, realObject ); } }; Modified: private/z-man/clio/factory.hpp =================================================================== --- private/z-man/clio/factory.hpp 2008-02-19 12:10:08 UTC (rev 8001) +++ private/z-man/clio/factory.hpp 2008-02-19 12:47:18 UTC (rev 8002) @@ -5,6 +5,7 @@ #include "totype.hpp" #include "typetraits.hpp" #include "clio_config.hpp" +#include "objectwrapperaware.hpp" namespace clio { @@ -177,7 +178,7 @@ // overriding factory as single factories template<class T, class DERIVED=T> -class OverridingFactoryCreate +class OverridingFactoryCreate: public AwareMaker { public: // create an object @@ -196,7 +197,7 @@ }; template<class T, class DERIVED=T> -class OverridingFactoryClone +class OverridingFactoryClone: public AwareMaker { public: // copy an object Modified: private/z-man/clio/function_single.hpp =================================================================== --- private/z-man/clio/function_single.hpp 2008-02-19 12:10:08 UTC (rev 8001) +++ private/z-man/clio/function_single.hpp 2008-02-19 12:47:18 UTC (rev 8002) @@ -45,7 +45,7 @@ // Constructor wrappers. Constructors are thought of as static member functions without return type // (they aren't, but we don't mind.) template< class TWrap, class TBase CLIO_TYPELIST_ARG > -class ConstructorWrapper< TWrap, TBase, CLIO_TYPELIST_FIXED >: public TWrap +class ConstructorWrapper< TWrap, TBase, CLIO_TYPELIST_FIXED >: public TWrap, public AwareMaker { public: ConstructorWrapper( CLIO_TYPELIST_FUNCARG ) Modified: private/z-man/clio/objectwrapperaware.cpp =================================================================== --- private/z-man/clio/objectwrapperaware.cpp 2008-02-19 12:10:08 UTC (rev 8001) +++ private/z-man/clio/objectwrapperaware.cpp 2008-02-19 12:47:18 UTC (rev 8002) @@ -38,7 +38,7 @@ } // informs an object about the wrapper it was assigned to. -void MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW +void AwareMaker::MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW { assert(object); object->SetObjectWrapper( wrapper ); Modified: private/z-man/clio/objectwrapperaware.hpp =================================================================== --- private/z-man/clio/objectwrapperaware.hpp 2008-02-19 12:10:08 UTC (rev 8001) +++ private/z-man/clio/objectwrapperaware.hpp 2008-02-19 12:47:18 UTC (rev 8002) @@ -11,26 +11,34 @@ // attached to class ObjectWrapperAware { + friend class AwareMaker; public: ObjectWrapperAware(); virtual ~ObjectWrapperAware()=0; - // accessors for the wrapper - void SetObjectWrapper( ObjectWrapper * wrapper ) CLIO_NOTHROW; + // returns the current object wrapper ObjectWrapper * GetObjectWrapper() const CLIO_NOTHROW; protected: virtual void OnSetObjectWrapper(); // hook called after the object wrapper was set private: + // accessors for the wrapper + void SetObjectWrapper( ObjectWrapper * wrapper ) CLIO_NOTHROW; ObjectWrapper * wrapper_; }; -// informs an object about the wrapper it was assigned to. -void MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW; +// Don't derive from this class in client code, the functions +// are only intendet to be called from within clio. +class AwareMaker +{ +protected: + // informs an object about the wrapper it was assigned to. + static void MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW; -// this second overload makes it possible to call the function from a template without knowing -// whether it makes sense or not. If it doesn't make sense, this stub is called instead. -inline void MakeObjectWrapperAware( ObjectWrapper *, void * ){} + // this second overload makes it possible to call the function from a template without knowing + // whether it makes sense or not. If it doesn't make sense, this stub is called instead. + inline static void MakeObjectWrapperAware( ObjectWrapper *, void * ){} +}; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-19 17:21:17
|
Revision: 8009 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8009&view=rev Author: z-man Date: 2008-02-19 09:21:21 -0800 (Tue, 19 Feb 2008) Log Message: ----------- Added IChained, a base class for wrappers that share the lifetime with a real object. Example use: accessor proxies for member variables. Modified Paths: -------------- private/z-man/clio/Makefile private/z-man/clio/macros.hpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapper.hpp private/z-man/clio/tests/container.test/test.cpp Added Paths: ----------- private/z-man/clio/ichained.cpp private/z-man/clio/ichained.hpp Modified: private/z-man/clio/Makefile =================================================================== --- private/z-man/clio/Makefile 2008-02-19 15:32:57 UTC (rev 8008) +++ private/z-man/clio/Makefile 2008-02-19 17:21:21 UTC (rev 8009) @@ -1,5 +1,5 @@ -IOINCLUDE=/usr/local/include/io -#IOINCLUDE=/home/moos/usr/include/io +#IOINCLUDE=/usr/local/include/io +IOINCLUDE=/home/moos/usr/include/io #CXX = g++-4.1.1 #CXX = gcc-40-g++ CXX = g++ Added: private/z-man/clio/ichained.cpp =================================================================== --- private/z-man/clio/ichained.cpp (rev 0) +++ private/z-man/clio/ichained.cpp 2008-02-19 17:21:21 UTC (rev 8009) @@ -0,0 +1,73 @@ +#include "ichained.hpp" + +#include "objectwrapper.hpp" +#include "iclassinfo.hpp" + +#include <IoState.h> +#include <IoObject.h> + +namespace clio +{ + +IChained::IChained() +{ + chainedTo_ = 0; +} + +IChained::~IChained() +{ + if ( chainedTo_ ) + { + chainedTo_->UnRegisterChained( this ); + } +} + +// called when the owning object is marked not to be collected +void IChained::OnMark( IoObject * self ) const +{ + if ( chainedTo_ && chainedTo_->GetSelf() ) + { + // make sure chainedTo_ and self are of the same garbage collector + if ( IoObject_state( chainedTo_->GetSelf() )->collector != IoObject_state( self )->collector ) + { + // they're not! get a new chained_ from the right state. + ObjectWrapper * newChained = chainedTo_->GetClassInfo().GetObjectWrapperThis( chainedTo_->GetObject() ); + chainedTo_->UnRegisterChained( const_cast< IChained * >( this ) ); + newChained->RegisterChained( const_cast< IChained * >( this ) ); + + assert( IoObject_state( chainedTo_->GetSelf() )->collector == IoObject_state( self )->collector ); + } + + IoObject_shouldMark( chainedTo_->GetSelf() ); + } +} + +// called when the object this thing is chained to gets destroyed +void IChained::OnBreak() CLIO_NOTHROW +{ + chainedTo_ = 0; +} + +// hook called after the object wrapper was set +void IChained::OnSetObjectWrapper() +{ + // register as a GC marker + ObjectWrapper * wrapper = GetObjectWrapper(); + if ( wrapper ) + { + wrapper->RegisterGCMarker( *this ); + + // IChained Objects are always owned by IO + wrapper->SetOwnership( ObjectWrapper::OwnedByIo ); + } +} + +// links this chained object to a wrapper +void IChained::SetChainedWrapper( ObjectWrapper * chainedTo ) +{ + chainedTo_ = chainedTo; +} + +} + + Added: private/z-man/clio/ichained.hpp =================================================================== --- private/z-man/clio/ichained.hpp (rev 0) +++ private/z-man/clio/ichained.hpp 2008-02-19 17:21:21 UTC (rev 8009) @@ -0,0 +1,45 @@ +#ifndef CLIO_ICHAINED_H +#define CLIO_ICHAINED_H + +#include "clio_config.hpp" + +#include "gcmarker.hpp" +#include "objectwrapperaware.hpp" + +namespace clio +{ + +class ObjectWrapper; + +// chained objects. They share the lifetime with another object they are +// chained to, and GC marks on this object also mark the chained object. +// Objects of this class and its subclasses are ALWAYS owned by Io. +class IChained: public ObjectWrapperAware, public GCAutoMarker +{ + friend class ObjectWrapper; +public: + IChained(); + virtual ~IChained(); + + // called when the object this thing is chained to gets destroyed + inline void Break() CLIO_NOTHROW + { + OnBreak(); + } +protected: + // called when the owning object is marked not to be collected + virtual void OnMark( IoObject * self ) const; + + // called when the object this thing is chained to gets destroyed + virtual void OnBreak() CLIO_NOTHROW; + + virtual void OnSetObjectWrapper(); // hook called after the object wrapper was set +private: + // links this chained object to a wrapper + void SetChainedWrapper( ObjectWrapper * chainedTo ); + + ObjectWrapper * chainedTo_; +}; + +} +#endif Modified: private/z-man/clio/macros.hpp =================================================================== --- private/z-man/clio/macros.hpp 2008-02-19 15:32:57 UTC (rev 8008) +++ private/z-man/clio/macros.hpp 2008-02-19 17:21:21 UTC (rev 8009) @@ -201,7 +201,7 @@ }; // with that class as template parameter T, this template is instantiated and -// odes the rest of the work. +// does the rest of the work. template< class T > class clioPrivate_ClioWrap: public T { public: Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-19 15:32:57 UTC (rev 8008) +++ private/z-man/clio/objectwrapper.cpp 2008-02-19 17:21:21 UTC (rev 8009) @@ -3,6 +3,7 @@ #include "iclassinfo.hpp" #include "error.hpp" #include "factory.hpp" +#include "ichained.hpp" #include <IoObject.h> #include <IoMessage.h> @@ -17,6 +18,14 @@ class IClassInfo; class IClassStateInfo; +// data structures to find which wrapped object a given memory position belongs to +typedef std::map< void const *, ObjectWrapper * > WrapperMap; // map from C++ objects their main ObjectWrapper +static WrapperMap & GetWrapperMap() +{ + static WrapperMap map; + return map; +} + // data structures to keep track of main wrappers of objects shared between states typedef std::set< ObjectWrapper * > WrapperSet; typedef std::map< IoState *, WrapperSet > WrappersOnState; @@ -84,17 +93,27 @@ if ( object_ ) { + GetWrapperMap().erase( object_ ); GetClassInfo().UnregisterWrapper( object_, this ); - if ( GetOwnership() == OwnedByIo && Next() == this ) + if ( Next() == this ) { - markers_.CollectAll(); - GetClassInfo().GetFactory().Destroy( object_ ); + if ( GetOwnership() == OwnedByIo ) + { + markers_.CollectAll(); + GetClassInfo().GetFactory().Destroy( object_ ); - // inform other wrappers of the object's death - ObjectDestroyed(); + // inform other wrappers of the object's death + ObjectDestroyed(); - assert( !object_ ); + assert( !object_ ); + } + + // inform chained objects + for( ChainedSet::iterator iter = chained_.begin(); iter != chained_.end(); ++iter ) + { + (*iter)->Break(); + } } object_ = 0; @@ -152,6 +171,58 @@ throw Exception("Action not supported on prototypes"); } +// registers a chained object. Chained objects share the lifetime of the wrapper +// they are chained to, and if they're unchained, they are volatile and are +// assumed to go out of scope on the next call to C++. +void ObjectWrapper::RegisterChained( IChained * chained ) +{ + chained_.insert( chained ); + chained->SetChainedWrapper( this ); +} + +void ObjectWrapper::UnRegisterChained( IChained * chained ) +{ + chained_.erase( chained ); + chained->SetChainedWrapper( NULL ); +} + +// find the right object wrapper and chain to it, or do nothing. +void ObjectWrapper::RegisterChained( IChained * chained, void const * location ) +{ + WrapperMap::iterator icandidate = GetWrapperMap().lower_bound( location ); + if ( icandidate == GetWrapperMap().end() ) + { + // totaly out of bounds, do dothing + return; + } + + ObjectWrapper * candidate = (*icandidate).second; + if ( !candidate ) + { + // invalid iterator. Not sure how this can happen, but definitely: do nothing. + return; + } + + if ( (char *)location - (char *)candidate->GetObject() >= (int)candidate->GetClassInfo().GetSize() ) + { + // location out of bounds. Do nothing., + return; + } + + // ah, location lies inside the memory block managed by the wrapper candidate. + candidate->RegisterChained( chained ); +} + +void ObjectWrapper::RegisterGCMarker( GCAutoMarker & marker ) +{ + markers_.Add( marker ); +} + +void ObjectWrapper::UnRegisterGCMarker( GCAutoMarker & marker ) +{ + markers_.Remove( marker ); +} + ObjectWrapper * ObjectWrapper::GetObjectWrapper( IoObject * self ) CLIO_NOTHROW { if ( !IClassInfo::IsClioObject( self ) ) @@ -200,6 +271,7 @@ { // yes? Then we're the main wrapper now. GetClassInfo().RegisterWrapper( object_, this ); + GetWrapperMap()[ object_ ] = this; // take over automatic GC markers markers_.TakeOver( GCAutoMarkerBigSet::Get(), object_, GetClassInfo().GetSize() ); Modified: private/z-man/clio/objectwrapper.hpp =================================================================== --- private/z-man/clio/objectwrapper.hpp 2008-02-19 15:32:57 UTC (rev 8008) +++ private/z-man/clio/objectwrapper.hpp 2008-02-19 17:21:21 UTC (rev 8009) @@ -16,6 +16,7 @@ class IClassInfo; class IClassStateInfo; class IFactory; +class IChained; // Every C++ class object known to Io will be wrapped in one of those. // The wrapper keeps contact with the IoObject and handles the direct @@ -36,6 +37,9 @@ Shared4 // .... }; + // set of chained objects + typedef std::set< IChained * > ChainedSet; + ObjectWrapper( IClassInfo const & classInfo, IoObject * self ); // constructor virtual ~ObjectWrapper(); // destructor @@ -48,9 +52,24 @@ // error helper function static void NoObjectError(); + // registers a chained object. Chained objects share the lifetime of the wrapper + // they are chained to, and if they're unchained, they are volatile and are + // assumed to go out of scope on the next call to C++. + void RegisterChained( IChained * chained ); + void UnRegisterChained( IChained * chained ); + + // find the right object wrapper and chain to it, or do nothing. + static void RegisterChained( IChained * chained, void const * location ); + // clones this object // ObjectWrapper * Clone( IoObject * self ) const; + // registers a GC marker; it will be invoked whenever this wrapper is marked. + void RegisterGCMarker( GCAutoMarker & marker ); + + // unregisters a GC marker + void UnRegisterGCMarker( GCAutoMarker & marker ); + // returns the object wrapped by this inline void * GetObject() const { @@ -95,6 +114,8 @@ IoObject * self_; // the prototype object for this interface Ownership ownership_; // who owns the object GCAutoMarkerSmallSet markers_; // the GC markers that are part of the wrapped object + + ChainedSet chained_; // set of chained objects }; class ObjectWrapperPrototype: public ObjectWrapper Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-19 15:32:57 UTC (rev 8008) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-19 17:21:21 UTC (rev 8009) @@ -34,15 +34,30 @@ Container & container_; }; +class A +{}; + +class B +{ +public: + B( A & ){} +}; + class TestVector { public: - std::vector< int > & GetInts2() + A const & GetA() { + static A a; + return a; + }; + + std::vector< int > & GetInts() + { return ints_; } - ContainerWrapper< std::vector< int > > GetInts() + ContainerWrapper< std::vector< int > > GetInts2() { return ContainerWrapper< std::vector< int > >( ints_ ); } @@ -50,22 +65,35 @@ std::vector< int > ints_; }; -/* namespace clio { namespace dataconversion { -template< class T > struct DataConverterManager< std::vector<T> & >: public DataConverterManager< ContainerWrapper< std::vector<T> > & > + +template<> struct DataConverterManager< A >: public DataConverterManager< B > { +}; + +template<> struct DataConverterManager< A & >: public DataConverterValue< B > +{ +}; + +template<> struct DataConverterManager< A const & >: public DataConverterManager< B > +{ +}; + +template< class T > struct DataConverterManager< std::vector<T> & >: public DataConverterManager< ContainerWrapper< std::vector<T> > > +{ typedef DataConverterManager< ContainerWrapper< std::vector<T> > & > BASE; +/* static IoObject * ToIo( IoState * state, std::vector<T> & vec, const clio::DataConversionCall & call ) { - return BASE::ToIo( state, ContainerWrapper< std::vector<T> >( vec ), call ); + return BASE::ToIo( state, ContainerWrapper< std::vector<T> >( vec ), call );} +*/ }; } } -*/ CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( ContainerWrapper, (1,(class)), false ); @@ -93,7 +121,8 @@ CLIO_CLASS( TestVector ) { - CLIO_METHOD( GetInts ); + CLIO_METHOD( GetA ); + // CLIO_METHOD( GetInts ); } void Test() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-19 18:53:06
|
Revision: 8010 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8010&view=rev Author: z-man Date: 2008-02-19 10:47:35 -0800 (Tue, 19 Feb 2008) Log Message: ----------- Got basic std::vector wrapper working. You can't do much with it yet, of course. Modified Paths: -------------- private/z-man/clio/Makefile private/z-man/clio/ichained.cpp private/z-man/clio/tests/container.test/test.cpp Modified: private/z-man/clio/Makefile =================================================================== --- private/z-man/clio/Makefile 2008-02-19 17:21:21 UTC (rev 8009) +++ private/z-man/clio/Makefile 2008-02-19 18:47:35 UTC (rev 8010) @@ -1,5 +1,5 @@ -#IOINCLUDE=/usr/local/include/io -IOINCLUDE=/home/moos/usr/include/io +IOINCLUDE=/usr/local/include/io +#IOINCLUDE=/home/moos/usr/include/io #CXX = g++-4.1.1 #CXX = gcc-40-g++ CXX = g++ Modified: private/z-man/clio/ichained.cpp =================================================================== --- private/z-man/clio/ichained.cpp 2008-02-19 17:21:21 UTC (rev 8009) +++ private/z-man/clio/ichained.cpp 2008-02-19 18:47:35 UTC (rev 8010) @@ -55,7 +55,8 @@ ObjectWrapper * wrapper = GetObjectWrapper(); if ( wrapper ) { - wrapper->RegisterGCMarker( *this ); + // not required; the automatic GC marker finder will take care of that later. + // wrapper->RegisterGCMarker( *this ); // IChained Objects are always owned by IO wrapper->SetOwnership( ObjectWrapper::OwnedByIo ); Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-19 17:21:21 UTC (rev 8009) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-19 18:47:35 UTC (rev 8010) @@ -1,128 +1,209 @@ #include "helptest.hpp" #include "typetraits.hpp" +#include "ichained.hpp" // **************************** // std:: containers // **************************** -template< class Container > class ContainerWrapper +class A +{}; + +class TestVector { public: + A & GetA() + { + static A a; + return a; + }; + + std::vector< int > & GetInts() + { + return ints_; + } +private: + std::vector< int > ints_; +}; + +namespace clio +{ + +// proxy objects. ORIGINAL should be the raw type of the wrapped object. +template< class ORIGINAL > +class Proxy: public IChained +{ +public: + // returns the original object + ORIGINAL & Get() const + { + if ( !original_ ) + { + std::ostringstream err; + err << "Proxy for " << GetTypeName< ORIGINAL >() << + " is broken, the wrapped object may have gone out of scope."; + throw Exception( "Broken Proxy", err.str() ); + } + + return *original_; + } + + // creates proxy for original + explicit Proxy( ORIGINAL * original ) + : original_( original ) + { + // register with object wrappers + assert( original ); + ObjectWrapper::RegisterChained( this, original ); + } + + // creates proxy for original + explicit Proxy( ORIGINAL & original ) + : original_( &original ) + { + // register with object wrappers + ObjectWrapper::RegisterChained( this, &original ); + } +protected: + // called when the object this thing is chained to gets destroyed + virtual void OnBreak() CLIO_NOTHROW + { + // remove reference to original + original_ = 0; + } +private: +private: + // poiter to the original wrapped object + ORIGINAL * original_; +}; + +template< class Container > class VectorProxy: public Proxy< Container > +{ +public: typedef typename Container::value_type value_type; typedef typename Container::reference reference; typedef typename Container::const_reference const_reference; - explicit ContainerWrapper( Container & container ) - : container_( container ) + explicit VectorProxy( Container & container ) + : Proxy< Container >( container ) {} + explicit VectorProxy( Container * container ) + : Proxy< Container >( container ) + {} + const_reference at( int index ) const { - return container_[index]; + return this->Get()[index]; } void append( const_reference value ) { - container_.push_back(value); + this->Get().push_back(value); } unsigned int size() const { - return container_.size(); + return this->Get().size(); } -private: - Container & container_; }; +} -class A -{}; +CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::VectorProxy, (1,(class)), false ); -class B +CLIO_TEMPLATE_CLASS( clio::VectorProxy, (1,(class))) { -public: - B( A & ){} -}; + typedef T1 CONTAINER; + CLIO_METHOD(append); + CLIO_METHOD(size); + CLIO_METHOD( at ); +} -class TestVector +namespace clio { + +namespace dataconversion +{ + +// Data conversion via proxy classes. The proxy class is supposed to have this +// public interface: +// class PROXY{ +// PROXY( ORIGINAL ); +// ORIGINAL Get(); +// }; +// and is supposed to be derived from IChained. + +template< class ORIGINAL, class PROXY > class DataConverterProxy: public DataConverterDefs< ORIGINAL > +{ public: - A const & GetA() - { - static A a; - return a; - }; + typedef DataConverterDefs< ORIGINAL > Base; - std::vector< int > & GetInts() + typedef typename Base::TArg TArg; + typedef typename Base::Converted Converted; + + typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< PROXY > > IMPL; + + static Converted FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) { - return ints_; + PROXY & proxy = IMPL::FromIo( from, call, thrower ); + return proxy.Get(); } - ContainerWrapper< std::vector< int > > GetInts2() + static void CheckType( IChained const & ){} + + static inline IoObject * ToIo( IoState * state, TArg from, DataConversionCall const & call ) { - return ContainerWrapper< std::vector< int > >( ints_ ); + // create + typename IMPL::TArg arg = *(new PROXY(from)); + + // READ BELOW IF THIS LINE GIVES AN ERROR + DataConverterProxy::CheckType( arg ); + // If the above line gives an error, that means you tried to register + // a proxy object for data conversion that is not derived from clio::IChained. + // Let all your proxies inherit from clio::IChained to correct this error. It's + // best if you let them inherit from clio::Proxy< ORIGINAL >. + + return IMPL::ToIo( state, arg, call ); } -private: - std::vector< int > ints_; }; -namespace clio +class B: public clio::IChained { -namespace dataconversion -{ +public: + B( A & ){} +}; template<> struct DataConverterManager< A >: public DataConverterManager< B > { }; -template<> struct DataConverterManager< A & >: public DataConverterValue< B > +template<> struct DataConverterManager< A const & >: public DataConverterManager< B > { }; -template<> struct DataConverterManager< A const & >: public DataConverterManager< B > +template<> struct DataConverterManager< A & >: public DataConverterProxy< A &, Proxy<A> > { }; -template< class T > struct DataConverterManager< std::vector<T> & >: public DataConverterManager< ContainerWrapper< std::vector<T> > > +template< class T > +struct DataConverterManager< std::vector<T> & > + : public DataConverterProxy< std::vector<T> &, + VectorProxy< std::vector<T> > > { - typedef DataConverterManager< ContainerWrapper< std::vector<T> > & > BASE; +}; -/* - static IoObject * ToIo( IoState * state, std::vector<T> & vec, const clio::DataConversionCall & call ) - { - return BASE::ToIo( state, ContainerWrapper< std::vector<T> >( vec ), call );} -*/ -}; } + } -CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( ContainerWrapper, (1,(class)), false ); - CLIO_TEMPLATE_CLASS( std::vector, (1,(class))) { } -CLIO_TEMPLATE_CLASS( ContainerWrapper, (1,(class))) -{ - typedef T1 CONTAINER; - CLIO_METHOD(append); - // CLIO_METHOD(pop_back); - CLIO_METHOD(size); - // typedef T1 VECTOR::ACCESSOR(int); - // CLIO_METHOD(operator[]); - // CLIO_METHOD_EX(operator[],(VECTOR::const_reference (VECTOR::*)(VECTOR::size_type) const),"squareBrackets"); - //CLIO_METHOD((void (VECTOR::*)(T1 const &)) &VECTOR::push_back); -//CLIO_METHOD((const T1 & (VECTOR::*)() const)&front); - //CLIO_METHOD(back); - // CLIO_METHOD(((GETTER)&front)); - // CLIO_METHOD_EX( front, GETTER, "front" ); - // CLIO_METHOD_EX( front, (T1 const & (VECTOR::*)() const), "front" ); - CLIO_METHOD( at ); -} - CLIO_CLASS( TestVector ) { CLIO_METHOD( GetA ); - // CLIO_METHOD( GetInts ); + CLIO_METHOD( GetInts ); } void Test() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-20 12:34:59
|
Revision: 8013 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8013&view=rev Author: z-man Date: 2008-02-20 04:34:59 -0800 (Wed, 20 Feb 2008) Log Message: ----------- First crash test now passes. Second test, reference to inner integers, fails. Modified Paths: -------------- private/z-man/clio/classinfo.hpp private/z-man/clio/ichained.cpp private/z-man/clio/ichained.hpp private/z-man/clio/iclassinfo.cpp private/z-man/clio/iclassinfo.hpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapper.hpp private/z-man/clio/objectwrapperaware.cpp private/z-man/clio/objectwrapperaware.hpp private/z-man/clio/tests/container.test/test.cpp private/z-man/clio/tests/crash.test/test.io Modified: private/z-man/clio/classinfo.hpp =================================================================== --- private/z-man/clio/classinfo.hpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/classinfo.hpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -112,6 +112,12 @@ return sizeof(T); } + // inform class than an object of it went out of scope + virtual void OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW + { + BreakObjectWrapperAware( ExtractObject( wrapper ) ); + } + ClassInfo() { SetNameGetter( Name_C , classname::ClassNameDefaultGetter< T, Name_C >::Get ); Modified: private/z-man/clio/ichained.cpp =================================================================== --- private/z-man/clio/ichained.cpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/ichained.cpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -11,41 +11,22 @@ IChained::IChained() { - chainedTo_ = 0; } IChained::~IChained() { - if ( chainedTo_ ) - { - chainedTo_->UnRegisterChained( this ); - } } -// called when the owning object is marked not to be collected -void IChained::OnMark( IoObject * self ) const +// register to the system that this chained object really manages +// something at location 'memory'. +void IChained::Register( void * memory ) const { - if ( chainedTo_ && chainedTo_->GetSelf() ) - { - // make sure chainedTo_ and self are of the same garbage collector - if ( IoObject_state( chainedTo_->GetSelf() )->collector != IoObject_state( self )->collector ) - { - // they're not! get a new chained_ from the right state. - ObjectWrapper * newChained = chainedTo_->GetClassInfo().GetObjectWrapperThis( chainedTo_->GetObject() ); - chainedTo_->UnRegisterChained( const_cast< IChained * >( this ) ); - newChained->RegisterChained( const_cast< IChained * >( this ) ); - - assert( IoObject_state( chainedTo_->GetSelf() )->collector == IoObject_state( self )->collector ); - } - - IoObject_shouldMark( chainedTo_->GetSelf() ); - } + ObjectWrapper::RegisterChained( this->GetObjectWrapper(), memory ); } // called when the object this thing is chained to gets destroyed void IChained::OnBreak() CLIO_NOTHROW { - chainedTo_ = 0; } // hook called after the object wrapper was set @@ -63,12 +44,6 @@ } } -// links this chained object to a wrapper -void IChained::SetChainedWrapper( ObjectWrapper * chainedTo ) -{ - chainedTo_ = chainedTo; } -} - Modified: private/z-man/clio/ichained.hpp =================================================================== --- private/z-man/clio/ichained.hpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/ichained.hpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -3,7 +3,6 @@ #include "clio_config.hpp" -#include "gcmarker.hpp" #include "objectwrapperaware.hpp" namespace clio @@ -14,31 +13,22 @@ // chained objects. They share the lifetime with another object they are // chained to, and GC marks on this object also mark the chained object. // Objects of this class and its subclasses are ALWAYS owned by Io. -class IChained: public ObjectWrapperAware, public GCAutoMarker +class IChained: public ObjectWrapperAware { friend class ObjectWrapper; public: IChained(); virtual ~IChained(); - // called when the object this thing is chained to gets destroyed - inline void Break() CLIO_NOTHROW - { - OnBreak(); - } + // register to the system that this chained object really manages + // something at location 'memory'. + void Register( void * memory ) const; protected: - // called when the owning object is marked not to be collected - virtual void OnMark( IoObject * self ) const; - // called when the object this thing is chained to gets destroyed virtual void OnBreak() CLIO_NOTHROW; virtual void OnSetObjectWrapper(); // hook called after the object wrapper was set private: - // links this chained object to a wrapper - void SetChainedWrapper( ObjectWrapper * chainedTo ); - - ObjectWrapper * chainedTo_; }; } Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/iclassinfo.cpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -368,6 +368,20 @@ return FetchIoObject( const_cast< void * >( object ), state, ownership ); } +// returns an object wrapper wrapping an object of this class +ObjectWrapper & IClassInfo::FetchObjectWrapper( void * object, IoState * state, Ownership ownership ) const CLIO_NOTHROW +{ + ObjectWrapper * ret = ObjectWrapper::GetObjectWrapper( + FetchIoObject( object, state, ownership ) ); + assert( ret ); + return *ret; +} + +ObjectWrapper & IClassInfo::FetchObjectWrapper( void const * object, IoState * state, Ownership ownership ) const CLIO_NOTHROW +{ + return FetchObjectWrapper( const_cast< void * >( object ), state, ownership ); +} + // add object to reverse map void IClassInfo::RegisterWrapper( void * object, ObjectWrapper * wrapper ) const CLIO_NOTHROW { @@ -587,13 +601,20 @@ // have them marked, too, if they are managed by the same collector if ( IoObject_state( run->GetSelf() )->collector == IoObject_state( wrapper->GetSelf() )->collector ) + { IoObject_shouldMark( run->GetSelf() ); + // have the chained wrapper marked, too + if ( run->chainedTo_ && run->chainedTo_->owner_ ) + { + IoObject_shouldMark( run->chainedTo_->owner_->GetSelf() ); + } + } run = run->Next(); } while ( wrapper != run ); } - + // have all smart pointer members be marked wrapper->markers_.MarkAll( self ); } Modified: private/z-man/clio/iclassinfo.hpp =================================================================== --- private/z-man/clio/iclassinfo.hpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/iclassinfo.hpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -120,6 +120,12 @@ return DoGetSize(); } + // inform class than an object of it went out of scope + void Break( ObjectWrapper & wrapper ) const + { + OnBreak( wrapper ); + } + // registers a factory, taking ownership of it void RegisterFactory( IFactory * factory ) const CLIO_NOTHROW; @@ -146,6 +152,10 @@ IoObject * FetchIoObject( void * object, IoState * state = 0, Ownership ownership = ObjectWrapper::OwnedByIo ) const CLIO_NOTHROW; IoObject * FetchIoObject( void const * object, IoState * state = 0, Ownership ownership = ObjectWrapper::OwnedByIo ) const CLIO_NOTHROW; + // get an object wrapper for a C++ object of this class, create it if neccessary + ObjectWrapper & FetchObjectWrapper( void * object, IoState * state = 0, Ownership ownership = ObjectWrapper::OwnedByIo ) const CLIO_NOTHROW; + ObjectWrapper & FetchObjectWrapper( void const * object, IoState * state = 0, Ownership ownership = ObjectWrapper::OwnedByIo ) const CLIO_NOTHROW; + // add object to reverse map void RegisterWrapper( void * object, ObjectWrapper * wrapper ) const CLIO_NOTHROW; @@ -199,6 +209,9 @@ // returns the size of the wrapped object virtual size_t DoGetSize() const CLIO_NOTHROW = 0; + // inform class than an object of it went out of scope + virtual void OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; + // returns a static function capable of creating an Io object with an object of this class virtual IoStateProtoFunc * DoGetStateProtoFunc() const CLIO_NOTHROW = 0; Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/objectwrapper.cpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -3,7 +3,7 @@ #include "iclassinfo.hpp" #include "error.hpp" #include "factory.hpp" -#include "ichained.hpp" +// #include "ichained.hpp" #include <IoObject.h> #include <IoMessage.h> @@ -15,6 +15,58 @@ namespace clio { + +ChainedSet::ChainedSet( ObjectWrapper * owner ) +: owner_( owner ) +{ +} + +ChainedSet::~ChainedSet() +{ + // inform chained objects + for( Set::iterator iter = set_.begin(); iter != set_.end(); ++iter ) + { + (*iter)->chainedTo_ = 0; + } +} + +// registers a chained object. Chained objects share the lifetime of the wrapper +// they are chained to, and if they're unchained, they are volatile and are +// assumed to go out of scope on the next call to C++. +void ChainedSet::RegisterChained( ObjectWrapper * chained ) +{ + set_.insert( chained ); + chained->chainedTo_ = this; +} + +void ChainedSet::UnRegisterChained( ObjectWrapper * chained ) +{ + set_.erase( chained ); + chained->chainedTo_ = NULL; +} + +// breaks all chained objects. Call when the mother object goes out of scope. +void ChainedSet::Break() +{ + // inform chained objects + for( Set::iterator iter = set_.begin(); iter != set_.end(); ++iter ) + { + (*iter)->Break(); + } +} + +// returns singleton for unchained objects +static ChainedSet & GetUnchained() +{ + static ChainedSet set; + return set; +} + +void ObjectWrapper::BreakAll() +{ + GetUnchained().Break(); +} + class IClassInfo; class IClassStateInfo; @@ -74,6 +126,8 @@ , classInfo_( classInfo ) , self_( self ) , ownership_( OwnedByIo ) + , chained_( this ) + , chainedTo_( 0 ) { // std::cout << "Wrapper created\n"; @@ -108,12 +162,8 @@ assert( !object_ ); } - - // inform chained objects - for( ChainedSet::iterator iter = chained_.begin(); iter != chained_.end(); ++iter ) - { - (*iter)->Break(); - } + + Break(); } object_ = 0; @@ -143,6 +193,12 @@ GetSharedWrappersOnState().erase( otherState ); } } + + // unchain + if ( chainedTo_ ) + { + chainedTo_->UnRegisterChained( this ); + } } void ObjectWrapper::ObjectDestroyed() CLIO_NOTHROW @@ -171,46 +227,81 @@ throw Exception("Action not supported on prototypes"); } -// registers a chained object. Chained objects share the lifetime of the wrapper -// they are chained to, and if they're unchained, they are volatile and are -// assumed to go out of scope on the next call to C++. -void ObjectWrapper::RegisterChained( IChained * chained ) +void ObjectWrapper::Break() { - chained_.insert( chained ); - chained->SetChainedWrapper( this ); -} + // inform class info + if ( GetObject() ) + { + GetClassInfo().Break( *this ); + } -void ObjectWrapper::UnRegisterChained( IChained * chained ) -{ - chained_.erase( chained ); - chained->SetChainedWrapper( NULL ); + // inform chained objects + chained_.Break(); + + // nullify object + object_ = 0; } // find the right object wrapper and chain to it, or do nothing. -void ObjectWrapper::RegisterChained( IChained * chained, void const * location ) +void ObjectWrapper::RegisterChained( ObjectWrapper * chained, void const * location ) { - WrapperMap::iterator icandidate = GetWrapperMap().lower_bound( location ); - if ( icandidate == GetWrapperMap().end() ) + // is the chained object already chained to something worthwile? + if ( chained->chainedTo_ && chained->chainedTo_->owner_ ) { - // totaly out of bounds, do dothing return; } + // find the iterator that points to just the wrapper that holds an object + // that may contain *location. + WrapperMap::iterator icandidate = GetWrapperMap().upper_bound( location ); + if ( icandidate == GetWrapperMap().begin() ) + { + // totaly out of bounds, default action + GetUnchained().RegisterChained( chained ); + return; + } + else if ( icandidate == GetWrapperMap().end() ) + { + // take the lase element + icandidate = GetWrapperMap().find( (*GetWrapperMap().rbegin()).first ); + } + else + { + -- icandidate; + } + ObjectWrapper * candidate = (*icandidate).second; if ( !candidate ) { // invalid iterator. Not sure how this can happen, but definitely: do nothing. + GetUnchained().RegisterChained( chained ); return; } if ( (char *)location - (char *)candidate->GetObject() >= (int)candidate->GetClassInfo().GetSize() ) { - // location out of bounds. Do nothing., + // location out of bounds. Do nothing. + GetUnchained().RegisterChained( chained ); return; } + // make sure chainedTo_ and self are of the same garbage collector + if ( IoObject_state( chained->GetSelf() )->collector != IoObject_state( candidate->GetSelf() )->collector ) + { + // they're not! get a new candidate from the right state. + candidate = &candidate->GetClassInfo().FetchObjectWrapper( candidate->GetObject(), IoObject_state( chained->GetSelf() ) ); + assert( IoObject_state( chained->GetSelf() )->collector == IoObject_state( candidate->GetSelf() )->collector ); + } + + if ( candidate == chained ) + { + // location out of bounds. Do nothing. + GetUnchained().RegisterChained( chained ); + return; + } + // ah, location lies inside the memory block managed by the wrapper candidate. - candidate->RegisterChained( chained ); + candidate->chained_.RegisterChained( chained ); } void ObjectWrapper::RegisterGCMarker( GCAutoMarker & marker ) @@ -236,6 +327,8 @@ : classInfo_( other.GetClassInfo() ) , self_( self ) , ownership_( OwnedByIo ) +, chained_( this ) +, chainedTo_( 0 ) { // start a linked ring Insert( this ); @@ -269,6 +362,9 @@ } else { + // chain this wrapper to exterior wrappers + RegisterChained( this, object_ ); + // yes? Then we're the main wrapper now. GetClassInfo().RegisterWrapper( object_, this ); GetWrapperMap()[ object_ ] = this; Modified: private/z-man/clio/objectwrapper.hpp =================================================================== --- private/z-man/clio/objectwrapper.hpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/objectwrapper.hpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -16,8 +16,32 @@ class IClassInfo; class IClassStateInfo; class IFactory; -class IChained; +class ObjectWrapper; +// set of chained objects +class ChainedSet +{ + friend class ObjectWrapper; + friend class IClassInfo; +public: + typedef std::set< ObjectWrapper * > Set; + + explicit ChainedSet( ObjectWrapper * owner = NULL ); + ~ChainedSet(); + + // registers a chained object. Chained objects share the lifetime of the wrapper + // they are chained to, and if they're unchained, they are volatile and are + // assumed to go out of scope on the next call to C++. + void RegisterChained( ObjectWrapper * chained ); + void UnRegisterChained( ObjectWrapper * chained ); + + // breaks all chained objects. Call when the mother object goes out of scope. + void Break(); +private: + Set set_; + ObjectWrapper * owner_; +}; + // Every C++ class object known to Io will be wrapped in one of those. // The wrapper keeps contact with the IoObject and handles the direct // communication with Io. @@ -25,6 +49,7 @@ { friend class IClassInfo; friend class ObjectWrapperAware; + friend class ChainedSet; public: enum Ownership @@ -37,9 +62,6 @@ Shared4 // .... }; - // set of chained objects - typedef std::set< IChained * > ChainedSet; - ObjectWrapper( IClassInfo const & classInfo, IoObject * self ); // constructor virtual ~ObjectWrapper(); // destructor @@ -52,15 +74,15 @@ // error helper function static void NoObjectError(); - // registers a chained object. Chained objects share the lifetime of the wrapper - // they are chained to, and if they're unchained, they are volatile and are - // assumed to go out of scope on the next call to C++. - void RegisterChained( IChained * chained ); - void UnRegisterChained( IChained * chained ); - // find the right object wrapper and chain to it, or do nothing. - static void RegisterChained( IChained * chained, void const * location ); + static void RegisterChained( ObjectWrapper * chained, void const * location ); + // call when this object, for one reason or another, goes out of scope + void Break(); + + // call on all calls to C++ that may make objects get deleted + static void BreakAll(); + // clones this object // ObjectWrapper * Clone( IoObject * self ) const; @@ -116,6 +138,7 @@ GCAutoMarkerSmallSet markers_; // the GC markers that are part of the wrapped object ChainedSet chained_; // set of chained objects + ChainedSet * chainedTo_; // wrapper this object is chained to }; class ObjectWrapperPrototype: public ObjectWrapper Modified: private/z-man/clio/objectwrapperaware.cpp =================================================================== --- private/z-man/clio/objectwrapperaware.cpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/objectwrapperaware.cpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -37,6 +37,11 @@ { } +// wrapper hook +void ObjectWrapperAware::OnBreak() +{ +} + // informs an object about the wrapper it was assigned to. void AwareMaker::MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW { @@ -44,4 +49,11 @@ object->SetObjectWrapper( wrapper ); } +// informs an object about the wrapper it was assigned to. +void AwareMaker::BreakObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW +{ + assert(object); + object->OnBreak(); } + +} Modified: private/z-man/clio/objectwrapperaware.hpp =================================================================== --- private/z-man/clio/objectwrapperaware.hpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/objectwrapperaware.hpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -20,6 +20,7 @@ ObjectWrapper * GetObjectWrapper() const CLIO_NOTHROW; protected: virtual void OnSetObjectWrapper(); // hook called after the object wrapper was set + virtual void OnBreak(); // called when a parent object breaks private: // accessors for the wrapper void SetObjectWrapper( ObjectWrapper * wrapper ) CLIO_NOTHROW; @@ -38,6 +39,13 @@ // this second overload makes it possible to call the function from a template without knowing // whether it makes sense or not. If it doesn't make sense, this stub is called instead. inline static void MakeObjectWrapperAware( ObjectWrapper *, void * ){} + + // informs an object about a parent object breaking + static void BreakObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW; + + // this second overload makes it possible to call the function from a template without knowing + // whether it makes sense or not. If it doesn't make sense, this stub is called instead. + inline static void BreakObjectWrapperAware( void * ){} }; } Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-20 12:34:59 UTC (rev 8013) @@ -54,7 +54,7 @@ { // register with object wrappers assert( original ); - ObjectWrapper::RegisterChained( this, original ); + Register( original ); } // creates proxy for original @@ -62,7 +62,7 @@ : original_( &original ) { // register with object wrappers - ObjectWrapper::RegisterChained( this, &original ); + Register( &original ); } protected: // called when the object this thing is chained to gets destroyed Modified: private/z-man/clio/tests/crash.test/test.io =================================================================== --- private/z-man/clio/tests/crash.test/test.io 2008-02-20 10:18:50 UTC (rev 8012) +++ private/z-man/clio/tests/crash.test/test.io 2008-02-20 12:34:59 UTC (rev 8013) @@ -3,19 +3,23 @@ // crash test 1: get an inner object of another object getInner := method( y := Y clone(); return y getInner() ) innerX := getInner() -innerInt := innerX getInt() -innerInt2 := innerX getInt() // wait for the original to expire callGC() - // and try to use the inner object innerX test() +// next attempt, reference to inner integers +getInner2 := method( y := Y clone(); return y getInner() getInt() ) +innerInt := getInner2() + +innerInt set(3) +innerInt println + +callGC() + // try to access an inner integer after the main object expired innerInt println innerInt set(2) - -// this can print anything, but not 2 -innerInt2 println +innerInt println This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-20 15:07:42
|
Revision: 8014 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8014&view=rev Author: z-man Date: 2008-02-20 07:07:44 -0800 (Wed, 20 Feb 2008) Log Message: ----------- Intermediate commit with lots of broken stuff. Need to work on a sane way to check which object contains which other one. Modified Paths: -------------- private/z-man/clio/classinfo.hpp private/z-man/clio/dataconversion_extended.hpp private/z-man/clio/enum.hpp private/z-man/clio/ichained.cpp private/z-man/clio/ichained.hpp private/z-man/clio/iclassinfo.cpp private/z-man/clio/iclassinfo.hpp private/z-man/clio/ifunctioninfo.cpp private/z-man/clio/ifunctioninfo.hpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapper.hpp private/z-man/clio/objectwrapperaware.cpp private/z-man/clio/objectwrapperaware.hpp private/z-man/clio/tests/basic.test/test.cpp private/z-man/clio/tests/container.test/test.cpp private/z-man/clio/tests/crash.test/test.io Modified: private/z-man/clio/classinfo.hpp =================================================================== --- private/z-man/clio/classinfo.hpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/classinfo.hpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -113,9 +113,9 @@ } // inform class than an object of it went out of scope - virtual void OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW + virtual bool OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW { - BreakObjectWrapperAware( ExtractObject( wrapper ) ); + return BreakObjectWrapperAware( ExtractObject( wrapper ) ); } ClassInfo() Modified: private/z-man/clio/dataconversion_extended.hpp =================================================================== --- private/z-man/clio/dataconversion_extended.hpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/dataconversion_extended.hpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -131,6 +131,7 @@ #include "macros.hpp" #include "objectwrapperaware.hpp" #include "codeinjection.hpp" +#include "ichained.hpp" // now comes the really fancy stuff. Here, we can already use clio's full wrapping power to // use C++ wrapper types as the objects converted to Io. @@ -141,7 +142,7 @@ { // For example this little beast: it wraps const references to primitives // (and other objects) so the receiver on the Io side can get them. -template < class PRIMITIVE > class PrimitiveProxyConstBase: public ObjectWrapperAware +template < class PRIMITIVE > class PrimitiveProxyConstBase: public IChained { public: PrimitiveProxyConstBase() @@ -149,11 +150,13 @@ PrimitiveProxyConstBase( PRIMITIVE const * data ) : data_ ( const_cast< PRIMITIVE *>( data ) ) , cache_( *data ) - {} + { + } PrimitiveProxyConstBase( PRIMITIVE data ) : data_ ( &cache_ ) , cache_( data ) - {} + { + } PRIMITIVE const * GetTarget() const { @@ -162,6 +165,10 @@ PrimitiveProxyConstBase & SetTarget( PRIMITIVE const * data ) { + // TODO: need to look at reregistration + assert(0); + Register( data ); + assert( data ); data_ = const_cast< PRIMITIVE *>( data ); return *this; @@ -178,6 +185,19 @@ return *data_; } protected: + virtual void OnBreak() CLIO_NOTHROW + { + Detach(); + } + + virtual void OnSetObjectWrapper() + { + if ( data_ && GetObjectWrapper() ) + { + Register( data_ ); + } + } + PRIMITIVE * data_; PRIMITIVE cache_; }; Modified: private/z-man/clio/enum.hpp =================================================================== --- private/z-man/clio/enum.hpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/enum.hpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -109,7 +109,7 @@ #define CLIO_ENUM( NAME ) CLIO_ENUM_EX( NAME, "" ) // macro to add enum values. -#define CLIO_ENUM_VALUE_EX( VALUE, NAME ) CLIO_METHOD_IMPORT_EX( EnumWrapper< CLASS >::ReturnValue<VALUE>,, NAME ); EnumWrapper< CLASS >::RegisterValue( VALUE, NAME ) +#define CLIO_ENUM_VALUE_EX( VALUE, NAME ) CLIO_METHOD_IMPORT_EX( EnumWrapper< CLASS >::ReturnValue<VALUE>,, NAME ).NonBreaking(); EnumWrapper< CLASS >::RegisterValue( VALUE, NAME ) #define CLIO_ENUM_VALUE( VALUE ) CLIO_ENUM_VALUE_EX( VALUE, clio::GetFunctionName( #VALUE, "" ).c_str() ) #endif Modified: private/z-man/clio/ichained.cpp =================================================================== --- private/z-man/clio/ichained.cpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/ichained.cpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -19,13 +19,13 @@ // register to the system that this chained object really manages // something at location 'memory'. -void IChained::Register( void * memory ) const +void IChained::Register( void const * memory ) const { ObjectWrapper::RegisterChained( this->GetObjectWrapper(), memory ); } // called when the object this thing is chained to gets destroyed -void IChained::OnBreak() CLIO_NOTHROW +void IChained::OnBreak() { } Modified: private/z-man/clio/ichained.hpp =================================================================== --- private/z-man/clio/ichained.hpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/ichained.hpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -22,10 +22,10 @@ // register to the system that this chained object really manages // something at location 'memory'. - void Register( void * memory ) const; + void Register( void const * memory ) const; protected: // called when the object this thing is chained to gets destroyed - virtual void OnBreak() CLIO_NOTHROW; + virtual void OnBreak(); virtual void OnSetObjectWrapper(); // hook called after the object wrapper was set private: Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/iclassinfo.cpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -347,7 +347,16 @@ // found? Be happy and return it. if ( wrapper ) + { + // restore the object pointer in case it broke + if ( !wrapper->object_ ) + { + wrapper->object_ = object; + } + assert( wrapper->object_ == object ); + return wrapper->GetSelf(); + } // not found. We need to create a new wrapper. Modified: private/z-man/clio/iclassinfo.hpp =================================================================== --- private/z-man/clio/iclassinfo.hpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/iclassinfo.hpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -121,9 +121,9 @@ } // inform class than an object of it went out of scope - void Break( ObjectWrapper & wrapper ) const + bool Break( ObjectWrapper & wrapper ) const { - OnBreak( wrapper ); + return OnBreak( wrapper ); } // registers a factory, taking ownership of it @@ -210,7 +210,7 @@ virtual size_t DoGetSize() const CLIO_NOTHROW = 0; // inform class than an object of it went out of scope - virtual void OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; + virtual bool OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; // returns a static function capable of creating an Io object with an object of this class virtual IoStateProtoFunc * DoGetStateProtoFunc() const CLIO_NOTHROW = 0; Modified: private/z-man/clio/ifunctioninfo.cpp =================================================================== --- private/z-man/clio/ifunctioninfo.cpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/ifunctioninfo.cpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -170,11 +170,14 @@ argumentsRetained.push_back( object ); } + IoObject * ret = NULL; + IFunctionInfo const * executer = this; + // and execute if ( !Overloads::Next() ) { // no overloads, just call and see. - return (*execute_)( selfWrapper, self, locals, m, state, arguments, this ); + ret = (*execute_)( selfWrapper, self, locals, m, state, arguments, this ); } else { @@ -210,7 +213,7 @@ run = run->Overloads::Next(); } - // TODO: better check that there is only one best matching overload + // better check that there is only one best matching overload if ( overloads.size() != 1 ) { // get passed argument types @@ -283,11 +286,42 @@ assert( overloads.size() == 1 ); // call only available overload - return (*( overloads[0]->execute_ ) )( selfWrapper, self, locals, m, state, arguments, this ); + executer = overloads[0]; + ret = (*( executer->execute_ ) )( selfWrapper, self, locals, m, state, arguments, this ); } - assert(0); - return 0; + assert(ret); + + // transfer ownership + ObjectWrapper * wrapper = ObjectWrapper::GetObjectWrapper( ret ); + if ( wrapper ) + { + if ( executer->transferOwnership_ ) + { + wrapper->SetOwnership( ObjectWrapper::OwnedByIo ); + } + + if ( !executer->nonBreaking_ ) + { + // unchain the object. Right now, we're pretty sure it exists. + wrapper->UnChain(); + + // well, we better assume all C++ objects returned by a previous C++ function + // are gone now. + ObjectWrapper::BreakAll(); + } + + // chain the object. It's the only possibly volatile object + // that survived the carnage of the previous function call. + wrapper->Chain(); + } + else + { + // break all C++ objects anyway. + ObjectWrapper::BreakAll(); + } + + return ret; } // checks whether the call is coming from a subclass @@ -550,6 +584,8 @@ , execute_( execute ) , quality_( quality ) , callIsComingFromScript_( false ) + , transferOwnership_( false ) + , nonBreaking_( false ) {} // adds a function overload, returns representing function Modified: private/z-man/clio/ifunctioninfo.hpp =================================================================== --- private/z-man/clio/ifunctioninfo.hpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/ifunctioninfo.hpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -94,13 +94,25 @@ { return debugInfo_; } - + IFunctionInfo & SetDebugInfo( std::string const & debugInfo ) { debugInfo_ = debugInfo; return *this; } + IFunctionInfo & TransferOwnership() + { + transferOwnership_ = true; + return *this; + } + + IFunctionInfo & NonBreaking() + { + nonBreaking_ = true; + return *this; + } + // returns the full function name std::string GetFullName() const CLIO_NOTHROW; protected: @@ -131,6 +143,13 @@ // the top of the stack, set when the function is called static void const * topOfStack_; + + // if set, this flag indicates that the ownership of the returned pointer/reference shall + // change from the function to the caller. + bool transferOwnership_; + + // if set, this indicates that the method will never ever break (deallocate) C++ objects. + bool nonBreaking_; }; // information about the call currently in process Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/objectwrapper.cpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -51,8 +51,15 @@ // inform chained objects for( Set::iterator iter = set_.begin(); iter != set_.end(); ++iter ) { - (*iter)->Break(); + // first fetch the object. ObjectWrapper::Break() may remove itself from the set. + ObjectWrapper * object = *iter; + assert( object ); + object->Break(); + object->chainedTo_ = 0; } + + // once broken, the chains are no longer needed + set_.clear(); } // returns singleton for unchained objects @@ -227,12 +234,47 @@ throw Exception("Action not supported on prototypes"); } +// chain this wrapper to possible surrounding wrappers +void ObjectWrapper::Chain() +{ + // chain this wrapper to exterior wrappers + RegisterChained( this, object_ ); +} + +void ObjectWrapper::UnChain() +{ + // un chain this wrapper from exterior wrappers + if ( chainedTo_ ) + { + chainedTo_->UnRegisterChained( this ); + } +} + void ObjectWrapper::Break() { // inform class info if ( GetObject() ) { - GetClassInfo().Break( *this ); + if( !GetClassInfo().Break( *this ) ) + { + // object itself says it is aware of this wrapper, and that it is still alive, + // and will inform us about its demise in time. + return; + } + + // if this object is owned by IO (can be in another state), also assume everything + // is fine. + ObjectWrapper * run = this; + do + { + if ( run->GetOwnership() == OwnedByIo ) + { + return; + } + + run = run->Next(); + } + while ( run != this ); } // inform chained objects @@ -243,12 +285,19 @@ } // find the right object wrapper and chain to it, or do nothing. -void ObjectWrapper::RegisterChained( ObjectWrapper * chained, void const * location ) +bool ObjectWrapper::RegisterChainedSpecific( ObjectWrapper * chained, void const * location ) { + assert( chained ); + + if ( !location ) + { + return true; + } + // is the chained object already chained to something worthwile? if ( chained->chainedTo_ && chained->chainedTo_->owner_ ) { - return; + return true; } // find the iterator that points to just the wrapper that holds an object @@ -257,8 +306,7 @@ if ( icandidate == GetWrapperMap().begin() ) { // totaly out of bounds, default action - GetUnchained().RegisterChained( chained ); - return; + return false; } else if ( icandidate == GetWrapperMap().end() ) { @@ -270,19 +318,29 @@ -- icandidate; } + // avoid self-chaining + while( (*icandidate).second == chained && icandidate != GetWrapperMap().begin() ) + { + --icandidate; + } + ObjectWrapper * candidate = (*icandidate).second; if ( !candidate ) { // invalid iterator. Not sure how this can happen, but definitely: do nothing. - GetUnchained().RegisterChained( chained ); - return; + return false; } + // find topmost wrapper + while( candidate->chainedTo_ && candidate->chainedTo_->owner_ ) + { + candidate = candidate->chainedTo_->owner_; + } + if ( (char *)location - (char *)candidate->GetObject() >= (int)candidate->GetClassInfo().GetSize() ) { // location out of bounds. Do nothing. - GetUnchained().RegisterChained( chained ); - return; + return false; } // make sure chainedTo_ and self are of the same garbage collector @@ -297,13 +355,28 @@ { // location out of bounds. Do nothing. GetUnchained().RegisterChained( chained ); - return; + return false; } // ah, location lies inside the memory block managed by the wrapper candidate. candidate->chained_.RegisterChained( chained ); + return true; } +// find the right object wrapper and chain to it, or do nothing. +void ObjectWrapper::RegisterChained( ObjectWrapper * chained, void const * location ) +{ + if ( !RegisterChainedSpecific( chained, location ) ) + { + // only register C++-owned objects in the global set, only they can expire + // without us noticing + if ( chained->GetOwnership() != OwnedByIo ) + { + GetUnchained().RegisterChained( chained ); + } + } +} + void ObjectWrapper::RegisterGCMarker( GCAutoMarker & marker ) { markers_.Add( marker ); @@ -362,9 +435,6 @@ } else { - // chain this wrapper to exterior wrappers - RegisterChained( this, object_ ); - // yes? Then we're the main wrapper now. GetClassInfo().RegisterWrapper( object_, this ); GetWrapperMap()[ object_ ] = this; Modified: private/z-man/clio/objectwrapper.hpp =================================================================== --- private/z-man/clio/objectwrapper.hpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/objectwrapper.hpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -74,9 +74,18 @@ // error helper function static void NoObjectError(); - // find the right object wrapper and chain to it, or do nothing. + // find the right object wrapper and chain to it (and return true), or do nothing (and return false). + static bool RegisterChainedSpecific( ObjectWrapper * chained, void const * location ); + + // find the right object wrapper and chain to it, or chain wrapper to global hook. static void RegisterChained( ObjectWrapper * chained, void const * location ); + // un chain this wrapper from surrounding wrappers + void UnChain(); + + // chain this wrapper to possible surrounding wrappers + void Chain(); + // call when this object, for one reason or another, goes out of scope void Break(); Modified: private/z-man/clio/objectwrapperaware.cpp =================================================================== --- private/z-man/clio/objectwrapperaware.cpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/objectwrapperaware.cpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -50,10 +50,11 @@ } // informs an object about the wrapper it was assigned to. -void AwareMaker::BreakObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW +bool AwareMaker::BreakObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW { assert(object); object->OnBreak(); + return false; } } Modified: private/z-man/clio/objectwrapperaware.hpp =================================================================== --- private/z-man/clio/objectwrapperaware.hpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/objectwrapperaware.hpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -40,12 +40,13 @@ // whether it makes sense or not. If it doesn't make sense, this stub is called instead. inline static void MakeObjectWrapperAware( ObjectWrapper *, void * ){} - // informs an object about a parent object breaking - static void BreakObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW; + // informs an object about a parent object breaking. Returns 'false' if the object + // feels quite alive. + static bool BreakObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW; // this second overload makes it possible to call the function from a template without knowing // whether it makes sense or not. If it doesn't make sense, this stub is called instead. - inline static void BreakObjectWrapperAware( void * ){} + inline static bool BreakObjectWrapperAware( void * ){return true;} }; } Modified: private/z-man/clio/tests/basic.test/test.cpp =================================================================== --- private/z-man/clio/tests/basic.test/test.cpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/tests/basic.test/test.cpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -59,8 +59,7 @@ static void Static() {} - // pointer return values are wrapped in Io, and Io takes ownership of the - // object by default + // pointer return values are wrapped in Io TestWrapper * Create( int i ) { TestWrapper * wrapper = new TestWrapper(); @@ -109,7 +108,7 @@ CLIO_METHOD( Convert2 ); CLIO_METHOD( Ptr ); CLIO_METHOD( Ptr2 ); -CLIO_METHOD( Create ); +CLIO_METHOD( Create ).TransferOwnership(); CLIO_METHOD( StaticObject ); CLIO_METHOD( Value ); CLIO_METHOD( UnknownOut ); Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-20 15:07:44 UTC (rev 8014) @@ -52,21 +52,25 @@ explicit Proxy( ORIGINAL * original ) : original_( original ) { - // register with object wrappers assert( original ); - Register( original ); } // creates proxy for original explicit Proxy( ORIGINAL & original ) : original_( &original ) { - // register with object wrappers - Register( &original ); } protected: + virtual void OnSetObjectWrapper() + { + if ( GetObjectWrapper() && original_ ) + { + Register( original_ ); + } + } + // called when the object this thing is chained to gets destroyed - virtual void OnBreak() CLIO_NOTHROW + virtual void OnBreak() { // remove reference to original original_ = 0; Modified: private/z-man/clio/tests/crash.test/test.io =================================================================== --- private/z-man/clio/tests/crash.test/test.io 2008-02-20 12:34:59 UTC (rev 8013) +++ private/z-man/clio/tests/crash.test/test.io 2008-02-20 15:07:44 UTC (rev 8014) @@ -4,7 +4,7 @@ getInner := method( y := Y clone(); return y getInner() ) innerX := getInner() -// wait for the original to expire +// wait for the original to expired callGC() // and try to use the inner object This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-20 16:43:02
|
Revision: 8015 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8015&view=rev Author: z-man Date: 2008-02-20 08:43:05 -0800 (Wed, 20 Feb 2008) Log Message: ----------- Fixed references to nested class properties. Modified Paths: -------------- private/z-man/clio/gcmarker.cpp private/z-man/clio/ifunctioninfo.cpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapper.hpp private/z-man/clio/tests/crash.test/output.txt private/z-man/clio/tests/crash.test/test.io Modified: private/z-man/clio/gcmarker.cpp =================================================================== --- private/z-man/clio/gcmarker.cpp 2008-02-20 15:07:44 UTC (rev 8014) +++ private/z-man/clio/gcmarker.cpp 2008-02-20 16:43:05 UTC (rev 8015) @@ -76,15 +76,18 @@ } // a small collection of GC auto markers. It holds the markers that belong -// to the C+= part of a single Io object. - +// to the C++ part of a single Io object. GCAutoMarkerSmallSet::~GCAutoMarkerSmallSet() { for ( RawSet::iterator iter = markers_.begin(); iter != markers_.end(); ++iter ) { if( *iter ) { - Remove( *(*iter) ); + GCAutoMarker & marker = *(*iter); + Remove( marker ); + + // re-add them to the big set + GCAutoMarkerBigSet::Get().Add( marker ); } } } Modified: private/z-man/clio/ifunctioninfo.cpp =================================================================== --- private/z-man/clio/ifunctioninfo.cpp 2008-02-20 15:07:44 UTC (rev 8014) +++ private/z-man/clio/ifunctioninfo.cpp 2008-02-20 16:43:05 UTC (rev 8015) @@ -304,7 +304,7 @@ if ( !executer->nonBreaking_ ) { // unchain the object. Right now, we're pretty sure it exists. - wrapper->UnChain(); + wrapper->UnChainGlobal(); // well, we better assume all C++ objects returned by a previous C++ function // are gone now. Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-20 15:07:44 UTC (rev 8014) +++ private/z-man/clio/objectwrapper.cpp 2008-02-20 16:43:05 UTC (rev 8015) @@ -46,7 +46,7 @@ } // breaks all chained objects. Call when the mother object goes out of scope. -void ChainedSet::Break() +void ChainedSet::Break( bool force ) { // inform chained objects for( Set::iterator iter = set_.begin(); iter != set_.end(); ++iter ) @@ -54,7 +54,7 @@ // first fetch the object. ObjectWrapper::Break() may remove itself from the set. ObjectWrapper * object = *iter; assert( object ); - object->Break(); + object->Break( force ); object->chainedTo_ = 0; } @@ -85,6 +85,42 @@ return map; } +// returns the biggest object wrapper that manages the given location +static ObjectWrapper * GetEnclosingWrapper( void const * location ) +{ + WrapperMap const & map = GetWrapperMap(); + + // find the iterator that points to just the wrapper that holds an object + // that may contain *location. + WrapperMap::const_iterator icandidate = map.upper_bound( location ); + if ( icandidate == map.begin() ) + { + // totaly out of bounds, default action + return 0; + } + else if ( icandidate == map.end() ) + { + // take the last element + icandidate = map.find( (*map.rbegin()).first ); + } + else + { + -- icandidate; + } + + ObjectWrapper * candidate = (*icandidate).second; + if ( candidate ) + { + // check whether the size fits + if ( (char const *)location - (char const *)candidate->GetObject() >= (int)candidate->GetClassInfo().GetSize() ) + { + return 0; + } + } + + return candidate; +} + // data structures to keep track of main wrappers of objects shared between states typedef std::set< ObjectWrapper * > WrapperSet; typedef std::map< IoState *, WrapperSet > WrappersOnState; @@ -159,18 +195,22 @@ if ( Next() == this ) { + void * oldObject = object_; + if ( GetOwnership() == OwnedByIo ) { - markers_.CollectAll(); - GetClassInfo().GetFactory().Destroy( object_ ); - // inform other wrappers of the object's death ObjectDestroyed(); + markers_.CollectAll(); + GetClassInfo().GetFactory().Destroy( oldObject ); + assert( !object_ ); } - - Break(); + else + { + Break(); + } } object_ = 0; @@ -216,6 +256,7 @@ { // remove all traces of the object GetClassInfo().UnregisterWrapper( run->object_, run ); + run->Break( true ); run->object_ = 0; run = run->Next(); } @@ -250,12 +291,21 @@ } } -void ObjectWrapper::Break() +void ObjectWrapper::UnChainGlobal() { + // un chain this wrapper from exterior wrappers + if ( chainedTo_ && !chainedTo_->owner_ ) + { + chainedTo_->UnRegisterChained( this ); + } +} + +void ObjectWrapper::Break( bool force ) +{ // inform class info if ( GetObject() ) { - if( !GetClassInfo().Break( *this ) ) + if( !GetClassInfo().Break( *this ) && !force ) { // object itself says it is aware of this wrapper, and that it is still alive, // and will inform us about its demise in time. @@ -264,22 +314,32 @@ // if this object is owned by IO (can be in another state), also assume everything // is fine. - ObjectWrapper * run = this; - do + if ( !force ) { - if ( run->GetOwnership() == OwnedByIo ) + ObjectWrapper * run = this; + do { - return; + if ( run->GetOwnership() == OwnedByIo ) + { + return; + } + + run = run->Next(); } - - run = run->Next(); + while ( run != this ); } - while ( run != this ); } // inform chained objects - chained_.Break(); + chained_.Break( force ); + // unlink from wrapper map + WrapperMap & map = GetWrapperMap(); + if ( map[ object_ ] == this ) + { + map.erase( object_ ); + } + // nullify object object_ = 0; } @@ -289,60 +349,24 @@ { assert( chained ); - if ( !location ) - { - return true; - } - // is the chained object already chained to something worthwile? if ( chained->chainedTo_ && chained->chainedTo_->owner_ ) { return true; } - // find the iterator that points to just the wrapper that holds an object - // that may contain *location. - WrapperMap::iterator icandidate = GetWrapperMap().upper_bound( location ); - if ( icandidate == GetWrapperMap().begin() ) + if ( !location ) { - // totaly out of bounds, default action - return false; + return true; } - else if ( icandidate == GetWrapperMap().end() ) - { - // take the lase element - icandidate = GetWrapperMap().find( (*GetWrapperMap().rbegin()).first ); - } - else - { - -- icandidate; - } - // avoid self-chaining - while( (*icandidate).second == chained && icandidate != GetWrapperMap().begin() ) - { - --icandidate; - } - - ObjectWrapper * candidate = (*icandidate).second; + ObjectWrapper * candidate = GetEnclosingWrapper( location ); if ( !candidate ) { - // invalid iterator. Not sure how this can happen, but definitely: do nothing. + // no wrapper found return false; } - // find topmost wrapper - while( candidate->chainedTo_ && candidate->chainedTo_->owner_ ) - { - candidate = candidate->chainedTo_->owner_; - } - - if ( (char *)location - (char *)candidate->GetObject() >= (int)candidate->GetClassInfo().GetSize() ) - { - // location out of bounds. Do nothing. - return false; - } - // make sure chainedTo_ and self are of the same garbage collector if ( IoObject_state( chained->GetSelf() )->collector != IoObject_state( candidate->GetSelf() )->collector ) { @@ -354,7 +378,6 @@ if ( candidate == chained ) { // location out of bounds. Do nothing. - GetUnchained().RegisterChained( chained ); return false; } @@ -437,8 +460,61 @@ { // yes? Then we're the main wrapper now. GetClassInfo().RegisterWrapper( object_, this ); - GetWrapperMap()[ object_ ] = this; + + // update wrapper map + { + // check for enclosing wrapper + ObjectWrapper * enclosing = GetEnclosingWrapper( object_ ); + + WrapperMap & map = GetWrapperMap(); + + size_t mySize = GetClassInfo().GetSize(); + if ( enclosing ) + { + // if the enclosing wrapper is smaller than this or owned by C and the sizes + // are equal, reverse the enclosing order + if ( enclosing->GetClassInfo().GetSize() < mySize || + ( enclosing->GetClassInfo().GetSize() == mySize && + enclosing->GetOwnership() == OwnedByC ) ) + { + map.erase( enclosing->GetObject() ); + map[ object_ ] = this; + + // chain the enclosed object to this + enclosing->Chain(); + } + } + else + { + map[ object_ ] = this; + + // find possible enclosed objects and erase them from the map + + // find the iterator that points to just the wrapper that holds an object + // that may contain *location. + WrapperMap::iterator start = map.find( object_ ); + WrapperMap::iterator end = start; + ++start; + do + { + ++end; + if ( end == map.end() ) + { + break; + } + + if ( (char *)(*end).first - (char *)object_ >= (int)mySize ) + { + break; + } + } + while( true ); + + map.erase( start, end ); + } + } + // take over automatic GC markers markers_.TakeOver( GCAutoMarkerBigSet::Get(), object_, GetClassInfo().GetSize() ); } Modified: private/z-man/clio/objectwrapper.hpp =================================================================== --- private/z-man/clio/objectwrapper.hpp 2008-02-20 15:07:44 UTC (rev 8014) +++ private/z-man/clio/objectwrapper.hpp 2008-02-20 16:43:05 UTC (rev 8015) @@ -36,7 +36,7 @@ void UnRegisterChained( ObjectWrapper * chained ); // breaks all chained objects. Call when the mother object goes out of scope. - void Break(); + void Break( bool force = false ); private: Set set_; ObjectWrapper * owner_; @@ -80,14 +80,17 @@ // find the right object wrapper and chain to it, or chain wrapper to global hook. static void RegisterChained( ObjectWrapper * chained, void const * location ); - // un chain this wrapper from surrounding wrappers + // unchain this wrapper from surrounding wrappers. void UnChain(); + // unchain this wrapper from the global list so it survives a BreakAll() call. + void UnChainGlobal(); + // chain this wrapper to possible surrounding wrappers void Chain(); // call when this object, for one reason or another, goes out of scope - void Break(); + void Break( bool force = false ); // call on all calls to C++ that may make objects get deleted static void BreakAll(); Modified: private/z-man/clio/tests/crash.test/output.txt =================================================================== --- private/z-man/clio/tests/crash.test/output.txt 2008-02-20 15:07:44 UTC (rev 8014) +++ private/z-man/clio/tests/crash.test/output.txt 2008-02-20 16:43:05 UTC (rev 8015) @@ -0,0 +1,38 @@ +<<<< callGC := method( for(a,0,1000,blarg := a clone ) ) + +<<<< // crash test 1: get an inner object of another object +<<<< getInner := method( y := Y clone(); return y getInner() ) +<<<< innerX := getInner() +X created. +Y created. + +<<<< // wait for the original to expired +<<<< callGC() + +<<<< // and try to use the inner object +<<<< innerX test() +Test. + +<<<< // next attempt, reference to inner integers +<<<< getInner2 := method( y := Y clone(); return y getInner() getInt() ) +<<<< innerInt := getInner2() +X created. +Y created. + +<<<< innerInt set(3) +<<<< innerInt println +3 + +<<<< callGC() + +<<<< // try to access an inner integer after the main object (hopefully not!) expired +<<<< innerInt println +3 +<<<< innerInt set(2) +<<<< innerInt println +2 + +Y destroyed. +X destroyed. +Y destroyed. +X destroyed. Modified: private/z-man/clio/tests/crash.test/test.io =================================================================== --- private/z-man/clio/tests/crash.test/test.io 2008-02-20 15:07:44 UTC (rev 8014) +++ private/z-man/clio/tests/crash.test/test.io 2008-02-20 16:43:05 UTC (rev 8015) @@ -19,7 +19,7 @@ callGC() -// try to access an inner integer after the main object expired +// try to access an inner integer after the main object (hopefully not!) expired innerInt println innerInt set(2) innerInt println This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-20 16:51:31
|
Revision: 8016 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8016&view=rev Author: z-man Date: 2008-02-20 08:51:31 -0800 (Wed, 20 Feb 2008) Log Message: ----------- Marked some internally wrapped functions as non-breaking. Modified Paths: -------------- private/z-man/clio/dataconversion_extended.hpp private/z-man/clio/enum.cpp private/z-man/clio/enum.hpp Modified: private/z-man/clio/dataconversion_extended.hpp =================================================================== --- private/z-man/clio/dataconversion_extended.hpp 2008-02-20 16:43:05 UTC (rev 8015) +++ private/z-man/clio/dataconversion_extended.hpp 2008-02-20 16:51:31 UTC (rev 8016) @@ -142,6 +142,8 @@ { // For example this little beast: it wraps const references to primitives // (and other objects) so the receiver on the Io side can get them. +// This is really just for primitives. Anything that may cause memory allocation +// /deallocation on assignment is not suited. template < class PRIMITIVE > class PrimitiveProxyConstBase: public IChained { public: @@ -291,7 +293,7 @@ CLIO_TEMPLATE_CLASS_EX( clio::dataconversion::PrimitiveProxyConstBase, (1,(class)), "ConstRef" ) { - CLIO_METHOD( Get ); + CLIO_METHOD( Get ).NonBreaking(); } CLIO_TEMPLATE_CLASS_EX( clio::dataconversion::PrimitiveProxyNoConstBase, (1,(class)), "NoConstRef" ) @@ -299,7 +301,7 @@ typedef clio::dataconversion::PrimitiveProxyConstBase< T1 > Base; CLIO_CLASS_BASE( Base ); - CLIO_METHOD( Set ); + CLIO_METHOD( Set ).NonBreaking(); } CLIO_TEMPLATE_CLASS_EX( clio::dataconversion::PrimitiveProxy, (1,(class)), "Ref" ) Modified: private/z-man/clio/enum.cpp =================================================================== --- private/z-man/clio/enum.cpp 2008-02-20 16:43:05 UTC (rev 8015) +++ private/z-man/clio/enum.cpp 2008-02-20 16:51:31 UTC (rev 8016) @@ -104,9 +104,9 @@ caster2.GetSource()->RegisterBaseClass( *caster2.GetTarget(), &caster2 ); } - CLIO_METHOD( GetName_ ); - CLIO_METHOD( GetStatic_ ); - CLIO_METHOD( With ); + CLIO_METHOD( GetName_ ).NonBreaking(); + CLIO_METHOD( GetStatic_ ).NonBreaking(); + CLIO_METHOD( With ).NonBreaking(); CLIO_INJECTCODE( "print := method( getName_( self ) print )" ); CLIO_INJECTCODE( "toSimpleString := method( getName_( self ) )" ); Modified: private/z-man/clio/enum.hpp =================================================================== --- private/z-man/clio/enum.hpp 2008-02-20 16:43:05 UTC (rev 8015) +++ private/z-man/clio/enum.hpp 2008-02-20 16:51:31 UTC (rev 8016) @@ -71,12 +71,12 @@ info.CreateDestructor ( BoolToType< true >() ); // register helper functions - CLIO_METHOD_IMPORT( EnumWrapper<CLASS>::GetName_ ); - CLIO_METHOD_IMPORT( EnumWrapper<CLASS>::GetStatic_ ); - CLIO_METHOD_IMPORT( EnumWrapper<CLASS>::Compare_ ); + CLIO_METHOD_IMPORT( EnumWrapper<CLASS>::GetName_ ).NonBreaking(); + CLIO_METHOD_IMPORT( EnumWrapper<CLASS>::GetStatic_ ).NonBreaking(); + CLIO_METHOD_IMPORT( EnumWrapper<CLASS>::Compare_ ).NonBreaking(); // register constructor from Number - CLIO_METHOD_IMPORT_EX( EnumWrapper<CLASS>::With,, "with" ); + CLIO_METHOD_IMPORT_EX( EnumWrapper<CLASS>::With,, "with" ).NonBreaking(); // inject glue code for display CLIO_INJECTCODE( enumIoCode ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-20 18:15:17
|
Revision: 8017 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8017&view=rev Author: z-man Date: 2008-02-20 10:15:18 -0800 (Wed, 20 Feb 2008) Log Message: ----------- Fixed memory access error, proxies were not broken on time. Modified Paths: -------------- private/z-man/clio/dataconversion_extended.hpp private/z-man/clio/ifunctioninfo.cpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapper.hpp Modified: private/z-man/clio/dataconversion_extended.hpp =================================================================== --- private/z-man/clio/dataconversion_extended.hpp 2008-02-20 16:51:31 UTC (rev 8016) +++ private/z-man/clio/dataconversion_extended.hpp 2008-02-20 18:15:18 UTC (rev 8017) @@ -194,7 +194,7 @@ virtual void OnSetObjectWrapper() { - if ( data_ && GetObjectWrapper() ) + if ( data_ && GetObjectWrapper() && data_ != &cache_ ) { Register( data_ ); } Modified: private/z-man/clio/ifunctioninfo.cpp =================================================================== --- private/z-man/clio/ifunctioninfo.cpp 2008-02-20 16:51:31 UTC (rev 8016) +++ private/z-man/clio/ifunctioninfo.cpp 2008-02-20 18:15:18 UTC (rev 8017) @@ -304,16 +304,24 @@ if ( !executer->nonBreaking_ ) { // unchain the object. Right now, we're pretty sure it exists. - wrapper->UnChainGlobal(); + ChainedSet * oldSet = wrapper->UnChainGlobal(); // well, we better assume all C++ objects returned by a previous C++ function // are gone now. ObjectWrapper::BreakAll(); + + // reregister object + if ( oldSet ) + { + oldSet->RegisterChained( wrapper ); + } } - - // chain the object. It's the only possibly volatile object - // that survived the carnage of the previous function call. - wrapper->Chain(); + else + { + // chain the object. It's the only possibly volatile object + // that survived the carnage of the previous function call. + wrapper->Chain(); + } } else { Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-20 16:51:31 UTC (rev 8016) +++ private/z-man/clio/objectwrapper.cpp 2008-02-20 18:15:18 UTC (rev 8017) @@ -203,6 +203,10 @@ ObjectDestroyed(); markers_.CollectAll(); + + // destroying the object may kill other, unrelated stuff + BreakAll(); + GetClassInfo().GetFactory().Destroy( oldObject ); assert( !object_ ); @@ -282,22 +286,32 @@ RegisterChained( this, object_ ); } -void ObjectWrapper::UnChain() +ChainedSet * ObjectWrapper::UnChain() { + ChainedSet * ret = chainedTo_; + // un chain this wrapper from exterior wrappers if ( chainedTo_ ) { chainedTo_->UnRegisterChained( this ); } + + return ret; } -void ObjectWrapper::UnChainGlobal() +ChainedSet * ObjectWrapper::UnChainGlobal() { // un chain this wrapper from exterior wrappers if ( chainedTo_ && !chainedTo_->owner_ ) { + ChainedSet * ret = chainedTo_; + chainedTo_->UnRegisterChained( this ); + + return ret; } + + return 0; } void ObjectWrapper::Break( bool force ) @@ -393,7 +407,7 @@ { // only register C++-owned objects in the global set, only they can expire // without us noticing - if ( chained->GetOwnership() != OwnedByIo ) + if ( chained->GetOwnership() != OwnedByIo || location != chained->GetObject() ) { GetUnchained().RegisterChained( chained ); } @@ -420,7 +434,8 @@ // copy constructor for cloning ObjectWrapper::ObjectWrapper( ObjectWrapper const & other, IoObject * self ) -: classInfo_( other.GetClassInfo() ) +: object_( 0 ) +, classInfo_( other.GetClassInfo() ) , self_( self ) , ownership_( OwnedByIo ) , chained_( this ) Modified: private/z-man/clio/objectwrapper.hpp =================================================================== --- private/z-man/clio/objectwrapper.hpp 2008-02-20 16:51:31 UTC (rev 8016) +++ private/z-man/clio/objectwrapper.hpp 2008-02-20 18:15:18 UTC (rev 8017) @@ -81,10 +81,10 @@ static void RegisterChained( ObjectWrapper * chained, void const * location ); // unchain this wrapper from surrounding wrappers. - void UnChain(); + ChainedSet * UnChain(); // unchain this wrapper from the global list so it survives a BreakAll() call. - void UnChainGlobal(); + ChainedSet * UnChainGlobal(); // chain this wrapper to possible surrounding wrappers void Chain(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-20 18:50:52
|
Revision: 8018 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8018&view=rev Author: z-man Date: 2008-02-20 10:45:16 -0800 (Wed, 20 Feb 2008) Log Message: ----------- Ok, repaired crash test again, and avoided a garbage collector race condition. Modified Paths: -------------- private/z-man/clio/iclassinfo.cpp private/z-man/clio/ifunctioninfo.cpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/tests/container.test/test.cpp Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-20 18:15:18 UTC (rev 8017) +++ private/z-man/clio/iclassinfo.cpp 2008-02-20 18:45:16 UTC (rev 8018) @@ -13,6 +13,7 @@ #include "ifunctioninfo.hpp" #include "state.hpp" +#include <deque> #include <iostream> #include <sstream> #include <typeinfo> @@ -540,6 +541,29 @@ return 0; } +/* +// to avoid tag memory leaks. +class TagAutoDeleter +{ +public: + ~TagAutoDeleter() + { + for ( std::deque< IoTag * >::iterator i = tags_.begin(); i != tags_.end(); ++i ) + { + IoTag_free( *i ); + } + tags_.clear(); + } + + void Add( IoTag * tag ) + { + tags_.push_back( tag ); + } +private: + std::deque< IoTag * > tags_; +}; +*/ + // tag creator IoTag * IClassInfo::Tag( IoState * state ) const CLIO_NOTHROW { @@ -554,6 +578,9 @@ // tag->performFunc = (TagPerformFunc*) Perform; // tag->activateFunc = (TagActivateFunc*) Activate; + // static TagAutoDeleter deleter; + // deleter.Add( tag ); + return tag; } Modified: private/z-man/clio/ifunctioninfo.cpp =================================================================== --- private/z-man/clio/ifunctioninfo.cpp 2008-02-20 18:15:18 UTC (rev 8017) +++ private/z-man/clio/ifunctioninfo.cpp 2008-02-20 18:45:16 UTC (rev 8018) @@ -316,12 +316,10 @@ oldSet->RegisterChained( wrapper ); } } - else - { - // chain the object. It's the only possibly volatile object - // that survived the carnage of the previous function call. - wrapper->Chain(); - } + + // chain the object. It's the only possibly volatile object + // that survived the carnage of the previous function call. + wrapper->Chain(); } else { Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-20 18:15:18 UTC (rev 8017) +++ private/z-man/clio/objectwrapper.cpp 2008-02-20 18:45:16 UTC (rev 8018) @@ -37,6 +37,11 @@ { set_.insert( chained ); chained->chainedTo_ = this; + + if ( owner_ && owner_->GetSelf() ) + { + IoObject_shouldMark( owner_->GetSelf() ); + } } void ChainedSet::UnRegisterChained( ObjectWrapper * chained ) Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-20 18:15:18 UTC (rev 8017) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-20 18:45:16 UTC (rev 8018) @@ -41,7 +41,7 @@ { std::ostringstream err; err << "Proxy for " << GetTypeName< ORIGINAL >() << - " is broken, the wrapped object may have gone out of scope."; + " is broken"; throw Exception( "Broken Proxy", err.str() ); } @@ -60,6 +60,10 @@ : original_( &original ) { } + + ~Proxy() + { + } protected: virtual void OnSetObjectWrapper() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-20 20:54:44
|
Revision: 8021 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8021&view=rev Author: z-man Date: 2008-02-20 12:54:49 -0800 (Wed, 20 Feb 2008) Log Message: ----------- Refactored container test to use some a common header. Modified Paths: -------------- private/z-man/clio/tests/container.test/test.cpp Added Paths: ----------- private/z-man/clio/proxy.cpp private/z-man/clio/proxy.hpp private/z-man/clio/std_container.cpp private/z-man/clio/std_container.hpp Added: private/z-man/clio/proxy.cpp =================================================================== --- private/z-man/clio/proxy.cpp (rev 0) +++ private/z-man/clio/proxy.cpp 2008-02-20 20:54:49 UTC (rev 8021) @@ -0,0 +1,6 @@ +#include "proxy.hpp" + +namespace clio +{ + +} Added: private/z-man/clio/proxy.hpp =================================================================== --- private/z-man/clio/proxy.hpp (rev 0) +++ private/z-man/clio/proxy.hpp 2008-02-20 20:54:49 UTC (rev 8021) @@ -0,0 +1,121 @@ +#ifndef CLIO_PROXY_H +#define CLIO_PROXY_H + +#include "ichained.hpp" +#include "classname.hpp" +#include "dataconversion.hpp" + +#include <sstream> + +namespace clio +{ + +// proxy objects. ORIGINAL should be the raw type of the wrapped object. +template< class ORIGINAL > +class Proxy: public IChained +{ +public: + // returns the original object + ORIGINAL & Get() const + { + if ( !original_ ) + { + std::ostringstream err; + err << "Proxy for " << GetTypeName< ORIGINAL >() << + " is broken"; + throw Exception( "Broken Proxy", err.str() ); + } + + return *original_; + } + + // creates proxy for original + explicit Proxy( ORIGINAL * original ) + : original_( original ) + { + assert( original ); + } + + // creates proxy for original + explicit Proxy( ORIGINAL & original ) + : original_( &original ) + { + } + + virtual ~Proxy() + { + } +protected: + // called when the object is linked to its wrapper + virtual void OnSetObjectWrapper() + { + if ( GetObjectWrapper() && original_ ) + { + Register( original_ ); + } + } + + // called when the object this thing is chained to gets destroyed + virtual void OnBreak() + { + // remove reference to original + original_ = 0; + + // delegate + IChained::OnBreak(); + } +private: + // pointer to the original wrapped object + ORIGINAL * original_; +}; + +namespace dataconversion +{ + +// Data conversion via proxy classes. The proxy class is supposed to have this +// public interface: +// class PROXY{ +// PROXY( ORIGINAL ); +// ORIGINAL Get(); +// }; +// and is supposed to be derived from IChained. + +template< class ORIGINAL, class PROXY > class DataConverterProxy: public DataConverterDefs< ORIGINAL > +{ +public: + typedef DataConverterDefs< ORIGINAL > Base; + + typedef typename Base::TArg TArg; + typedef typename Base::Converted Converted; + + typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< PROXY > > IMPL; + + static Converted FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) + { + PROXY & proxy = IMPL::FromIo( from, call, thrower ); + return proxy.Get(); + } + + static void CheckType( IChained const & ){} + + static inline IoObject * ToIo( IoState * state, TArg from, DataConversionCall const & call ) + { + // create + typename IMPL::TArg arg = *(new PROXY(from)); + + // READ BELOW IF THIS LINE GIVES AN ERROR + DataConverterProxy::CheckType( arg ); + // If the above line gives an error, that means you tried to register + // a proxy object for data conversion that is not derived from clio::IChained. + // Let all your proxies inherit from clio::IChained to correct this error. It's + // best if you let them inherit from clio::Proxy< ORIGINAL >. + + return IMPL::ToIo( state, arg, call ); + } +}; + +} + +} + +#endif Added: private/z-man/clio/std_container.cpp =================================================================== --- private/z-man/clio/std_container.cpp (rev 0) +++ private/z-man/clio/std_container.cpp 2008-02-20 20:54:49 UTC (rev 8021) @@ -0,0 +1,13 @@ +#include "std_container.hpp" + +namespace clio +{ + +char const * vectorProxyCode = +"foreach1_ := method( s := size; for( i, 0, s-1, at(i) doMessage( call message argAt(0) ) ) )\n" +"foreach2_ := method( s := size; for( i, 0, s-1, setSlot( call message argAt(0) code, at(i) ); doMessage( call message argAt(1) ) ) )\n" +"foreach3_ := method( s := size; for( i, 0, s-1, setSlot( call message argAt(0) code, i ); setSlot( call message argAt(1) code, at(i) ); doMessage( call message argAt(2) ) ) )\n" +"foreach := method( if ( call message argCount == 1, self getSlot(\"foreach1_\") performOn( call target, call sender, call message, call slotContext ), if ( call message argCount == 2, self getSlot(\"foreach2_\") performOn( call target, call sender, call message, call slotContext ), self getSlot(\"foreach3_\") performOn( call target, call sender, call message, call slotContext ) ) ) )\n" +; + +} Added: private/z-man/clio/std_container.hpp =================================================================== --- private/z-man/clio/std_container.hpp (rev 0) +++ private/z-man/clio/std_container.hpp 2008-02-20 20:54:49 UTC (rev 8021) @@ -0,0 +1,93 @@ +#ifndef CLIO_STD_CONTAINER_H +#define CLIO_STD_CONTAIENR_H + +#include "proxy.hpp" +#include "macros.hpp" + +#include <vector> +#include <map> +#include <set> +#include <deque> + +namespace clio +{ +// proxy for std::vector, behaving as closely as possible like Io lists +template< class Container > class VectorProxy: public Proxy< Container > +{ +public: + typedef typename Container::size_type size_type; + typedef typename Container::value_type value_type; + typedef typename Container::reference reference; + typedef typename Container::const_reference const_reference; + + explicit VectorProxy( Container & container ) + : Proxy< Container >( container ) + {} + + explicit VectorProxy( Container * container ) + : Proxy< Container >( container ) + {} + + void CheckIndex( size_type index ) const + { + if ( index < 0 || index >= size() ) + { + throw Exception( "index out of bounds" ); + } + } + + const_reference at( size_type index ) const + { + CheckIndex( index ); + return this->Get()[index]; + } + + void append( const_reference value ) + { + this->Get().push_back(value); + } + + size_type size() const + { + return this->Get().size(); + } + + void atPut( size_type index, const_reference value ) + { + CheckIndex( index ); + this->Get()[ index ] = value; + } + + value_type pop() + { + CheckIndex(0); + value_type ret = this->Get().back(); + this->Get().pop_back(); + return ret; + } +}; + +extern char const * vectorProxyCode; + +} + +CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::VectorProxy, (1,(class)), false ); + +CLIO_TEMPLATE_CLASS( clio::VectorProxy, (1,(class))) +{ + typedef T1 CONTAINER; + CLIO_METHOD( append ); + CLIO_METHOD( size ); + CLIO_METHOD( at ); + CLIO_METHOD( atPut ); + CLIO_METHOD( pop ); + + CLIO_INJECTCODE( vectorProxyCode ); + // CLIO_METHOD(); +} + +CLIO_TEMPLATE_CLASS( std::vector, (1,(class))) +{ +} + +#endif Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-20 20:47:26 UTC (rev 8020) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-20 20:54:49 UTC (rev 8021) @@ -1,6 +1,6 @@ #include "helptest.hpp" #include "typetraits.hpp" -#include "ichained.hpp" +#include "std_container.hpp" // **************************** // std:: containers @@ -26,201 +26,17 @@ std::vector< int > ints_; }; -namespace clio +class B: public clio::IChained { - -// proxy objects. ORIGINAL should be the raw type of the wrapped object. -template< class ORIGINAL > -class Proxy: public IChained -{ public: - // returns the original object - ORIGINAL & Get() const - { - if ( !original_ ) - { - std::ostringstream err; - err << "Proxy for " << GetTypeName< ORIGINAL >() << - " is broken"; - throw Exception( "Broken Proxy", err.str() ); - } - - return *original_; - } - - // creates proxy for original - explicit Proxy( ORIGINAL * original ) - : original_( original ) - { - assert( original ); - } - - // creates proxy for original - explicit Proxy( ORIGINAL & original ) - : original_( &original ) - { - } - - ~Proxy() - { - } -protected: - virtual void OnSetObjectWrapper() - { - if ( GetObjectWrapper() && original_ ) - { - Register( original_ ); - } - } - - // called when the object this thing is chained to gets destroyed - virtual void OnBreak() - { - // remove reference to original - original_ = 0; - - // delegate - IChained::OnBreak(); - } -private: -private: - // poiter to the original wrapped object - ORIGINAL * original_; + B( A & ){} }; -// proxy for std::vector, behaving as closely as possible like Io lists -template< class Container > class VectorProxy: public Proxy< Container > -{ -public: - typedef typename Container::size_type size_type; - typedef typename Container::value_type value_type; - typedef typename Container::reference reference; - typedef typename Container::const_reference const_reference; - - explicit VectorProxy( Container & container ) - : Proxy< Container >( container ) - {} - - explicit VectorProxy( Container * container ) - : Proxy< Container >( container ) - {} - - void CheckIndex( size_type index ) const - { - if ( index < 0 || index >= size() ) - { - throw Exception( "index out of bounds" ); - } - } - - const_reference at( size_type index ) const - { - CheckIndex( index ); - return this->Get()[index]; - } - - void append( const_reference value ) - { - this->Get().push_back(value); - } - - size_type size() const - { - return this->Get().size(); - } - - void atPut( size_type index, const_reference value ) - { - CheckIndex( index ); - this->Get()[ index ] = value; - } - - value_type pop() - { - CheckIndex(0); - value_type ret = this->Get().back(); - this->Get().pop_back(); - return ret; - } -}; -} - -CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::VectorProxy, (1,(class)), false ); - -char const * vectorProxyCode = -"foreach1_ := method( s := size; for( i, 0, s-1, at(i) doMessage( call message argAt(0) ) ) )\n" -"foreach2_ := method( s := size; for( i, 0, s-1, setSlot( call message argAt(0) code, at(i) ); doMessage( call message argAt(1) ) ) )\n" -"foreach3_ := method( s := size; for( i, 0, s-1, setSlot( call message argAt(0) code, i ); setSlot( call message argAt(1) code, at(i) ); doMessage( call message argAt(2) ) ) )\n" -"foreach := method( if ( call message argCount == 1, self getSlot(\"foreach1_\") performOn( call target, call sender, call message, call slotContext ), if ( call message argCount == 2, self getSlot(\"foreach2_\") performOn( call target, call sender, call message, call slotContext ), self getSlot(\"foreach3_\") performOn( call target, call sender, call message, call slotContext ) ) ) )\n" -; - -CLIO_TEMPLATE_CLASS( clio::VectorProxy, (1,(class))) -{ - typedef T1 CONTAINER; - CLIO_METHOD( append ); - CLIO_METHOD( size ); - CLIO_METHOD( at ); - CLIO_METHOD( atPut ); - CLIO_METHOD( pop ); - - CLIO_INJECTCODE( vectorProxyCode ); - // CLIO_METHOD(); -} - namespace clio { - namespace dataconversion { -// Data conversion via proxy classes. The proxy class is supposed to have this -// public interface: -// class PROXY{ -// PROXY( ORIGINAL ); -// ORIGINAL Get(); -// }; -// and is supposed to be derived from IChained. - -template< class ORIGINAL, class PROXY > class DataConverterProxy: public DataConverterDefs< ORIGINAL > -{ -public: - typedef DataConverterDefs< ORIGINAL > Base; - - typedef typename Base::TArg TArg; - typedef typename Base::Converted Converted; - - typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< PROXY > > IMPL; - - static Converted FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) - { - PROXY & proxy = IMPL::FromIo( from, call, thrower ); - return proxy.Get(); - } - - static void CheckType( IChained const & ){} - - static inline IoObject * ToIo( IoState * state, TArg from, DataConversionCall const & call ) - { - // create - typename IMPL::TArg arg = *(new PROXY(from)); - - // READ BELOW IF THIS LINE GIVES AN ERROR - DataConverterProxy::CheckType( arg ); - // If the above line gives an error, that means you tried to register - // a proxy object for data conversion that is not derived from clio::IChained. - // Let all your proxies inherit from clio::IChained to correct this error. It's - // best if you let them inherit from clio::Proxy< ORIGINAL >. - - return IMPL::ToIo( state, arg, call ); - } -}; - -class B: public clio::IChained -{ -public: - B( A & ){} -}; - template<> struct DataConverterManager< A >: public DataConverterManager< B > { }; @@ -244,10 +60,6 @@ } -CLIO_TEMPLATE_CLASS( std::vector, (1,(class))) -{ -} - CLIO_CLASS( TestVector ) { CLIO_METHOD( GetA ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 00:05:51
|
Revision: 8025 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8025&view=rev Author: z-man Date: 2008-02-20 16:05:53 -0800 (Wed, 20 Feb 2008) Log Message: ----------- Yay, std::vector parameters wrapped in all variants. Modified Paths: -------------- private/z-man/clio/proxy.hpp private/z-man/clio/std_container.cpp private/z-man/clio/std_container.hpp private/z-man/clio/tests/container.test/output.txt private/z-man/clio/tests/container.test/test.cpp private/z-man/clio/tests/container.test/test.io private/z-man/clio/typetraits.hpp Modified: private/z-man/clio/proxy.hpp =================================================================== --- private/z-man/clio/proxy.hpp 2008-02-20 22:21:06 UTC (rev 8024) +++ private/z-man/clio/proxy.hpp 2008-02-21 00:05:53 UTC (rev 8025) @@ -16,6 +16,7 @@ { public: typedef T ORIGINAL; + typedef WrapperBase GETTER; // returns the original object ORIGINAL & Get() const @@ -111,9 +112,15 @@ // Data conversion via proxy classes. The proxy class is supposed to have this // public interface: // class PROXY{ +// TYPEDEF SOMEOTHERCLASS GETTER; // PROXY( ORIGINAL ); +// }; +// where SOMEOTHERCLASS has the form +// class SOMEOTHERCLASS{ // ORIGINAL Get(); // }; + +// // and is supposed to be derived from IChained. Not surprisingly, Wrapper<> and Proxy<> // apply :) @@ -125,11 +132,12 @@ typedef typename Base::TArg TArg; typedef typename Base::Converted Converted; - typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< PROXY > > IMPL; + typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< typename PROXY::GETTER > > IMPL_GET; + typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< PROXY > > IMPL_SET; static Converted FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) { - PROXY & proxy = IMPL::FromIo( from, call, thrower ); + PROXY & proxy = IMPL_GET::FromIo( from, call, thrower ); return proxy.Get(); } @@ -138,7 +146,7 @@ static inline IoObject * ToIo( IoState * state, TArg from, DataConversionCall const & call ) { // create - typename IMPL::TArg arg = *(new PROXY(from)); + typename IMPL_SET::TArg arg = *(new PROXY(from)); // READ BELOW IF THIS LINE GIVES AN ERROR DataConverterProxy::CheckType( arg ); @@ -147,7 +155,7 @@ // Let all your proxies inherit from clio::IChained to correct this error. It's // best if you let them inherit from clio::Proxy< ORIGINAL >. - return IMPL::ToIo( state, arg, call ); + return IMPL_SET::ToIo( state, arg, call ); } }; @@ -173,6 +181,16 @@ CLIO_CLASS_BASE( clio::WrapperBase< T1 > ); } -#define CLIO_CONVERTAS_WRAPPER +#define CLIO_CONVERTAS_PROXY( CLASS, PROXY ) namespace clio{ namespace dataconversion{ \ +template<> struct DataConverterManager< CLASS >: public DataConverterProxy< CLASS, PROXY >{}; \ +}} +#define CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, CONST, INDIRECTION, SIGNATURE, PROXY ) namespace clio{ namespace dataconversion{ \ +CLIO_TEMPLATE_STATEMENT_FORCE( SIGNATURE ) \ +struct DataConverterManager< CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST INDIRECTION > : \ +public DataConverterProxy< \ +CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST INDIRECTION, \ +PROXY< CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST > >{}; \ +}} + #endif Modified: private/z-man/clio/std_container.cpp =================================================================== --- private/z-man/clio/std_container.cpp 2008-02-20 22:21:06 UTC (rev 8024) +++ private/z-man/clio/std_container.cpp 2008-02-21 00:05:53 UTC (rev 8025) @@ -3,11 +3,13 @@ namespace clio { -char const * vectorProxyCode = +char const * vectorProxyCodeConst = "foreach1_ := method( s := size; for( i, 0, s-1, at(i) doMessage( call message argAt(0) ) ) )\n" "foreach2_ := method( s := size; for( i, 0, s-1, setSlot( call message argAt(0) code, at(i) ); doMessage( call message argAt(1) ) ) )\n" "foreach3_ := method( s := size; for( i, 0, s-1, setSlot( call message argAt(0) code, i ); setSlot( call message argAt(1) code, at(i) ); doMessage( call message argAt(2) ) ) )\n" "foreach := method( if ( call message argCount == 1, self getSlot(\"foreach1_\") performOn( call target, call sender, call message, call slotContext ), if ( call message argCount == 2, self getSlot(\"foreach2_\") performOn( call target, call sender, call message, call slotContext ), self getSlot(\"foreach3_\") performOn( call target, call sender, call message, call slotContext ) ) ) )\n" ; +char const * vectorProxyCode = ""; + } Modified: private/z-man/clio/std_container.hpp =================================================================== --- private/z-man/clio/std_container.hpp 2008-02-20 22:21:06 UTC (rev 8024) +++ private/z-man/clio/std_container.hpp 2008-02-21 00:05:53 UTC (rev 8025) @@ -12,7 +12,7 @@ namespace clio { // proxy for std::vector, behaving as closely as possible like Io lists -template< class Container > class VectorProxy: public Proxy< Container > +template< class Container > class ConstVectorProxy: public Proxy< Container > { public: typedef typename Container::size_type size_type; @@ -20,11 +20,11 @@ typedef typename Container::reference reference; typedef typename Container::const_reference const_reference; - explicit VectorProxy( Container & container ) + explicit ConstVectorProxy( Container & container ) : Proxy< Container >( container ) {} - explicit VectorProxy( Container * container ) + explicit ConstVectorProxy( Container * container ) : Proxy< Container >( container ) {} @@ -42,25 +42,43 @@ return this->Get()[index]; } - void append( const_reference value ) + size_type size() const { - this->Get().push_back(value); + return this->Get().size(); } +}; - size_type size() const +// proxy for std::vector, behaving as closely as possible like Io lists +template< class Container > class VectorProxy: public ConstVectorProxy< Container > +{ +public: + typedef typename Container::size_type size_type; + typedef typename Container::value_type value_type; + typedef typename Container::reference reference; + typedef typename Container::const_reference const_reference; + + explicit VectorProxy( Container & container ) + : ConstVectorProxy< Container >( container ) + {} + + explicit VectorProxy( Container * container ) + : ConstVectorProxy< Container >( container ) + {} + + void append( const_reference value ) { - return this->Get().size(); + this->Get().push_back(value); } void atPut( size_type index, const_reference value ) { - CheckIndex( index ); + this->CheckIndex( index ); this->Get()[ index ] = value; } value_type pop() { - CheckIndex(0); + this->CheckIndex(0); value_type ret = this->Get().back(); this->Get().pop_back(); return ret; @@ -68,17 +86,30 @@ }; extern char const * vectorProxyCode; +extern char const * vectorProxyCodeConst; } -CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::VectorProxy, (1,(class)), false ); +CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::ConstVectorProxy, (1,(class)), false ); +CLIO_TEMPLATE_CLASS( clio::ConstVectorProxy, (1,(class))) +{ + CLIO_CLASS_BASE( clio::Proxy<T1> ); + + typedef T1 CONTAINER; + CLIO_METHOD( size ); + CLIO_METHOD( at ); + + CLIO_INJECTCODE( vectorProxyCodeConst ); + // CLIO_METHOD(); +} + CLIO_TEMPLATE_CLASS( clio::VectorProxy, (1,(class))) { + CLIO_CLASS_BASE( clio::ConstVectorProxy<T1> ); + typedef T1 CONTAINER; CLIO_METHOD( append ); - CLIO_METHOD( size ); - CLIO_METHOD( at ); CLIO_METHOD( atPut ); CLIO_METHOD( pop ); @@ -90,4 +121,10 @@ { } +CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector, , , (2,(class,class)), VectorProxy ); +CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector, , &, (2,(class,class)), VectorProxy ); +CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector,const, &, (2,(class,class)), ConstVectorProxy ); +CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector, , *, (2,(class,class)), VectorProxy ); +CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector,const, *, (2,(class,class)), ConstVectorProxy ); + #endif Modified: private/z-man/clio/tests/container.test/output.txt =================================================================== --- private/z-man/clio/tests/container.test/output.txt 2008-02-20 22:21:06 UTC (rev 8024) +++ private/z-man/clio/tests/container.test/output.txt 2008-02-21 00:05:53 UTC (rev 8025) @@ -1,5 +1,5 @@ <<<< x := TestVector clone -<<<< ints := x getInts +<<<< ints := x accessInts <<<< ints append(1) <<<< x getInts <<<< ints append(2) @@ -25,6 +25,11 @@ 2 3 +<<<< x getInts foreach(println) +1 +2 +3 + <<<< ints pop println 3 <<<< ints pop println Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-20 22:21:06 UTC (rev 8024) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-21 00:05:53 UTC (rev 8025) @@ -18,10 +18,25 @@ return a; }; - std::vector< int > & GetInts() + std::vector< int > & AccessInts() { return ints_; } + + std::vector< int > const & GetInts() + { + return ints_; + } + + std::vector< int > * AccessIntsPtr() + { + return &ints_; + } + + std::vector< int > const * GetIntsPtr() + { + return &ints_; + } private: std::vector< int > ints_; }; @@ -32,11 +47,14 @@ B( A & ){} }; +CLIO_CONVERTAS_PROXY( A &, Proxy<A> ); + namespace clio { namespace dataconversion { + template<> struct DataConverterManager< A >: public DataConverterManager< B > { }; @@ -45,17 +63,6 @@ { }; -template<> struct DataConverterManager< A & >: public DataConverterProxy< A &, Proxy<A> > -{ -}; - -template< class T > -struct DataConverterManager< std::vector<T> & > - : public DataConverterProxy< std::vector<T> &, - VectorProxy< std::vector<T> > > -{ -}; - } } @@ -64,6 +71,9 @@ { CLIO_METHOD( GetA ); CLIO_METHOD( GetInts ); + CLIO_METHOD( AccessInts ); + CLIO_METHOD( GetIntsPtr ); + CLIO_METHOD( AccessIntsPtr ); } void Test() Modified: private/z-man/clio/tests/container.test/test.io =================================================================== --- private/z-man/clio/tests/container.test/test.io 2008-02-20 22:21:06 UTC (rev 8024) +++ private/z-man/clio/tests/container.test/test.io 2008-02-21 00:05:53 UTC (rev 8025) @@ -1,5 +1,5 @@ x := TestVector clone -ints := x getInts +ints := x accessInts ints append(1) x getInts ints append(2) @@ -13,5 +13,7 @@ i2 append(3) ints foreach(println) +x getInts foreach(println) + ints pop println ints pop println Modified: private/z-man/clio/typetraits.hpp =================================================================== --- private/z-man/clio/typetraits.hpp 2008-02-20 22:21:06 UTC (rev 8024) +++ private/z-man/clio/typetraits.hpp 2008-02-21 00:05:53 UTC (rev 8025) @@ -61,6 +61,12 @@ // typedef T * Pointer; }; +// removes pointer and reference +template< class T > struct ReoveIndirection +{ + typedef typename TestPointer< typename TestReference< T >::NoReference >::NoPointer Direct; +}; + /* template< class T > struct TestPointer< T & > { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 01:47:47
|
Revision: 8026 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8026&view=rev Author: z-man Date: 2008-02-20 17:47:44 -0800 (Wed, 20 Feb 2008) Log Message: ----------- Creation and passing in of std::vector objects now works, too. Modified Paths: -------------- private/z-man/clio/proxy.hpp private/z-man/clio/std_container.hpp private/z-man/clio/tests/container.test/output.txt private/z-man/clio/tests/container.test/test.cpp private/z-man/clio/tests/container.test/test.io Modified: private/z-man/clio/proxy.hpp =================================================================== --- private/z-man/clio/proxy.hpp 2008-02-21 00:05:53 UTC (rev 8025) +++ private/z-man/clio/proxy.hpp 2008-02-21 01:47:44 UTC (rev 8026) @@ -12,22 +12,66 @@ // Wrapper objects. T should be the raw type of the wrapped object. template< class T > -class WrapperBase: public IChained +class WrapperBaseConst: public WrapperBaseConst< const T > { public: typedef T ORIGINAL; - typedef WrapperBase GETTER; + typedef WrapperBaseConst GETTER; + typedef WrapperBaseConst< const T > BASE; // returns the original object - ORIGINAL & Get() const + ORIGINAL & Get() { return DoGet(); } private: // returns the original object - virtual ORIGINAL & DoGet() const = 0; + virtual ORIGINAL & DoGet() = 0; }; +// Wrapper objects. T should be the raw type of the wrapped object. +template< class T > +class WrapperBaseConst< const T >: public IChained +{ +public: + typedef T ORIGINAL; + typedef WrapperBaseConst GETTER; + typedef IChained BASE; + + // returns the original object + ORIGINAL const & Get() const + { + return DoGet(); + } +private: + // returns the original object + virtual ORIGINAL const & DoGet() const = 0; +}; + +// Wrapper objects. T should be the raw type of the wrapped object. +template< class T > +class WrapperBase: public WrapperBaseConst< T > +{ +public: + typedef T ORIGINAL; + + // returns the original object + ORIGINAL const & Get() const + { + return DoGet(); + } + + // returns the original object + ORIGINAL & Get() + { + return DoGet(); + } +private: + // returns the original object + virtual ORIGINAL const & DoGet() const = 0; + virtual ORIGINAL & DoGet() = 0; +}; + // Proxy objects. ORIGINAL should be the raw type of the wrapped object, the template< class ORIGINAL > class Proxy: public WrapperBase< ORIGINAL > @@ -70,7 +114,7 @@ } private: // returns the original object - ORIGINAL & DoGet() const + ORIGINAL & DoGetBase() const { if ( !original_ ) { @@ -83,6 +127,17 @@ return *original_; } + // returns the original object + ORIGINAL const & DoGet() const + { + return DoGetBase(); + } + + ORIGINAL & DoGet() + { + return DoGetBase(); + } + // pointer to the original wrapped object ORIGINAL * original_; }; @@ -98,10 +153,26 @@ { } + Wrapper() + { + } + virtual ~Wrapper() { } private: + // returns the original object + ORIGINAL const & DoGet() const + { + return wrapped_; + } + + // returns the original object + ORIGINAL & DoGet() + { + return wrapped_; + } + // copy of the original wrapped object ORIGINAL wrapped_; }; @@ -115,9 +186,10 @@ // TYPEDEF SOMEOTHERCLASS GETTER; // PROXY( ORIGINAL ); // }; -// where SOMEOTHERCLASS has the form +// where SOMEOTHERCLASS is a base class of PROXY of the form // class SOMEOTHERCLASS{ -// ORIGINAL Get(); +// ORIGINAL const & Get(); +// ORIGINAL & Get(); // }; // @@ -127,17 +199,19 @@ template< class ORIGINAL, class PROXY > class DataConverterProxy: public DataConverterDefs< ORIGINAL > { public: + typedef typename PROXY::GETTER GETTER; typedef DataConverterDefs< ORIGINAL > Base; + typedef DataConverterDefs< typename GETTER::ORIGINAL > Base2; typedef typename Base::TArg TArg; typedef typename Base::Converted Converted; - - typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< typename PROXY::GETTER > > IMPL_GET; + + typedef DataConverterReference< GETTER &, DataConverterPointerImplementation< GETTER > > IMPL_GET; typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< PROXY > > IMPL_SET; static Converted FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) { - PROXY & proxy = IMPL_GET::FromIo( from, call, thrower ); + GETTER & proxy = IMPL_GET::FromIo( from, call, thrower ); return proxy.Get(); } @@ -166,10 +240,21 @@ #include "typetraits.hpp" #include "macros.hpp" +CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::WrapperBaseConst, (1,(class)), false ); +CLIO_TEMPLATE_SET_ABSTRACT( clio::WrapperBaseConst, (1,(class)), true ); +CLIO_TEMPLATE_CLASS( clio::WrapperBaseConst, (1,(class)) ) +{ + typedef typename clio::WrapperBaseConst<T1>::BASE BASE; + + CLIO_CLASS_BASE( BASE ); +} + CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::WrapperBase, (1,(class)), false ); CLIO_TEMPLATE_SET_ABSTRACT( clio::WrapperBase, (1,(class)), true ); CLIO_TEMPLATE_CLASS( clio::WrapperBase, (1,(class)) ) -{} +{ + CLIO_CLASS_BASE( WrapperBaseConst<T1> ); +} CLIO_TEMPLATE_CLASS( clio::Proxy, (1,(class)) ) { @@ -182,7 +267,7 @@ } #define CLIO_CONVERTAS_PROXY( CLASS, PROXY ) namespace clio{ namespace dataconversion{ \ -template<> struct DataConverterManager< CLASS >: public DataConverterProxy< CLASS, PROXY >{}; \ +template<> struct DataConverterManager< CLASS >: public DataConverterProxy< CLASS, Proxy< PROXY > >{}; \ }} #define CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, CONST, INDIRECTION, SIGNATURE, PROXY ) namespace clio{ namespace dataconversion{ \ @@ -190,7 +275,7 @@ struct DataConverterManager< CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST INDIRECTION > : \ public DataConverterProxy< \ CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST INDIRECTION, \ -PROXY< CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST > >{}; \ +PROXY< Proxy< CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST > > >{}; \ }} #endif Modified: private/z-man/clio/std_container.hpp =================================================================== --- private/z-man/clio/std_container.hpp 2008-02-21 00:05:53 UTC (rev 8025) +++ private/z-man/clio/std_container.hpp 2008-02-21 01:47:44 UTC (rev 8026) @@ -3,6 +3,7 @@ #include "proxy.hpp" #include "macros.hpp" +#include "gcpointer.hpp" #include <vector> #include <map> @@ -11,23 +12,30 @@ namespace clio { +template< class T > class VectorWrapper; + // proxy for std::vector, behaving as closely as possible like Io lists -template< class Container > class ConstVectorProxy: public Proxy< Container > +template< class BASE > class ConstVectorProxy: public BASE { public: + typedef typename BASE::ORIGINAL Container; + typedef typename Container::size_type size_type; typedef typename Container::value_type value_type; typedef typename Container::reference reference; typedef typename Container::const_reference const_reference; explicit ConstVectorProxy( Container & container ) - : Proxy< Container >( container ) + : BASE( container ) {} explicit ConstVectorProxy( Container * container ) - : Proxy< Container >( container ) + : BASE( container ) {} + ConstVectorProxy() + {} + void CheckIndex( size_type index ) const { if ( index < 0 || index >= size() ) @@ -46,25 +54,34 @@ { return this->Get().size(); } + + typedef VectorWrapper<value_type> WRAPPER; + + WRAPPER * clone() const; }; // proxy for std::vector, behaving as closely as possible like Io lists -template< class Container > class VectorProxy: public ConstVectorProxy< Container > +template< class BASE > class VectorProxy: public ConstVectorProxy< BASE > { public: + typedef typename BASE::ORIGINAL Container; + typedef typename Container::size_type size_type; typedef typename Container::value_type value_type; typedef typename Container::reference reference; typedef typename Container::const_reference const_reference; explicit VectorProxy( Container & container ) - : ConstVectorProxy< Container >( container ) + : ConstVectorProxy< BASE >( container ) {} explicit VectorProxy( Container * container ) - : ConstVectorProxy< Container >( container ) + : ConstVectorProxy< BASE >( container ) {} + VectorProxy() + {} + void append( const_reference value ) { this->Get().push_back(value); @@ -85,6 +102,43 @@ } }; +template< class T > class VectorWrapper: public VectorProxy< Wrapper< std::vector< T > > > +{ +public: + typedef VectorProxy< Wrapper< std::vector< T > > > BASE; + + typedef typename BASE::Container Container; + + VectorWrapper( VectorWrapper const & other ) + { + Get() = other.Get(); + } + + explicit VectorWrapper( Container const & container ) + { + Get() = container; + } + + explicit VectorWrapper( Container const * container ) + { + if ( !container ) + { + throw Exception( "Expected container, got nil" ); + } + Get() = *container; + } + + VectorWrapper() + {} +}; + + +template< class BASE > +typename ConstVectorProxy<BASE>::WRAPPER * ConstVectorProxy<BASE>::clone() const +{ + return new WRAPPER( Get() ); +} + extern char const * vectorProxyCode; extern char const * vectorProxyCodeConst; @@ -94,11 +148,12 @@ CLIO_TEMPLATE_CLASS( clio::ConstVectorProxy, (1,(class))) { - CLIO_CLASS_BASE( clio::Proxy<T1> ); + CLIO_CLASS_BASE( T1 ); - typedef T1 CONTAINER; - CLIO_METHOD( size ); - CLIO_METHOD( at ); + CLIO_METHOD( size ).NonBreaking();; + CLIO_METHOD( at ).NonBreaking(); + + CLIO_METHOD( clone ).TransferOwnership(); CLIO_INJECTCODE( vectorProxyCodeConst ); // CLIO_METHOD(); @@ -108,7 +163,6 @@ { CLIO_CLASS_BASE( clio::ConstVectorProxy<T1> ); - typedef T1 CONTAINER; CLIO_METHOD( append ); CLIO_METHOD( atPut ); CLIO_METHOD( pop ); @@ -117,10 +171,17 @@ // CLIO_METHOD(); } -CLIO_TEMPLATE_CLASS( std::vector, (1,(class))) +CLIO_TEMPLATE_CLASS_EX( std::vector, (1,(class)), "RawVector" ) { } +CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::VectorWrapper, (1,(class)), true ); +CLIO_TEMPLATE_CLASS_EX( clio::VectorWrapper, (1,(class)), "StdVector" ) +{ + CLIO_CLASS_BASE( clio::VectorProxy< Wrapper< std::vector<T1> > > ); +} +CLIO_TEMPLATE_CLASS_MASTER_EX( clio::VectorWrapper, (1,(class)), (1,(clio::IoObjectPointer) ), "StdVector", "With" ); + CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector, , , (2,(class,class)), VectorProxy ); CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector, , &, (2,(class,class)), VectorProxy ); CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector,const, &, (2,(class,class)), ConstVectorProxy ); Modified: private/z-man/clio/tests/container.test/output.txt =================================================================== --- private/z-man/clio/tests/container.test/output.txt 2008-02-21 00:05:53 UTC (rev 8025) +++ private/z-man/clio/tests/container.test/output.txt 2008-02-21 01:47:44 UTC (rev 8026) @@ -35,3 +35,8 @@ <<<< ints pop println 2 +<<<< x getInts foreach(println) +1 +<<<< x setInts( StdVector With(Number) clone ) +<<<< x getInts foreach(println) + Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-21 00:05:53 UTC (rev 8025) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-21 01:47:44 UTC (rev 8026) @@ -28,6 +28,16 @@ return ints_; } + void SetInts( std::vector< int > const & arg ) + { + ints_ = arg; + } + + void SetInts2( std::vector< int > & arg ) + { + ints_ = arg; + } + std::vector< int > * AccessIntsPtr() { return &ints_; @@ -47,7 +57,7 @@ B( A & ){} }; -CLIO_CONVERTAS_PROXY( A &, Proxy<A> ); +CLIO_CONVERTAS_PROXY( A &, A ); namespace clio { @@ -71,6 +81,8 @@ { CLIO_METHOD( GetA ); CLIO_METHOD( GetInts ); + CLIO_METHOD( SetInts ); + CLIO_METHOD( SetInts2 ); CLIO_METHOD( AccessInts ); CLIO_METHOD( GetIntsPtr ); CLIO_METHOD( AccessIntsPtr ); Modified: private/z-man/clio/tests/container.test/test.io =================================================================== --- private/z-man/clio/tests/container.test/test.io 2008-02-21 00:05:53 UTC (rev 8025) +++ private/z-man/clio/tests/container.test/test.io 2008-02-21 01:47:44 UTC (rev 8026) @@ -17,3 +17,7 @@ ints pop println ints pop println + +x getInts foreach(println) +x setInts( StdVector With(Number) clone ) +x getInts foreach(println) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 02:04:45
|
Revision: 8027 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8027&view=rev Author: z-man Date: 2008-02-20 17:58:23 -0800 (Wed, 20 Feb 2008) Log Message: ----------- GCC 4.1 compatibility (ok,ok, standard compliance) Modified Paths: -------------- private/z-man/clio/proxy.hpp private/z-man/clio/std_container.hpp Modified: private/z-man/clio/proxy.hpp =================================================================== --- private/z-man/clio/proxy.hpp 2008-02-21 01:47:44 UTC (rev 8026) +++ private/z-man/clio/proxy.hpp 2008-02-21 01:58:23 UTC (rev 8027) @@ -97,7 +97,7 @@ // called when the object is linked to its wrapper virtual void OnSetObjectWrapper() { - if ( GetObjectWrapper() && original_ ) + if ( this->GetObjectWrapper() && original_ ) { Register( original_ ); } @@ -268,7 +268,7 @@ #define CLIO_CONVERTAS_PROXY( CLASS, PROXY ) namespace clio{ namespace dataconversion{ \ template<> struct DataConverterManager< CLASS >: public DataConverterProxy< CLASS, Proxy< PROXY > >{}; \ -}} +}}CLIO_FORCESEMICOLON(proxy1) #define CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, CONST, INDIRECTION, SIGNATURE, PROXY ) namespace clio{ namespace dataconversion{ \ CLIO_TEMPLATE_STATEMENT_FORCE( SIGNATURE ) \ @@ -276,6 +276,6 @@ public DataConverterProxy< \ CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST INDIRECTION, \ PROXY< Proxy< CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST > > >{}; \ -}} +}}CLIO_FORCESEMICOLON(proxy2) #endif Modified: private/z-man/clio/std_container.hpp =================================================================== --- private/z-man/clio/std_container.hpp 2008-02-21 01:47:44 UTC (rev 8026) +++ private/z-man/clio/std_container.hpp 2008-02-21 01:58:23 UTC (rev 8027) @@ -111,12 +111,12 @@ VectorWrapper( VectorWrapper const & other ) { - Get() = other.Get(); + this->Get() = other.Get(); } explicit VectorWrapper( Container const & container ) { - Get() = container; + this->Get() = container; } explicit VectorWrapper( Container const * container ) @@ -125,7 +125,7 @@ { throw Exception( "Expected container, got nil" ); } - Get() = *container; + this->Get() = *container; } VectorWrapper() @@ -136,7 +136,7 @@ template< class BASE > typename ConstVectorProxy<BASE>::WRAPPER * ConstVectorProxy<BASE>::clone() const { - return new WRAPPER( Get() ); + return new WRAPPER( this->Get() ); } extern char const * vectorProxyCode; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 12:35:44
|
Revision: 8028 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8028&view=rev Author: z-man Date: 2008-02-21 04:35:49 -0800 (Thu, 21 Feb 2008) Log Message: ----------- Better template generation selection: previously, you'd always get std::vector<float> when you wanted std::vector<int>. Now, Int, LongInt, UnsignedInt, ShortInt... can be used as arguments to the With() instantiation functions. Modified Paths: -------------- private/z-man/clio/classname.hpp private/z-man/clio/dataconversion.hpp private/z-man/clio/dataconversion_extended.cpp private/z-man/clio/dataconversion_extended.hpp private/z-man/clio/macros.hpp private/z-man/clio/proxy.hpp private/z-man/clio/std_container.hpp private/z-man/clio/tests/container.test/output.txt private/z-man/clio/tests/container.test/test.cpp private/z-man/clio/tests/container.test/test.io private/z-man/clio/tests/smartpointer.test/output.txt private/z-man/clio/tests/smartpointer.test/test.cpp private/z-man/clio/tests/templates.test/output.txt private/z-man/clio/tests/templates.test/test.cpp Modified: private/z-man/clio/classname.hpp =================================================================== --- private/z-man/clio/classname.hpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/classname.hpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -318,16 +318,18 @@ // or this, for io typenames CLIO_IO_CLASSNAME( std::string, "Sequence" ); -CLIO_IO_CLASSNAME( float, "Number" ); -CLIO_IO_CLASSNAME( double, "Number" ); +//CLIO_IO_CLASSNAME( float, "Number" ); +//CLIO_IO_CLASSNAME( double, "Double" ); +/* #define CLIO_IO_CLASSNAME_NUMBER( CLASS )\ CLIO_IO_CLASSNAME( CLASS, "Number" ); \ CLIO_IO_CLASSNAME( unsigned CLASS, "Number" ) +*/ -CLIO_IO_CLASSNAME_NUMBER( long int ); -CLIO_IO_CLASSNAME_NUMBER( int ); -CLIO_IO_CLASSNAME_NUMBER( short int ); -CLIO_IO_CLASSNAME_NUMBER( char ); +//CLIO_IO_CLASSNAME_NUMBER( long int ); +//CLIO_IO_CLASSNAME_NUMBER( int ); +//CLIO_IO_CLASSNAME_NUMBER( short int ); +//CLIO_IO_CLASSNAME_NUMBER( char ); #endif Modified: private/z-man/clio/dataconversion.hpp =================================================================== --- private/z-man/clio/dataconversion.hpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/dataconversion.hpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -22,6 +22,7 @@ namespace clio { +// template < class PRIMITIVE > class PrimitiveProxy; template< class T > class GCPointer; class IFunctionInfo; Modified: private/z-man/clio/dataconversion_extended.cpp =================================================================== --- private/z-man/clio/dataconversion_extended.cpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/dataconversion_extended.cpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -103,3 +103,20 @@ } } + +#define CLIO_CREATE_PRIMITIVE( INT, NAME ) \ +CLIO_INSTANTIATE_TEMPLATE(clio::PrimitiveProxy,(1,(INT)), NAME ) + +#define CLIO_CREATE_PRIMITIVE_INT( INT, NAME ) \ +CLIO_CREATE_PRIMITIVE( INT, NAME ); \ +CLIO_CREATE_PRIMITIVE( unsigned INT, "Unsigned" NAME ) \ + +CLIO_CREATE_PRIMITIVE_INT( long int, "LongInt" ); +CLIO_CREATE_PRIMITIVE_INT( int, "Int" ); +CLIO_CREATE_PRIMITIVE_INT( short int, "ShortInt" ); +CLIO_CREATE_PRIMITIVE_INT( char, "Char" ); + +CLIO_CREATE_PRIMITIVE( double, "Double" ); +CLIO_CREATE_PRIMITIVE( float, "Float" ); + +// CLIO_INSTANTIATE_TEMPLATE(clio::PrimitiveProxy,(1,(int)),"Int" ); Modified: private/z-man/clio/dataconversion_extended.hpp =================================================================== --- private/z-man/clio/dataconversion_extended.hpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/dataconversion_extended.hpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -138,6 +138,7 @@ namespace clio { + namespace dataconversion { // For example this little beast: it wraps const references to primitives @@ -271,11 +272,18 @@ struct PrimitiveProxyNoMaster{}; } + +template< class T > struct clioPrivate_classToTypeBase< T, true > +{ + typedef dataconversion::PrimitiveProxy<T> Type; +}; + } #define CLIO_INSTANTIATE_PRIMITIVE( INT, NAME ) \ CLIO_CLASSNAME_EX( clio::dataconversion::PrimitiveProxy<const INT>, "Const" NAME, clio::IClassInfo::Name_IoComplete ); \ -CLIO_CLASSNAME_EX( clio::dataconversion::PrimitiveProxy<INT>, NAME, clio::IClassInfo::Name_IoComplete ) +CLIO_CLASSNAME_EX( clio::dataconversion::PrimitiveProxy<INT>, NAME, clio::IClassInfo::Name_IoComplete ); \ +CLIO_IO_CLASSNAME( INT, NAME ) #define CLIO_INSTANTIATE_PRIMITIVE_INT( INT, NAME ) \ CLIO_INSTANTIATE_PRIMITIVE( INT, NAME ); \ Modified: private/z-man/clio/macros.hpp =================================================================== --- private/z-man/clio/macros.hpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/macros.hpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -185,11 +185,22 @@ // For the template instantiation overloads: // converts a type to another type -template< class T > struct clioPrivate_classToType +template< class T, bool primitive > struct clioPrivate_classToTypeBase { +}; + +template< class T > struct clioPrivate_classToTypeBase< T, false > +{ typedef T Type; }; +// For the template instantiation overloads: +// converts a type to another type +template< class T > struct clioPrivate_classToType +{ + typedef typename clioPrivate_classToTypeBase<T, clio::TestPrimitive< T >::IsPrimitive>::Type Type; +}; + // same as classToType template< class T > struct clioPrivate_typenameToType: public clioPrivate_classToType< T >{}; Modified: private/z-man/clio/proxy.hpp =================================================================== --- private/z-man/clio/proxy.hpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/proxy.hpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -278,4 +278,12 @@ PROXY< Proxy< CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST > > >{}; \ }}CLIO_FORCESEMICOLON(proxy2) +// complete convesion of (const) &/* arguments +#define CLIO_CONVERTAS_PROXY_TEMPLATE_COMPLETE( CLASS, SIGNATURE, PROXY ) \ +CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, , , SIGNATURE, PROXY ); \ +CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, ,& , SIGNATURE, PROXY ); \ +CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, const,& , SIGNATURE, Const##PROXY ); \ +CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, ,* , SIGNATURE, PROXY ); \ +CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, const,* , SIGNATURE, Const##PROXY ) + #endif Modified: private/z-man/clio/std_container.hpp =================================================================== --- private/z-man/clio/std_container.hpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/std_container.hpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -6,9 +6,6 @@ #include "gcpointer.hpp" #include <vector> -#include <map> -#include <set> -#include <deque> namespace clio { @@ -141,7 +138,6 @@ extern char const * vectorProxyCode; extern char const * vectorProxyCodeConst; - } CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::ConstVectorProxy, (1,(class)), false ); @@ -156,7 +152,6 @@ CLIO_METHOD( clone ).TransferOwnership(); CLIO_INJECTCODE( vectorProxyCodeConst ); - // CLIO_METHOD(); } CLIO_TEMPLATE_CLASS( clio::VectorProxy, (1,(class))) @@ -168,12 +163,9 @@ CLIO_METHOD( pop ); CLIO_INJECTCODE( vectorProxyCode ); - // CLIO_METHOD(); } -CLIO_TEMPLATE_CLASS_EX( std::vector, (1,(class)), "RawVector" ) -{ -} +CLIO_TEMPLATE_CLASS_EX( std::vector, (1,(class)), "RawVector" ){} CLIO_TEMPLATE_SET_DEFAULTCONSTRUCTOR( clio::VectorWrapper, (1,(class)), true ); CLIO_TEMPLATE_CLASS_EX( clio::VectorWrapper, (1,(class)), "StdVector" ) @@ -182,10 +174,6 @@ } CLIO_TEMPLATE_CLASS_MASTER_EX( clio::VectorWrapper, (1,(class)), (1,(clio::IoObjectPointer) ), "StdVector", "With" ); -CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector, , , (2,(class,class)), VectorProxy ); -CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector, , &, (2,(class,class)), VectorProxy ); -CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector,const, &, (2,(class,class)), ConstVectorProxy ); -CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector, , *, (2,(class,class)), VectorProxy ); -CLIO_CONVERTAS_PROXY_TEMPLATE( std::vector,const, *, (2,(class,class)), ConstVectorProxy ); +CLIO_CONVERTAS_PROXY_TEMPLATE_COMPLETE( std::vector, (2,(class,class)), VectorProxy ); #endif Modified: private/z-man/clio/tests/container.test/output.txt =================================================================== --- private/z-man/clio/tests/container.test/output.txt 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/tests/container.test/output.txt 2008-02-21 12:35:49 UTC (rev 8028) @@ -37,6 +37,7 @@ <<<< x getInts foreach(println) 1 -<<<< x setInts( StdVector With(Number) clone ) +<<<< x setInts( StdVector With(Int) clone append(5) ) <<<< x getInts foreach(println) +5 Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -47,6 +47,11 @@ { return &ints_; } + + std::vector< float > * CreateFloats() + { + return new std::vector< float >(); + } private: std::vector< int > ints_; }; @@ -86,6 +91,7 @@ CLIO_METHOD( AccessInts ); CLIO_METHOD( GetIntsPtr ); CLIO_METHOD( AccessIntsPtr ); + // CLIO_METHOD( CreateFloats ).TransferOwnership(); } void Test() Modified: private/z-man/clio/tests/container.test/test.io =================================================================== --- private/z-man/clio/tests/container.test/test.io 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/tests/container.test/test.io 2008-02-21 12:35:49 UTC (rev 8028) @@ -19,5 +19,5 @@ ints pop println x getInts foreach(println) -x setInts( StdVector With(Number) clone ) +x setInts( StdVector With(Int) clone append(5) ) x getInts foreach(println) Modified: private/z-man/clio/tests/smartpointer.test/output.txt =================================================================== --- private/z-man/clio/tests/smartpointer.test/output.txt 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/tests/smartpointer.test/output.txt 2008-02-21 12:35:49 UTC (rev 8028) @@ -4,36 +4,39 @@ <<<< callGC <<<< callGC <<<< SmartPointerTest setStaticTarget( SmartPointerTest clone ) -SmartPointerTest_0xHEXCODE created. <<<< nextTarget := SmartPointerTest clone -SmartPointerTest_0xHEXCODE created. <<<< y := SmartPointerTest getStaticTarget <<<< y setTarget( y ) <<<< SmartPointerTest setStaticTarget( nextTarget ) Expecting no deletions <<<< callGC +SmartPointerTest_0xHEXCODE created. +SmartPointerTest_0xHEXCODE created. <<<< y setTarget( y ) <<<< x := SmartPointerTest clone -SmartPointerTest_0xHEXCODE created. <<<< x setTarget( SmartPointerTest clone ) -SmartPointerTest_0xHEXCODE created. <<<< x setTarget( SmartPointerTest clone ) -SmartPointerTest_0xHEXCODE created. <<<< x setStaticTarget( SmartPointerTest clone ) -SmartPointerTest_0xHEXCODE created. Expecting only SmartPointerTest 4 to get deleted <<<< callGC +SmartPointerTest_0xHEXCODE created. +SmartPointerTest_0xHEXCODE created. +SmartPointerTest_0xHEXCODE created. +SmartPointerTest_0xHEXCODE created. SmartPointerTest_0xHEXCODE destroyed. +Expecting only SmartPointerTest 5 to get deleted <<<< x setTarget( SmartPointerTest clone ) +<<<< callGC SmartPointerTest_0xHEXCODE created. +SmartPointerTest_0xHEXCODE destroyed. <<<< x setStaticTarget( SmartPointerTest clone ) +Expecting only SmartPointerTest 6 to get deleted +<<<< callGC SmartPointerTest_0xHEXCODE created. -Expecting only SmartPointerTest 5 and 6 to get deleted -<<<< callGC SmartPointerTest_0xHEXCODE destroyed. +Expecting the rest to get deleted SmartPointerTest_0xHEXCODE destroyed. SmartPointerTest_0xHEXCODE destroyed. SmartPointerTest_0xHEXCODE destroyed. SmartPointerTest_0xHEXCODE destroyed. SmartPointerTest_0xHEXCODE destroyed. -SmartPointerTest_0xHEXCODE destroyed. Modified: private/z-man/clio/tests/smartpointer.test/test.cpp =================================================================== --- private/z-man/clio/tests/smartpointer.test/test.cpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/tests/smartpointer.test/test.cpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -4,6 +4,8 @@ // smart pointers // **************************** +std::ostream * out = NULL; + class SmartPointerTest { public: @@ -13,12 +15,12 @@ ++i; index_ = i; - std::cout << "SmartPointerTest_0x" << index_ << " created.\n"; + *out << "SmartPointerTest_0x" << index_ << " created.\n"; } ~SmartPointerTest() { - std::cout << "SmartPointerTest_0x" << index_ << " destroyed.\n"; + *out << "SmartPointerTest_0x" << index_ << " destroyed.\n"; index_ = -1; } @@ -70,6 +72,9 @@ TestString( state, "callGC" ); TestString( state2, "callGC" ); + std::stringstream s1; + out = &s1; + TestString( state, "SmartPointerTest setStaticTarget( SmartPointerTest clone )" ); TestString( state, "nextTarget := SmartPointerTest clone" ); TestString( state2, "y := SmartPointerTest getStaticTarget" ); @@ -77,17 +82,38 @@ TestString( state, "SmartPointerTest setStaticTarget( nextTarget )" ); std::cout << "Expecting no deletions\n"; TestString( state, "callGC" ); + + std::cout << s1.str(); + std::stringstream s2; + out = &s2; + TestString( state2, "y setTarget( y )" ); - TestString( state, "x := SmartPointerTest clone" ); TestString( state, "x setTarget( SmartPointerTest clone )" ); TestString( state, "x setTarget( SmartPointerTest clone )" ); TestString( state, "x setStaticTarget( SmartPointerTest clone )" ); std::cout << "Expecting only SmartPointerTest 4 to get deleted\n"; TestString( state, "callGC" ); + + std::cout << s2.str(); + std::stringstream s3; + out = &s3; + + std::cout << "Expecting only SmartPointerTest 5 to get deleted\n"; TestString( state, "x setTarget( SmartPointerTest clone )" ); + TestString( state, "callGC" ); + + std::cout << s3.str(); + std::stringstream s4; + out = &s4; + TestString( state, "x setStaticTarget( SmartPointerTest clone )" ); - std::cout << "Expecting only SmartPointerTest 5 and 6 to get deleted\n"; + std::cout << "Expecting only SmartPointerTest 6 to get deleted\n"; TestString( state, "callGC" ); + + std::cout << s4.str(); + out = &std::cout; + + std::cout << "Expecting the rest to get deleted\n"; } Modified: private/z-man/clio/tests/templates.test/output.txt =================================================================== --- private/z-man/clio/tests/templates.test/output.txt 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/tests/templates.test/output.txt 2008-02-21 12:35:49 UTC (rev 8028) @@ -41,7 +41,8 @@ <<<< testObject3 create() println nil <<<< TemplateTest With( testObject ) create() println -nil + TemplateTest_0xHEXCODE: + <<<< TemplateTest With( TemplateTest ) create() type println TemplateTest <<<< testObject3 create() println Modified: private/z-man/clio/tests/templates.test/test.cpp =================================================================== --- private/z-man/clio/tests/templates.test/test.cpp 2008-02-21 01:58:23 UTC (rev 8027) +++ private/z-man/clio/tests/templates.test/test.cpp 2008-02-21 12:35:49 UTC (rev 8028) @@ -13,11 +13,20 @@ // templates // **************************** +void f() +{ + int x; + x = 0; +} + template< class T1, class T2, int I1 > class TemplateTestBase { public: int h(){ return I1; } - static T1 Create(){ return T1(); } + static T1 Create(){ + f(); + return T1(); + } }; template< class T > class TemplateTest: public TemplateTestBase< T, T, 2 > This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 14:18:31
|
Revision: 8030 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8030&view=rev Author: z-man Date: 2008-02-21 06:18:36 -0800 (Thu, 21 Feb 2008) Log Message: ----------- Slightly Smarter way to handle ObjectWrapperAwares. Modified Paths: -------------- private/z-man/clio/classinfo.hpp private/z-man/clio/factory.hpp private/z-man/clio/function_single.hpp private/z-man/clio/iclassinfo.cpp private/z-man/clio/iclassinfo.hpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapper.hpp private/z-man/clio/objectwrapperaware.cpp private/z-man/clio/objectwrapperaware.hpp private/z-man/clio/tests/container.test/test.cpp private/z-man/clio/tests/virtual.test/test.cpp Modified: private/z-man/clio/classinfo.hpp =================================================================== --- private/z-man/clio/classinfo.hpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/classinfo.hpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -21,7 +21,7 @@ { template< class T > -class ClassInfo: public IClassInfo, public AwareMaker +class ClassInfo: public IClassInfo { public: // this is a singleton class @@ -112,12 +112,18 @@ return sizeof(T); } - // inform class than an object of it went out of scope - virtual bool OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW + // "dynamic cast" of an object of this class to ObjectWrapperAware + virtual ObjectWrapperAware * DoGetAwareObject( ObjectWrapper & wrapper ) const CLIO_NOTHROW { - return BreakObjectWrapperAware( ExtractObject( wrapper ) ); + return AwareMaker::GetObjectWrapperAware( ExtractObject( wrapper ) ); } + // inform class than an object of it went out of scope + // virtual bool OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW + // { + // return BreakObjectWrapperAware( ExtractObject( wrapper ) ); + // } + ClassInfo() { SetNameGetter( Name_C , classname::ClassNameDefaultGetter< T, Name_C >::Get ); @@ -140,6 +146,7 @@ return (IoStateProtoFunc *)&CreateStatic; } + /* // registers a wrapper with an object virtual void DoMakeWrapperAware( void * object, ObjectWrapper * wrapper ) const CLIO_NOTHROW { @@ -148,6 +155,7 @@ T * realObject = static_cast< T * >( object ); MakeObjectWrapperAware( wrapper, realObject ); } + */ }; template< class DERIVED, class BASE > class StaticCaster: public ICaster Modified: private/z-man/clio/factory.hpp =================================================================== --- private/z-man/clio/factory.hpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/factory.hpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -149,7 +149,7 @@ // create an object virtual T * Create( ObjectWrapper * wrapper ) const { - // if you get an error here, this means you failed to declare T an abstract class using + // if you get an error here, this means you need to declare T an abstract class using // the CLIO_CLASS_ABSTRACT macro. return new T; } @@ -160,7 +160,7 @@ // copy an object virtual T * Clone( ObjectWrapper * wrapper, T const & original ) const { - // if you get an error here, this means you failed to declare T an abstract class using + // if you get an error here, this means you need to declare T an abstract class using // the CLIO_CLASS_ABSTRACT macro. return new T( original ); } @@ -178,7 +178,7 @@ // overriding factory as single factories template<class T, class DERIVED=T> -class OverridingFactoryCreate: public AwareMaker +class OverridingFactoryCreate { public: // create an object @@ -190,14 +190,17 @@ // If you get an error here, the class T (look closely at the error message, it will // tell you what T is) has no default constructor available. Use // CLIO_CLASS_SET_DEFAULTCONSTRUCTOR( T, false ) to make that known. + + // inform the wrapper about the object. This is required because the + // managing IClassInfo object may not be aware of o's full type. + wrapper->SetAwareObject( o ); - MakeObjectWrapperAware( wrapper, o ); return static_cast< T *>( o ); } }; template<class T, class DERIVED=T> -class OverridingFactoryClone: public AwareMaker +class OverridingFactoryClone { public: // copy an object @@ -213,7 +216,10 @@ // CLIO_CLASS_SET_COPYCONSTRUCTOR( T, false ) // to make that known. - MakeObjectWrapperAware( wrapper, o ); + // inform the wrapper about the object. This is required because the + // managing IClassInfo object may not be aware of o's full type. + wrapper->SetAwareObject( o ); + return static_cast< T *>( o ); } }; Modified: private/z-man/clio/function_single.hpp =================================================================== --- private/z-man/clio/function_single.hpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/function_single.hpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -45,7 +45,7 @@ // Constructor wrappers. Constructors are thought of as static member functions without return type // (they aren't, but we don't mind.) template< class TWrap, class TBase CLIO_TYPELIST_ARG > -class ConstructorWrapper< TWrap, TBase, CLIO_TYPELIST_FIXED >: public TWrap, public AwareMaker +class ConstructorWrapper< TWrap, TBase, CLIO_TYPELIST_FIXED >: public TWrap { public: ConstructorWrapper( CLIO_TYPELIST_FUNCARG ) @@ -93,7 +93,7 @@ TBase * w = new TBase(CLIO_FUNCARGS); TBase * wBase = w; IoObject * ret = IClassInfo::CloneOverride( IFunctionInfo::GetCurrentTarget(), wBase ); - MakeObjectWrapperAware( &IClassInfo::GetObjectWrapper( ret ), w ); + // MakeObjectWrapperAware( &IClassInfo::GetObjectWrapper( ret ), w ); return ret; } }; Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/iclassinfo.cpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -485,10 +485,6 @@ else { void * ret = override_.Release(); - - if ( wrapper && ret ) - DoMakeWrapperAware( ret, wrapper ); - return ret; } } Modified: private/z-man/clio/iclassinfo.hpp =================================================================== --- private/z-man/clio/iclassinfo.hpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/iclassinfo.hpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -121,9 +121,15 @@ } // inform class than an object of it went out of scope - bool Break( ObjectWrapper & wrapper ) const + // bool Break( ObjectWrapper & wrapper ) const + // { + // return OnBreak( wrapper ); + // } + + // "dynamic cast" of an object of this class to ObjectWrapperAware + ObjectWrapperAware * GetAwareObject( ObjectWrapper & wrapper ) const { - return OnBreak( wrapper ); + return DoGetAwareObject( wrapper ); } // registers a factory, taking ownership of it @@ -209,8 +215,11 @@ // returns the size of the wrapped object virtual size_t DoGetSize() const CLIO_NOTHROW = 0; + // "dynamic cast" of an object of this class to ObjectWrapperAware + virtual ObjectWrapperAware * DoGetAwareObject( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; + // inform class than an object of it went out of scope - virtual bool OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; + // virtual bool OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; // returns a static function capable of creating an Io object with an object of this class virtual IoStateProtoFunc * DoGetStateProtoFunc() const CLIO_NOTHROW = 0; @@ -219,7 +228,7 @@ ObjectWrapper * CreatePrototype( IoObject * self ) const CLIO_NOTHROW; // registers a wrapper with an object - virtual void DoMakeWrapperAware( void * object, ObjectWrapper * wrapper ) const CLIO_NOTHROW = 0; + // virtual void DoMakeWrapperAware( void * object, ObjectWrapper * wrapper ) const CLIO_NOTHROW = 0; ClassRegistratorSet * registrators_; Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/objectwrapper.cpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -1,5 +1,5 @@ #include "objectwrapper.hpp" -// #include "objectwrapperaware.hpp" +#include "objectwrapperaware.hpp" #include "iclassinfo.hpp" #include "error.hpp" #include "factory.hpp" @@ -170,12 +170,13 @@ // constructor ObjectWrapper::ObjectWrapper( IClassInfo const & classInfo, IoObject * self ) - : object_( 0 ) - , classInfo_( classInfo ) - , self_( self ) - , ownership_( OwnedByIo ) - , chained_( this ) - , chainedTo_( 0 ) +: object_( 0 ) +, awareObject_( 0 ) +, classInfo_( classInfo ) +, self_( self ) +, ownership_( OwnedByIo ) +, chained_( this ) +, chainedTo_( 0 ) { // std::cout << "Wrapper created\n"; @@ -202,6 +203,14 @@ { void * oldObject = object_; + // inform the object + if ( awareObject_ ) + { + awareObject_->SetObjectWrapper( 0 ); + awareObject_->OnIoRelease(); + awareObject_ = 0; + } + if ( GetOwnership() == OwnedByIo ) { // inform other wrappers of the object's death @@ -267,6 +276,7 @@ GetClassInfo().UnregisterWrapper( run->object_, run ); run->Break( true ); run->object_ = 0; + run->awareObject_ = 0; run = run->Next(); } while ( run != this ); @@ -324,11 +334,15 @@ // inform class info if ( GetObject() ) { - if( !GetClassInfo().Break( *this ) && !force ) + if( awareObject_ ) { - // object itself says it is aware of this wrapper, and that it is still alive, - // and will inform us about its demise in time. - return; + awareObject_->Break(); + if ( !force ) + { + // object itself says it is aware of this wrapper, and that it is still alive, + // and will inform us about its demise in time. + return; + } } // if this object is owned by IO (can be in another state), also assume everything @@ -440,6 +454,7 @@ // copy constructor for cloning ObjectWrapper::ObjectWrapper( ObjectWrapper const & other, IoObject * self ) : object_( 0 ) +, awareObject_( 0 ) , classInfo_( other.GetClassInfo() ) , self_( self ) , ownership_( OwnedByIo ) @@ -480,6 +495,18 @@ { // yes? Then we're the main wrapper now. GetClassInfo().RegisterWrapper( object_, this ); + + // inform the object + if ( !awareObject_ ) + { + awareObject_ = GetClassInfo().GetAwareObject( *this ); + } + + if ( awareObject_ ) + { + awareObject_->SetObjectWrapper( this ); + awareObject_->OnIoReference(); + } // update wrapper map { Modified: private/z-man/clio/objectwrapper.hpp =================================================================== --- private/z-man/clio/objectwrapper.hpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/objectwrapper.hpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -17,6 +17,7 @@ class IClassStateInfo; class IFactory; class ObjectWrapper; +class ObjectWrapperAware; // set of chained objects class ChainedSet @@ -110,6 +111,25 @@ return object_; } + // returns the object wrapped by this (if it is derived from ObjectWrapperAware) + ObjectWrapperAware * GetAwareObject() const + { + return awareObject_; + } + + // sets the object wrapped by this (if it is derived from ObjectWrapperAware) + // don't call from client code. + void SetAwareObject( ObjectWrapperAware * object ) + { + assert( !awareObject_ ); + awareObject_ = object; + } + + // dummy variant for dumb templates + void SetAwareObject( void * object ) + { + } + // returns the class info describing the wrapped object inline IClassInfo const & GetClassInfo() const { @@ -142,6 +162,7 @@ ObjectWrapper( ObjectWrapper const & other, IoObject * self ); void * object_; // the wrapped object + ObjectWrapperAware * awareObject_; // the same object, set only if it is really of this type IClassInfo const & classInfo_; // the class info responsible for this object Modified: private/z-man/clio/objectwrapperaware.cpp =================================================================== --- private/z-man/clio/objectwrapperaware.cpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/objectwrapperaware.cpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -37,11 +37,22 @@ { } +// addRef-Hook +void ObjectWrapperAware::OnIoReference() +{ +} + +// release hook +void ObjectWrapperAware::OnIoRelease() +{ +} + // wrapper hook void ObjectWrapperAware::OnBreak() { } +/* // informs an object about the wrapper it was assigned to. void AwareMaker::MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW { @@ -56,5 +67,5 @@ object->OnBreak(); return false; } - +*/ } Modified: private/z-man/clio/objectwrapperaware.hpp =================================================================== --- private/z-man/clio/objectwrapperaware.hpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/objectwrapperaware.hpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -12,13 +12,23 @@ class ObjectWrapperAware { friend class AwareMaker; + friend class ObjectWrapper; public: ObjectWrapperAware(); virtual ~ObjectWrapperAware()=0; // returns the current object wrapper ObjectWrapper * GetObjectWrapper() const CLIO_NOTHROW; + + // call when this object breaks (some referenced bit may have gone out of scope) + inline void Break() + { + return OnBreak(); + } protected: + virtual void OnIoReference(); // hook called when Io takes an interest in this object + virtual void OnIoRelease(); // hook called when Io lost interest in this object. This will not be called from the ~ObjectWrapperAware() path, but from all other paths that release this object + virtual void OnSetObjectWrapper(); // hook called after the object wrapper was set virtual void OnBreak(); // called when a parent object breaks private: @@ -33,6 +43,7 @@ class AwareMaker { protected: +/* // informs an object about the wrapper it was assigned to. static void MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW; @@ -47,6 +58,18 @@ // this second overload makes it possible to call the function from a template without knowing // whether it makes sense or not. If it doesn't make sense, this stub is called instead. inline static bool BreakObjectWrapperAware( void * ){return true;} +*/ +public: + // informs an object about the wrapper it was assigned to. + inline static ObjectWrapperAware * GetObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW + { + return object; + } + + inline static ObjectWrapperAware * GetObjectWrapperAware( void * object ) CLIO_NOTHROW + { + return 0; + } }; } Modified: private/z-man/clio/tests/container.test/test.cpp =================================================================== --- private/z-man/clio/tests/container.test/test.cpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/tests/container.test/test.cpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -91,7 +91,7 @@ CLIO_METHOD( AccessInts ); CLIO_METHOD( GetIntsPtr ); CLIO_METHOD( AccessIntsPtr ); - // CLIO_METHOD( CreateFloats ).TransferOwnership(); + CLIO_METHOD( CreateFloats ).TransferOwnership(); } void Test() Modified: private/z-man/clio/tests/virtual.test/test.cpp =================================================================== --- private/z-man/clio/tests/virtual.test/test.cpp 2008-02-21 12:49:56 UTC (rev 8029) +++ private/z-man/clio/tests/virtual.test/test.cpp 2008-02-21 14:18:36 UTC (rev 8030) @@ -8,6 +8,8 @@ class Extensible { public: + Extensible(){} + virtual ~Extensible(){}; virtual void Function1() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 14:25:10
|
Revision: 8031 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8031&view=rev Author: z-man Date: 2008-02-21 06:25:14 -0800 (Thu, 21 Feb 2008) Log Message: ----------- Even less junk around ObjectWrapperAware. Modified Paths: -------------- private/z-man/clio/classinfo.hpp private/z-man/clio/iclassinfo.hpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapperaware.cpp private/z-man/clio/objectwrapperaware.hpp Modified: private/z-man/clio/classinfo.hpp =================================================================== --- private/z-man/clio/classinfo.hpp 2008-02-21 14:18:36 UTC (rev 8030) +++ private/z-man/clio/classinfo.hpp 2008-02-21 14:25:14 UTC (rev 8031) @@ -112,18 +112,12 @@ return sizeof(T); } - // "dynamic cast" of an object of this class to ObjectWrapperAware - virtual ObjectWrapperAware * DoGetAwareObject( ObjectWrapper & wrapper ) const CLIO_NOTHROW + // checks if wrapper wraps an ObjectWrapperAware object , and if yes, informs it. + virtual void DoSetAwareObject( ObjectWrapper & wrapper ) const CLIO_NOTHROW { - return AwareMaker::GetObjectWrapperAware( ExtractObject( wrapper ) ); + wrapper.SetAwareObject( ExtractObject( wrapper ) ); } - // inform class than an object of it went out of scope - // virtual bool OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW - // { - // return BreakObjectWrapperAware( ExtractObject( wrapper ) ); - // } - ClassInfo() { SetNameGetter( Name_C , classname::ClassNameDefaultGetter< T, Name_C >::Get ); @@ -145,17 +139,6 @@ { return (IoStateProtoFunc *)&CreateStatic; } - - /* - // registers a wrapper with an object - virtual void DoMakeWrapperAware( void * object, ObjectWrapper * wrapper ) const CLIO_NOTHROW - { - assert( object ); - assert( wrapper ); - T * realObject = static_cast< T * >( object ); - MakeObjectWrapperAware( wrapper, realObject ); - } - */ }; template< class DERIVED, class BASE > class StaticCaster: public ICaster Modified: private/z-man/clio/iclassinfo.hpp =================================================================== --- private/z-man/clio/iclassinfo.hpp 2008-02-21 14:18:36 UTC (rev 8030) +++ private/z-man/clio/iclassinfo.hpp 2008-02-21 14:25:14 UTC (rev 8031) @@ -120,16 +120,10 @@ return DoGetSize(); } - // inform class than an object of it went out of scope - // bool Break( ObjectWrapper & wrapper ) const - // { - // return OnBreak( wrapper ); - // } - - // "dynamic cast" of an object of this class to ObjectWrapperAware - ObjectWrapperAware * GetAwareObject( ObjectWrapper & wrapper ) const + // checks if wrapper wraps an ObjectWrapperAware object , and if yes, informs it. + void SetAwareObject( ObjectWrapper & wrapper ) const { - return DoGetAwareObject( wrapper ); + DoSetAwareObject( wrapper ); } // registers a factory, taking ownership of it @@ -215,21 +209,15 @@ // returns the size of the wrapped object virtual size_t DoGetSize() const CLIO_NOTHROW = 0; - // "dynamic cast" of an object of this class to ObjectWrapperAware - virtual ObjectWrapperAware * DoGetAwareObject( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; + // checks if wrapper wraps an ObjectWrapperAware object , and if yes, informs it. + virtual void DoSetAwareObject( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; - // inform class than an object of it went out of scope - // virtual bool OnBreak( ObjectWrapper & wrapper ) const CLIO_NOTHROW = 0; - // returns a static function capable of creating an Io object with an object of this class virtual IoStateProtoFunc * DoGetStateProtoFunc() const CLIO_NOTHROW = 0; // creates a prototype object ObjectWrapper * CreatePrototype( IoObject * self ) const CLIO_NOTHROW; - // registers a wrapper with an object - // virtual void DoMakeWrapperAware( void * object, ObjectWrapper * wrapper ) const CLIO_NOTHROW = 0; - ClassRegistratorSet * registrators_; mutable WrapperMap wrapperMap_; // map from C++ objects to wrappers Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-21 14:18:36 UTC (rev 8030) +++ private/z-man/clio/objectwrapper.cpp 2008-02-21 14:25:14 UTC (rev 8031) @@ -496,12 +496,13 @@ // yes? Then we're the main wrapper now. GetClassInfo().RegisterWrapper( object_, this ); - // inform the object + // fetch ObjectWrapperAware-part of the wrapped object (if it exists) if ( !awareObject_ ) { - awareObject_ = GetClassInfo().GetAwareObject( *this ); + GetClassInfo().SetAwareObject( *this ); } + // inform it that it was wrapped if ( awareObject_ ) { awareObject_->SetObjectWrapper( this ); Modified: private/z-man/clio/objectwrapperaware.cpp =================================================================== --- private/z-man/clio/objectwrapperaware.cpp 2008-02-21 14:18:36 UTC (rev 8030) +++ private/z-man/clio/objectwrapperaware.cpp 2008-02-21 14:25:14 UTC (rev 8031) @@ -52,20 +52,4 @@ { } -/* -// informs an object about the wrapper it was assigned to. -void AwareMaker::MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW -{ - assert(object); - object->SetObjectWrapper( wrapper ); } - -// informs an object about the wrapper it was assigned to. -bool AwareMaker::BreakObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW -{ - assert(object); - object->OnBreak(); - return false; -} -*/ -} Modified: private/z-man/clio/objectwrapperaware.hpp =================================================================== --- private/z-man/clio/objectwrapperaware.hpp 2008-02-21 14:18:36 UTC (rev 8030) +++ private/z-man/clio/objectwrapperaware.hpp 2008-02-21 14:25:14 UTC (rev 8031) @@ -38,40 +38,6 @@ ObjectWrapper * wrapper_; }; -// Don't derive from this class in client code, the functions -// are only intendet to be called from within clio. -class AwareMaker -{ -protected: -/* - // informs an object about the wrapper it was assigned to. - static void MakeObjectWrapperAware( ObjectWrapper * wrapper, ObjectWrapperAware * object ) CLIO_NOTHROW; - - // this second overload makes it possible to call the function from a template without knowing - // whether it makes sense or not. If it doesn't make sense, this stub is called instead. - inline static void MakeObjectWrapperAware( ObjectWrapper *, void * ){} - - // informs an object about a parent object breaking. Returns 'false' if the object - // feels quite alive. - static bool BreakObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW; - - // this second overload makes it possible to call the function from a template without knowing - // whether it makes sense or not. If it doesn't make sense, this stub is called instead. - inline static bool BreakObjectWrapperAware( void * ){return true;} -*/ -public: - // informs an object about the wrapper it was assigned to. - inline static ObjectWrapperAware * GetObjectWrapperAware( ObjectWrapperAware * object ) CLIO_NOTHROW - { - return object; - } - - inline static ObjectWrapperAware * GetObjectWrapperAware( void * object ) CLIO_NOTHROW - { - return 0; - } -}; - } #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 15:07:17
|
Revision: 8034 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8034&view=rev Author: z-man Date: 2008-02-21 07:07:20 -0800 (Thu, 21 Feb 2008) Log Message: ----------- Primitive wrappers now break instead of detach. Added support for proxy ownership changes. Modified Paths: -------------- private/z-man/clio/dataconversion.cpp private/z-man/clio/dataconversion.hpp private/z-man/clio/dataconversion_extended.hpp private/z-man/clio/ifunctioninfo.cpp private/z-man/clio/objectwrapper.cpp private/z-man/clio/objectwrapper.hpp private/z-man/clio/objectwrapperaware.cpp private/z-man/clio/objectwrapperaware.hpp private/z-man/clio/proxy.hpp private/z-man/clio/tests/container.test/output.txt private/z-man/clio/tests/container.test/test.io Modified: private/z-man/clio/dataconversion.cpp =================================================================== --- private/z-man/clio/dataconversion.cpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/dataconversion.cpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -6,6 +6,14 @@ namespace clio { +// call when a broken proxy object is accessed +void BrokenProxy( std::string const & className ) +{ + std::ostringstream err; + err << "Proxy for " << className << " is broken"; + throw Exception( "Broken Proxy", err.str() ); +} + // function argument conversion exception thrower FunctionArgumentExceptionThrower::FunctionArgumentExceptionThrower( int n, NameGetter name ) CLIO_NOTHROW Modified: private/z-man/clio/dataconversion.hpp =================================================================== --- private/z-man/clio/dataconversion.hpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/dataconversion.hpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -22,6 +22,9 @@ namespace clio { +// call when a broken proxy object is accessed +extern void BrokenProxy( std::string const & className ); + // template < class PRIMITIVE > class PrimitiveProxy; template< class T > class GCPointer; Modified: private/z-man/clio/dataconversion_extended.hpp =================================================================== --- private/z-man/clio/dataconversion_extended.hpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/dataconversion_extended.hpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -161,20 +161,14 @@ { } - PRIMITIVE const * GetTarget() const + PRIMITIVE const & GetTarget() const { - return data_; - } + if ( !data_ ) + { + BrokenProxy( GetTypeName< PRIMITIVE >() ); + } - PrimitiveProxyConstBase & SetTarget( PRIMITIVE const * data ) - { - // TODO: need to look at reregistration - assert(0); - Register( data ); - - assert( data ); - data_ = const_cast< PRIMITIVE *>( data ); - return *this; + return *data_; } void Detach() @@ -184,13 +178,27 @@ PRIMITIVE Get() const { - assert( data_ ); - return *data_; + return GetTarget(); } protected: + // called when the object changes ownership + virtual void OnOwnershipChange( ObjectWrapper::Ownership ownership ) + { + if ( ownership == ObjectWrapper::OwnedByIo ) + { + PRIMITIVE const * old = data_; + Detach(); + delete old; + } + } + virtual void OnBreak() CLIO_NOTHROW { - Detach(); + // break link + if ( &cache_ != data_ ) + { + data_ = 0; + } } virtual void OnSetObjectWrapper() @@ -219,21 +227,19 @@ :PrimitiveProxyConstBase< PRIMITIVE >( data ) {} - PRIMITIVE * GetTarget() const + PRIMITIVE & GetTarget() const { - return Base::data_; - } + if ( !Base::data_ ) + { + BrokenProxy( GetTypeName< PRIMITIVE >() ); + } - PrimitiveProxyNoConstBase & SetTarget( PRIMITIVE * data ) - { - Base::SetTarget( data ); - return *this; + return *Base::data_; } void Set( PRIMITIVE data ) { - assert( Base::data_ ); - *Base::data_ = data; + GetTarget() = data; } }; @@ -349,7 +355,7 @@ Proxy * proxy = DataConverterPointerImplementationBase< Proxy, true >::FromIo( from, call, thrower ); if ( !proxy ) thrower.Throw( "Only prototype found, but instance expected"); - return proxy->GetTarget(); + return &proxy->GetTarget(); } catch( ... ) { @@ -369,7 +375,7 @@ ClassInfo::Get().FetchIoObject( p, IoObject_state(from), ObjectWrapper::OwnedByIo ); // return a refernece to the held data - return p->GetTarget(); + return &p->GetTarget(); } catch( ... ){} Modified: private/z-man/clio/ifunctioninfo.cpp =================================================================== --- private/z-man/clio/ifunctioninfo.cpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/ifunctioninfo.cpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -324,7 +324,10 @@ else { // break all C++ objects anyway. - ObjectWrapper::BreakAll(); + if ( !executer->nonBreaking_ ) + { + ObjectWrapper::BreakAll(); + } } return ret; Modified: private/z-man/clio/objectwrapper.cpp =================================================================== --- private/z-man/clio/objectwrapper.cpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/objectwrapper.cpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -443,6 +443,19 @@ markers_.Remove( marker ); } +ObjectWrapper & ObjectWrapper::SetOwnership( Ownership ownership ) +{ + // inform aware object + if ( awareObject_ && ownership != ownership_ ) + { + awareObject_->OnOwnershipChange( ownership ); + } + + ownership_ = ownership; + return *this; +} + + ObjectWrapper * ObjectWrapper::GetObjectWrapper( IoObject * self ) CLIO_NOTHROW { if ( !IClassInfo::IsClioObject( self ) ) Modified: private/z-man/clio/objectwrapper.hpp =================================================================== --- private/z-man/clio/objectwrapper.hpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/objectwrapper.hpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -141,11 +141,7 @@ return ownership_; } - inline ObjectWrapper & SetOwnership( Ownership ownership ) - { - ownership_ = ownership; - return *this; - } + ObjectWrapper & SetOwnership( Ownership ownership ); static ObjectWrapper * GetObjectWrapper( IoObject * self ) CLIO_NOTHROW; Modified: private/z-man/clio/objectwrapperaware.cpp =================================================================== --- private/z-man/clio/objectwrapperaware.cpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/objectwrapperaware.cpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -32,6 +32,11 @@ return wrapper_; } +// called when the object changes ownership +void ObjectWrapperAware::OnOwnershipChange( ObjectWrapper::Ownership ownership ) +{ +} + // wrapper change hook void ObjectWrapperAware::OnSetObjectWrapper() { Modified: private/z-man/clio/objectwrapperaware.hpp =================================================================== --- private/z-man/clio/objectwrapperaware.hpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/objectwrapperaware.hpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -2,10 +2,10 @@ #define CLIO_IOBJECTWRAPPERAWARE_H #include "clio_config.hpp" +#include "objectwrapper.hpp" namespace clio { -class ObjectWrapper; // to be used as virtual base class for classes that know which ObjectWrapper they are // attached to @@ -26,6 +26,9 @@ return OnBreak(); } protected: + // called when the object changes ownership + virtual void OnOwnershipChange( ObjectWrapper::Ownership ownership ); + virtual void OnIoReference(); // hook called when Io takes an interest in this object virtual void OnIoRelease(); // hook called when Io lost interest in this object. This will not be called from the ~ObjectWrapperAware() path, but from all other paths that release this object Modified: private/z-man/clio/proxy.hpp =================================================================== --- private/z-man/clio/proxy.hpp 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/proxy.hpp 2008-02-21 15:07:20 UTC (rev 8034) @@ -80,6 +80,7 @@ // creates proxy for original explicit Proxy( ORIGINAL * original ) : original_( original ) + , owned_ ( false ) { assert( original ); } @@ -87,13 +88,31 @@ // creates proxy for original explicit Proxy( ORIGINAL & original ) : original_( &original ) + , owned_ ( false ) { } virtual ~Proxy() { + if ( owned_ ) + { + delete original_; + } + + owned_ = false; + original_ = 0; } protected: + // called when the object changes ownership + virtual void OnOwnershipChange( ObjectWrapper::Ownership ownership ) + { + // ownership transfer works only once. We take it. + if ( ownership == ObjectWrapper::OwnedByIo ) + { + owned_ = true; + } + } + // called when the object is linked to its wrapper virtual void OnSetObjectWrapper() { @@ -106,11 +125,14 @@ // called when the object this thing is chained to gets destroyed virtual void OnBreak() { - // remove reference to original - original_ = 0; + if ( !owned_ ) + { + // remove reference to original + original_ = 0; - // delegate - WrapperBase< ORIGINAL >::OnBreak(); + // delegate + WrapperBase< ORIGINAL >::OnBreak(); + } } private: // returns the original object @@ -118,10 +140,7 @@ { if ( !original_ ) { - std::ostringstream err; - err << "Proxy for " << GetTypeName< ORIGINAL >() << - " is broken"; - throw Exception( "Broken Proxy", err.str() ); + BrokenProxy( GetTypeName< ORIGINAL >() ); } return *original_; @@ -140,6 +159,9 @@ // pointer to the original wrapped object ORIGINAL * original_; + + // flag indicating ownership of the original + bool owned_; }; // Wrappers contain the wrapped object. Modified: private/z-man/clio/tests/container.test/output.txt =================================================================== --- private/z-man/clio/tests/container.test/output.txt 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/tests/container.test/output.txt 2008-02-21 15:07:20 UTC (rev 8034) @@ -40,4 +40,6 @@ <<<< x setInts( StdVector With(Int) clone append(5) ) <<<< x getInts foreach(println) 5 +<<<< x createFloats() + Modified: private/z-man/clio/tests/container.test/test.io =================================================================== --- private/z-man/clio/tests/container.test/test.io 2008-02-21 14:33:57 UTC (rev 8033) +++ private/z-man/clio/tests/container.test/test.io 2008-02-21 15:07:20 UTC (rev 8034) @@ -21,3 +21,5 @@ x getInts foreach(println) x setInts( StdVector With(Int) clone append(5) ) x getInts foreach(println) +x createFloats() + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 17:15:55
|
Revision: 8036 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8036&view=rev Author: z-man Date: 2008-02-21 09:15:58 -0800 (Thu, 21 Feb 2008) Log Message: ----------- Added security access levels. Modified Paths: -------------- private/z-man/clio/classregistrator.hpp private/z-man/clio/classregistratorset.cpp private/z-man/clio/helptest.hpp private/z-man/clio/iclassinfo.cpp private/z-man/clio/macros.hpp private/z-man/clio/stateregistrator.cpp private/z-man/clio/stateregistrator.hpp Added Paths: ----------- private/z-man/clio/security.cpp private/z-man/clio/security.hpp private/z-man/clio/tests/security.test/ private/z-man/clio/tests/security.test/output.txt private/z-man/clio/tests/security.test/test.cpp private/z-man/clio/tests/security.test/test.io Modified: private/z-man/clio/classregistrator.hpp =================================================================== --- private/z-man/clio/classregistrator.hpp 2008-02-21 17:11:33 UTC (rev 8035) +++ private/z-man/clio/classregistrator.hpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -3,6 +3,7 @@ #include "nocopy.hpp" #include "linkedlist.hpp" +#include "stateregistrator.hpp" class IoState; @@ -13,14 +14,14 @@ class ObjectWrapper; // something that wants to register things with a state -class IClassRegistrator: public LinkedListItem< IClassRegistrator > +class IClassRegistrator: public LinkedListItem< IClassRegistrator >, public Security { public: IClassRegistrator( ClassRegistratorSet & set ); virtual ~IClassRegistrator(); // for future extensions - struct ExtraInfo{}; + struct ExtraInfo: public IStateRegistrator::ExtraInfo{}; // register with a state, decoupling wrapper inline void Register( IoState * state, ObjectWrapper * self, ExtraInfo const & info ) Modified: private/z-man/clio/classregistratorset.cpp =================================================================== --- private/z-man/clio/classregistratorset.cpp 2008-02-21 17:11:33 UTC (rev 8035) +++ private/z-man/clio/classregistratorset.cpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -21,7 +21,10 @@ IClassRegistrator * run = anchor_.Next(); while ( run ) { - run->Register( state, self, info ); + if ( run->Allow( info.level_ ) ) + { + run->Register( state, self, info ); + } run = run->Next(); } } Modified: private/z-man/clio/helptest.hpp =================================================================== --- private/z-man/clio/helptest.hpp 2008-02-21 17:11:33 UTC (rev 8035) +++ private/z-man/clio/helptest.hpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -33,8 +33,14 @@ void Test(); +static int argnum_; +static char ** argv_; + int main( int argnum, char ** argv ) { + argnum_ = argnum; + argv_ = argv; + clio::State state; clio::IStateRegistrator::RegisterAll( state ); Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-21 17:11:33 UTC (rev 8035) +++ private/z-man/clio/iclassinfo.cpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -680,8 +680,12 @@ ObjectWrapper * wrapper = static_cast< ObjectWrapper * >( IoObject_dataPointer( self ) ); // register more things (methods) - GetClassRegistratorSet().RegisterAll( state, wrapper ); + // get info from state registrator + IClassRegistrator::ExtraInfo classInfo; + static_cast< ExtraInfo & >( classInfo ) = info; + GetClassRegistratorSet().RegisterAll( state, wrapper, classInfo ); + // register object class IoState_registerProtoWithFunc_( state, self, creator ); } @@ -736,11 +740,13 @@ assert( base ); ObjectWrapper * prototypeWrapperBase = base->prototypeMap_[ state ]; - assert( prototypeWrapperBase ); - IoObject * prototypeBase = prototypeWrapperBase->GetSelf(); - assert( prototypeBase ); + if ( prototypeWrapperBase ) + { + IoObject * prototypeBase = prototypeWrapperBase->GetSelf(); + assert( prototypeBase ); - IoObject_rawAppendProto_( prototype, prototypeBase ); + IoObject_rawAppendProto_( prototype, prototypeBase ); + } // register more things from base class (methods) // base->GetClassRegistratorSet().RegisterAll( state, wrapper ); Modified: private/z-man/clio/macros.hpp =================================================================== --- private/z-man/clio/macros.hpp 2008-02-21 17:11:33 UTC (rev 8035) +++ private/z-man/clio/macros.hpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -428,6 +428,9 @@ #define CLIO_CLASS_NESTED_IN_EX( PARENT ) clio::RegisterNestingParentClass< CLASS, PARENT >() #define CLIO_CLASS_NESTED_IN( PARENT ) CLIO_CLASS_NESTED_IN_EX(PARENT) +// change access level of class +#define CLIO_CLASS_MIN_LEVEL( LEVEL ) ClassInfo< CLASS >::Get().SetMinLevel( LEVEL ) + // declare a constructor with arbitrary arguments, it will be accessible via a "with" function #define CLIO_CONSTRUCTOR_CUSTOM_EX( ARGLIST, NAME ) \ - ( clio::Constructor< CLASS, CLIO_TYPELIST(ARGLIST)>( NAME ) ) Added: private/z-man/clio/security.cpp =================================================================== --- private/z-man/clio/security.cpp (rev 0) +++ private/z-man/clio/security.cpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -0,0 +1,9 @@ +#include "security.hpp" + +namespace clio +{ + + +} + + Added: private/z-man/clio/security.hpp =================================================================== --- private/z-man/clio/security.hpp (rev 0) +++ private/z-man/clio/security.hpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -0,0 +1,45 @@ +#ifndef CLIO_SECURITY_H +#define CLIO_SECURITY_H + +#include "clio_config.hpp" + +#include <limits.h> + +namespace clio +{ + +// class managing security levels +class Security +{ +public: + // the security level. Numerically lower values are higher security levels. + // level 0 would typically be allowed to do everything. You should + // define an enum or use #defines for your security levels, of course. + typedef int Level; + + Security() + : minLevel_( INT_MAX ) + { + } + + Level GetMinLevel() const + { + return minLevel_; + } + + void SetMinLevel( Level level ) + { + minLevel_ = level; + } + + // check if the minimum requirement is fulfilled + bool Allow( Level level ) + { + return level <= minLevel_; + } +private: + Level minLevel_; // minimal security level this item will be made available at +}; + +} +#endif Modified: private/z-man/clio/stateregistrator.cpp =================================================================== --- private/z-man/clio/stateregistrator.cpp 2008-02-21 17:11:33 UTC (rev 8035) +++ private/z-man/clio/stateregistrator.cpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -32,21 +32,30 @@ IStateRegistrator * run = Anchor()->Next(); while ( run ) { - run->PreRegister( state ); + if ( run->Allow( info.level_ ) ) + { + run->PreRegister( state ); + } run = run->Next(); } run = Anchor()->Next(); while ( run ) { - run->Register( state, info ); + if ( run->Allow( info.level_ ) ) + { + run->Register( state, info ); + } run = run->Next(); } run = Anchor()->Next(); while ( run ) { - run->PostRegister( state ); + if ( run->Allow( info.level_ ) ) + { + run->PostRegister( state ); + } run = run->Next(); } } Modified: private/z-man/clio/stateregistrator.hpp =================================================================== --- private/z-man/clio/stateregistrator.hpp 2008-02-21 17:11:33 UTC (rev 8035) +++ private/z-man/clio/stateregistrator.hpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -4,6 +4,7 @@ #include "nocopy.hpp" #include "linkedlist.hpp" #include "clio_config.hpp" +#include "security.hpp" // implementation @@ -13,15 +14,26 @@ { // something that wants to register things with a state -class IStateRegistrator: public LinkedListItem< IStateRegistrator > +class IStateRegistrator: public LinkedListItem< IStateRegistrator >, public Security { public: IStateRegistrator() CLIO_NOTHROW; virtual ~IStateRegistrator() CLIO_NOTHROW; // for future extensions -struct ExtraInfo{}; + struct ExtraInfo + { + Security::Level level_; // security level of the state + ExtraInfo() + : level_(0) + {} + + ExtraInfo( Security::Level level ) + : level_( level ) + {} + }; + // register all registrators with a state static void RegisterAll( IoState * state, ExtraInfo const & info ) CLIO_NOTHROW; static void RegisterAll( IoState * state ) CLIO_NOTHROW; Added: private/z-man/clio/tests/security.test/output.txt =================================================================== Added: private/z-man/clio/tests/security.test/test.cpp =================================================================== --- private/z-man/clio/tests/security.test/test.cpp (rev 0) +++ private/z-man/clio/tests/security.test/test.cpp 2008-02-21 17:15:58 UTC (rev 8036) @@ -0,0 +1,90 @@ +#include "helptest.hpp" + +// **************************** +// proto +// **************************** + +// a completely public class +class Public +{ +public: + void f() + { + std::cout << "Public::f()\n"; + }; +}; + +// a class that is secret on some access levels +class Secret +{ +public: + virtual ~Secret(){}; + + // this method will be very restricted and not available on + // all states that can see the class. + void f() + { + std::cout << "Secret::f()\n"; + }; + + // this method will be public. + void g() + { + std::cout << "Secret::g()\n"; + }; +}; + +// a class derived from the secret class using the secret class +// with the user "forgetting" to also make it secret +class SecretDerived: public Secret +{ +public: + // two functions accessing the secret base + Secret const & Base() const + { + return *this; + } + + Secret * BaseClone() const + { + return new Secret( *this ); + } +}; + +CLIO_CLASS( Public ) +{ + CLIO_METHOD(f); +} + +CLIO_CLASS( Secret ) +{ + CLIO_CLASS_MIN_LEVEL(1); + CLIO_METHOD(f).SetMinLevel(0); + CLIO_METHOD(g); +} + +CLIO_CLASS( SecretDerived ) +{ + CLIO_CLASS_BASE( Secret ); + + CLIO_METHOD( Base ); + CLIO_METHOD( BaseClone ).TransferOwnership(); +} + +void Test() +{ + clio::State state; + + // register only low security objects + clio::IStateRegistrator::RegisterAll( state, 1 ); + + TestFile( state, ( std::string( argv_[0] ) + ".io").c_str() ); + + clio::State state2; + + // register only very low security objects + clio::IStateRegistrator::RegisterAll( state2, 100 ); + + TestFile( state2, ( std::string(argv_[0] ) + ".io").c_str() ); +} + Added: private/z-man/clio/tests/security.test/test.io =================================================================== --- private/z-man/clio/tests/security.test/test.io (rev 0) +++ private/z-man/clio/tests/security.test/test.io 2008-02-21 17:15:58 UTC (rev 8036) @@ -0,0 +1,5 @@ +Public clone f() +Secret clone f() +SecretDerived clone base f() +SecretDerived clone baseClone g() +SecretDerived clone baseClone f() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 18:33:02
|
Revision: 8038 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8038&view=rev Author: z-man Date: 2008-02-21 10:33:04 -0800 (Thu, 21 Feb 2008) Log Message: ----------- Added automatic namespace detection. Modified Paths: -------------- private/z-man/clio/iclassinfo.cpp private/z-man/clio/macros.cpp private/z-man/clio/macros.hpp private/z-man/clio/tests/constructor.test/output.txt private/z-man/clio/tests/constructor.test/test.cpp Added Paths: ----------- private/z-man/clio/namespace.cpp private/z-man/clio/namespace.hpp private/z-man/clio/tests/namespace.test/ private/z-man/clio/tests/namespace.test/output.txt private/z-man/clio/tests/namespace.test/test.cpp private/z-man/clio/tests/namespace.test/test.io Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-21 17:25:34 UTC (rev 8037) +++ private/z-man/clio/iclassinfo.cpp 2008-02-21 18:33:04 UTC (rev 8038) @@ -673,7 +673,7 @@ IoStateProtoFunc * creator = DoGetStateProtoFunc(); // create object - IoObject * self = (*creator)( state ); + IoObject * self = Create( state ); assert( self ); // retrieve its wrapper (cast is safe, the object has just been created ) Modified: private/z-man/clio/macros.cpp =================================================================== --- private/z-man/clio/macros.cpp 2008-02-21 17:25:34 UTC (rev 8037) +++ private/z-man/clio/macros.cpp 2008-02-21 18:33:04 UTC (rev 8038) @@ -1,5 +1,7 @@ #include "macros.hpp" #include "namemangling.hpp" +#include "namespace.hpp" + #include <ctype.h> namespace clio Modified: private/z-man/clio/macros.hpp =================================================================== --- private/z-man/clio/macros.hpp 2008-02-21 17:25:34 UTC (rev 8037) +++ private/z-man/clio/macros.hpp 2008-02-21 18:33:04 UTC (rev 8038) @@ -9,6 +9,7 @@ #include "forcesemicolon.hpp" #include "templatearglist.hpp" #include "codeinjection.hpp" +#include "namespace.hpp" #include <string> #include <ctype.h> @@ -230,6 +231,13 @@ info.SetName( IClassInfo::Name_C , cName ); info.SetName( IClassInfo::Name_IoRaw, ioName ); + // register namespace + NameSpace * nameSpace = NameSpace::GetNameSpace( cName ); + if ( nameSpace ) + { + info.SetNestingParent( nameSpace ); + } + // create a basic default factory FactoryCreator< CLASS >::CreateFactory(); Added: private/z-man/clio/namespace.cpp =================================================================== --- private/z-man/clio/namespace.cpp (rev 0) +++ private/z-man/clio/namespace.cpp 2008-02-21 18:33:04 UTC (rev 8038) @@ -0,0 +1,95 @@ +#include "namespace.hpp" +#include "namemangling.hpp" + +#include <sstream> +#include <memory> + +namespace clio +{ + +// returns the size of the wrapped object +size_t NameSpace::DoGetSize() const CLIO_NOTHROW +{ + return 0; +} + +// checks if wrapper wraps an ObjectWrapperAware object , and if yes, informs it. +void NameSpace::DoSetAwareObject( ObjectWrapper & wrapper ) const CLIO_NOTHROW +{ +} + +static NameSpace & GetMasterNameSpace() +{ + static NameSpace space; + return space; +} + +// object creator +IoObject * NameSpace::CreateStatic( IoState * state ) +{ + return GetMasterNameSpace().Create( state ); +} + +// returns a static function capable of creating an Io object with an object of this class +IoStateProtoFunc * NameSpace::DoGetStateProtoFunc() const CLIO_NOTHROW +{ + return 0; // (IoStateProtoFunc *)CreateStatic; +} + +typedef static std::map< std::string, NameSpace * > SpaceMap; + +class AutoClearer +{ +public: + AutoClearer( SpaceMap & map ) + : map_( map ){} + + ~AutoClearer() + { + for( SpaceMap::iterator i = map_.begin(); i != map_.end(); ++i ) + { + delete (*i).second; + (*i).second = 0; + } + } +private: + SpaceMap & map_; +}; + +// gets a namespace of a given class name +NameSpace * NameSpace::GetNameSpace( std::string const & name ) +{ + // map of namespaces + static SpaceMap spaces; + static AutoClearer clearer( spaces ); + + // parse the class name + std::istringstream s( name ); + std::ostringstream nameSpaceName; + + do + { + int c = s.get(); + if (c == ':' ) + break; + + // no scope, no namespace + if ( s.eof() ) + return 0; + + nameSpaceName.put(c); + } + while( true ); + + NameSpace * & space = spaces[ nameSpaceName.str() ]; + if ( !space ) + { + space = new NameSpace; + space->SetName( IClassInfo::Name_C , nameSpaceName.str() ); + space->SetName( IClassInfo::Name_IoRaw, Uppercase( nameSpaceName.str().c_str() ) ); + } + + return space; +} + +} Added: private/z-man/clio/namespace.hpp =================================================================== --- private/z-man/clio/namespace.hpp (rev 0) +++ private/z-man/clio/namespace.hpp 2008-02-21 18:33:04 UTC (rev 8038) @@ -0,0 +1,31 @@ +#ifndef CLIO_NAMESPACE_H +#define CLIO_NAMESPACE_H + +#include "iclassinfo.hpp" + +namespace clio +{ + +// C++ name spaces. Empty class infos used only for nesting other stuff into it. +class NameSpace: public IClassInfo +{ +public: + // gets a namespace of a given class name + static NameSpace * GetNameSpace( std::string const & name ); +private: + // returns the size of the wrapped object + virtual size_t DoGetSize() const CLIO_NOTHROW; + + // checks if wrapper wraps an ObjectWrapperAware object , and if yes, informs it. + virtual void DoSetAwareObject( ObjectWrapper & wrapper ) const CLIO_NOTHROW; + + // returns a static function capable of creating an Io object with an object of this class + virtual IoStateProtoFunc * DoGetStateProtoFunc() const CLIO_NOTHROW; + + // create prototype object + static IoObject * CreateStatic( IoState * state ); +}; + +} + +#endif Modified: private/z-man/clio/tests/constructor.test/output.txt =================================================================== --- private/z-man/clio/tests/constructor.test/output.txt 2008-02-21 17:25:34 UTC (rev 8037) +++ private/z-man/clio/tests/constructor.test/output.txt 2008-02-21 18:33:04 UTC (rev 8038) @@ -5,11 +5,11 @@ Exception: Method requires an instance target, not a prototype. (during call of C++ function 'ConstructTest1::v()') -<<<< y := ConstructTest2 with(1) +<<<< y := CT ConstructTest2 with(1) Exception: Sequence expected, got 'Number' instead (parsing argument 0 of desired type 'char const *' during call of C++ function 'CT::ConstructTest2::with( char const * )') -<<<< y := ConstructTest2 with2(1) +<<<< y := CT ConstructTest2 with2(1) Exception: Sequence expected, got 'Number' instead (parsing argument 0 of desired type 'char const *' during call of C++ function 'CT::ConstructTest2::with2( char const * )') @@ -17,7 +17,7 @@ bla <<<< y v println bla -<<<< Derived := ConstructTest2 clone do( x := 1; v := method( "V in script +<<<< Derived := CT ConstructTest2 clone do( x := 1; v := method( "V in script " ) ) <<<< y := Derived with("blubb") blubb Modified: private/z-man/clio/tests/constructor.test/test.cpp =================================================================== --- private/z-man/clio/tests/constructor.test/test.cpp 2008-02-21 17:25:34 UTC (rev 8037) +++ private/z-man/clio/tests/constructor.test/test.cpp 2008-02-21 18:33:04 UTC (rev 8038) @@ -99,14 +99,14 @@ std::cout << "Expecting three errors\n"; TestString( state, "y v" ); - TestString( state, "y := ConstructTest2 with(1)" ); - TestString( state, "y := ConstructTest2 with2(1)" ); + TestString( state, "y := CT ConstructTest2 with(1)" ); + TestString( state, "y := CT ConstructTest2 with2(1)" ); TestString( state, "y := ConstructTest1 with(\"bla\")" ); TestString( state, "y v println" ); // testing construction of derived classes - TestString( state, "Derived := ConstructTest2 clone do( x := 1; v := method( \"V in script\n\" ) )" ); + TestString( state, "Derived := CT ConstructTest2 clone do( x := 1; v := method( \"V in script\n\" ) )" ); TestString( state, "y := Derived with(\"blubb\")" ); TestString( state, "y x println" ); TestString( state, "y v println" ); Added: private/z-man/clio/tests/namespace.test/output.txt =================================================================== --- private/z-man/clio/tests/namespace.test/output.txt (rev 0) +++ private/z-man/clio/tests/namespace.test/output.txt 2008-02-21 18:33:04 UTC (rev 8038) @@ -0,0 +1,3 @@ +<<<< Space Test clone + + Added: private/z-man/clio/tests/namespace.test/test.cpp =================================================================== --- private/z-man/clio/tests/namespace.test/test.cpp (rev 0) +++ private/z-man/clio/tests/namespace.test/test.cpp 2008-02-21 18:33:04 UTC (rev 8038) @@ -0,0 +1,21 @@ +#include "helptest.hpp" + +// **************************** +// proto +// **************************** + +namespace space +{ + class Test + { + }; +} + +CLIO_CLASS( space::Test ) +{ +} + +void Test() +{ +} + Added: private/z-man/clio/tests/namespace.test/test.io =================================================================== --- private/z-man/clio/tests/namespace.test/test.io (rev 0) +++ private/z-man/clio/tests/namespace.test/test.io 2008-02-21 18:33:04 UTC (rev 8038) @@ -0,0 +1,2 @@ +Space Test clone + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 18:53:05
|
Revision: 8039 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8039&view=rev Author: z-man Date: 2008-02-21 10:53:03 -0800 (Thu, 21 Feb 2008) Log Message: ----------- Small cleanup. Modified Paths: -------------- private/z-man/clio/namespace.cpp private/z-man/clio/namespace.hpp Modified: private/z-man/clio/namespace.cpp =================================================================== --- private/z-man/clio/namespace.cpp 2008-02-21 18:33:04 UTC (rev 8038) +++ private/z-man/clio/namespace.cpp 2008-02-21 18:53:03 UTC (rev 8039) @@ -18,22 +18,10 @@ { } -static NameSpace & GetMasterNameSpace() -{ - static NameSpace space; - return space; -} - -// object creator -IoObject * NameSpace::CreateStatic( IoState * state ) -{ - return GetMasterNameSpace().Create( state ); -} - // returns a static function capable of creating an Io object with an object of this class IoStateProtoFunc * NameSpace::DoGetStateProtoFunc() const CLIO_NOTHROW { - return 0; // (IoStateProtoFunc *)CreateStatic; + return 0; } typedef static std::map< std::string, NameSpace * > SpaceMap; Modified: private/z-man/clio/namespace.hpp =================================================================== --- private/z-man/clio/namespace.hpp 2008-02-21 18:33:04 UTC (rev 8038) +++ private/z-man/clio/namespace.hpp 2008-02-21 18:53:03 UTC (rev 8039) @@ -21,9 +21,6 @@ // returns a static function capable of creating an Io object with an object of this class virtual IoStateProtoFunc * DoGetStateProtoFunc() const CLIO_NOTHROW; - - // create prototype object - static IoObject * CreateStatic( IoState * state ); }; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <z-...@us...> - 2008-02-21 22:00:50
|
Revision: 8040 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8040&view=rev Author: z-man Date: 2008-02-21 14:00:56 -0800 (Thu, 21 Feb 2008) Log Message: ----------- Made a boatload of plain IoObject * to IoObjectPointers to avoid the Garbage Collector from Hell. Adapted enum test to namespaces. Fixed double proto errors by not registering namespace protos. Modified Paths: -------------- private/z-man/clio/function.hpp private/z-man/clio/iclassinfo.cpp private/z-man/clio/ifunctioninfo.cpp private/z-man/clio/namespace.cpp private/z-man/clio/tests/enum.test/output.txt private/z-man/clio/tests/enum.test/test.io private/z-man/clio/virtual_helper.cpp private/z-man/clio/virtual_helper.hpp Modified: private/z-man/clio/function.hpp =================================================================== --- private/z-man/clio/function.hpp 2008-02-21 18:53:03 UTC (rev 8039) +++ private/z-man/clio/function.hpp 2008-02-21 22:00:56 UTC (rev 8040) @@ -7,7 +7,7 @@ #include "typelist.hpp" #include "macrorecursion.hpp" -// #include "objectwrapperaware.hpp" +#include "gcpointer.hpp" namespace clio { Modified: private/z-man/clio/iclassinfo.cpp =================================================================== --- private/z-man/clio/iclassinfo.cpp 2008-02-21 18:53:03 UTC (rev 8039) +++ private/z-man/clio/iclassinfo.cpp 2008-02-21 22:00:56 UTC (rev 8040) @@ -590,7 +590,7 @@ // std::cout << "Cloning " << name_ << "\n"; // clone Io part of object - IoObject *clone = IoObject_rawClonePrimitive( self ); + IoObject * clone = IoObject_rawClonePrimitive( self ); // get C++ payload of old object, get class ObjectWrapper & wrapper = GetObjectWrapper( self ); @@ -687,7 +687,10 @@ GetClassRegistratorSet().RegisterAll( state, wrapper, classInfo ); // register object class - IoState_registerProtoWithFunc_( state, self, creator ); + if ( creator ) + { + IoState_registerProtoWithFunc_( state, self, creator ); + } } void IClassInfo::DoPreRegister( IoState * state ) CLIO_NOTHROW @@ -730,8 +733,6 @@ IoObject * prototype = prototypeWrapper->GetSelf(); assert( prototype ); - // ObjectWrapper * wrapper = static_cast< ObjectWrapper * >( prototype_->data.ptr ); - // register base classes for ( Casters::iterator iter = upcasts_.begin(); iter != upcasts_.end(); ++iter ) { Modified: private/z-man/clio/ifunctioninfo.cpp =================================================================== --- private/z-man/clio/ifunctioninfo.cpp 2008-02-21 18:53:03 UTC (rev 8039) +++ private/z-man/clio/ifunctioninfo.cpp 2008-02-21 22:00:56 UTC (rev 8040) @@ -147,7 +147,7 @@ StackResetter topMarker( & topOfStack_ ); // get self - IoObject * self = selfWrapper.GetSelf(); + IoObjectPointer self = selfWrapper.GetSelf(); assert( self ); // get state @@ -165,12 +165,12 @@ argumentsRetained.reserve( argCount ); for( int i = 0; i < argCount; ++i ) { - IoObject * object = IoMessage_locals_valueArgAt_( m, locals, i ); + IoObjectPointer object = IoMessage_locals_valueArgAt_( m, locals, i ); arguments.push_back( object ); argumentsRetained.push_back( object ); } - IoObject * ret = NULL; + IoObjectPointer ret = NULL; IFunctionInfo const * executer = this; // and execute @@ -403,13 +403,13 @@ try { /* - IoObject *call = IoObject_getSlot_(locals, IOSYMBOL("call")); - IoObject *sender = IoCall_sender(call, locals, m); + IoObjectPointercall = IoObject_getSlot_(locals, IOSYMBOL("call")); + IoObjectPointersender = IoCall_sender(call, locals, m); */ - // IoObject *sender = IoObject_getSlot(call, IOSTRING("sender")); + // IoObjectPointersender = IoObject_getSlot(call, IOSTRING("sender")); - IoObject * ret = selfData->function->ExecuteInline_( targetWrapper, locals, m ); + IoObjectPointer ret = selfData->function->ExecuteInline_( targetWrapper, locals, m ); return ret; } catch ( clio::Exception & e ) @@ -430,10 +430,10 @@ assert( locals ); assert( m ); - IoObject *bTarget = IoMessage_locals_valueArgAt_(m, locals, 0); - IoObject *bLocals = locals; - IoObject *bMessage = m; - IoObject *bContext = bTarget; + IoObjectPointer bTarget = IoMessage_locals_valueArgAt_(m, locals, 0); + IoObjectPointer bLocals = locals; + IoObjectPointer bMessage = m; + IoObjectPointer bContext = bTarget; int argCount = IoMessage_argCount(m); if (argCount > 1) @@ -460,7 +460,7 @@ IoCFunction *ClioFunction_rawClone(IoCFunction *proto) { - IoObject *self = IoObject_rawClonePrimitive(proto); + IoObjectPointer self = IoObject_rawClonePrimitive(proto); IoObject_setDataPointer_(self, cpalloc(DATA(proto), sizeof(ClioFunctionData))); IoObject_isActivatable_( self, 1 ); return self; @@ -480,7 +480,7 @@ IoCFunction * ClioFunction_proto(void *state) { - IoObject *self = IoObject_new(state); + IoObjectPointer self = IoObject_new(state); IoObject_tag_( self, ClioFunction_tag(state) ); IoObject_setDataPointer_(self, calloc(1, sizeof(ClioFunctionData))); @@ -501,7 +501,7 @@ {NULL, NULL}, }; - IoObject *self = IoState_protoWithInitFunction_((IoState *)state, ClioFunction_proto); + IoObjectPointer self = IoState_protoWithInitFunction_((IoState *)state, ClioFunction_proto); IoObject_addMethodTable_(self, methodTable); } @@ -546,7 +546,7 @@ IoObject * IoObject_addClioMethod_( IoObject *self, IoSymbol *slotName, IFunctionInfo *fp ) { IoTag *t = IoObject_tag( self ); - IoObject *proto = IoState_protoWithInitFunction_(IOSTATE, IoObject_proto); + IoObjectPointer proto = IoState_protoWithInitFunction_(IOSTATE, IoObject_proto); IoCFunction *f; if (t == IoObject_tag( proto ) ) @@ -673,7 +673,7 @@ void IFunctionInfo::DoRegister( IoState * state, ObjectWrapper * selfWrapper, ExtraInfo const & info ) CLIO_NOTHROW { // fetch Io Object - IoObject * self = selfWrapper->GetSelf(); + IoObjectPointer self = selfWrapper->GetSelf(); // get symbol matching function name IoSymbol * slotName = IOSYMBOL( name_.c_str() ); Modified: private/z-man/clio/namespace.cpp =================================================================== --- private/z-man/clio/namespace.cpp 2008-02-21 18:53:03 UTC (rev 8039) +++ private/z-man/clio/namespace.cpp 2008-02-21 22:00:56 UTC (rev 8040) @@ -24,7 +24,7 @@ return 0; } -typedef static std::map< std::string, NameSpace * > SpaceMap; +typedef std::map< std::string, NameSpace * > SpaceMap; class AutoClearer { Modified: private/z-man/clio/tests/enum.test/output.txt =================================================================== --- private/z-man/clio/tests/enum.test/output.txt 2008-02-21 18:53:03 UTC (rev 8039) +++ private/z-man/clio/tests/enum.test/output.txt 2008-02-21 22:00:56 UTC (rev 8040) @@ -29,7 +29,7 @@ value1 # testing reference instantiation -<<<< r := Ref With(TestEnum) +<<<< r := Clio Ref With(TestEnum) <<<< r = r with( TestEnum value3 ) <<<< r type println Ref With(TestEnum) Modified: private/z-man/clio/tests/enum.test/test.io =================================================================== --- private/z-man/clio/tests/enum.test/test.io 2008-02-21 18:53:03 UTC (rev 8039) +++ private/z-man/clio/tests/enum.test/test.io 2008-02-21 22:00:56 UTC (rev 8040) @@ -19,7 +19,7 @@ EnumTest get println # testing reference instantiation -r := Ref With(TestEnum) +r := Clio Ref With(TestEnum) r = r with( TestEnum value3 ) r type println r println Modified: private/z-man/clio/virtual_helper.cpp =================================================================== --- private/z-man/clio/virtual_helper.cpp 2008-02-21 18:53:03 UTC (rev 8039) +++ private/z-man/clio/virtual_helper.cpp 2008-02-21 22:00:56 UTC (rev 8040) @@ -48,7 +48,7 @@ ObjectWrapper * wrapper = aware->GetObjectWrapper(); if ( !wrapper ) return false; - IoObject * self = wrapper->GetSelf(); + IoObjectPointer self = wrapper->GetSelf(); if ( !self ) return false; @@ -71,7 +71,7 @@ ObjectWrapper * wrapper = aware->GetObjectWrapper(); if ( !wrapper ) return false; - IoObject * self = wrapper->GetSelf(); + IoObjectPointer self = wrapper->GetSelf(); if ( !self ) return false; @@ -128,7 +128,7 @@ // derived from the target object IoObject_rawAppendProto_( locals_, self_ ); - IoObject *self = self_; + IoObjectPointer self = self_; IoObject_setSlot_to_( locals_, IOSYMBOL("self"), self_ ); } Modified: private/z-man/clio/virtual_helper.hpp =================================================================== --- private/z-man/clio/virtual_helper.hpp 2008-02-21 18:53:03 UTC (rev 8039) +++ private/z-man/clio/virtual_helper.hpp 2008-02-21 22:00:56 UTC (rev 8040) @@ -5,6 +5,7 @@ #include <string> #include "dataconversion.hpp" #include "clio_config.hpp" +#include "gcpointer.hpp" class IoState; @@ -78,15 +79,15 @@ void SetMessage(IoMessage * message); private: IoState * state_; // the io state - IoObject * self_; // the object to call the method on + IoObjectPointer self_; // the object to call the method on IoSymbol * slotName_; // the slotname of the method to call - IoObject * method_; // the method itself + IoObjectPointer method_; // the method itself IoMessage * message_; // the message to send - IoObject * locals_; // the locals for the message call - IoObject * context_; // the context of the message call + IoObjectPointer locals_; // the locals for the message call + IoObjectPointer context_; // the context of the message call }; /* the easiest usage is for calling zero-argument functions: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |