added wxDynamicObject (kind of delegate, docs to come once this has calmed down)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22765 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -33,6 +33,11 @@
|
||||
|
||||
#if wxUSE_EXTENDED_RTTI
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Enum Support
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -407,7 +412,7 @@ void wxSetStringToArray( const wxString &s , wxArrayString &array )
|
||||
// wxClassInfo
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const wxPropertyAccessor *wxClassInfo::FindAccessor(const char *PropertyName)
|
||||
const wxPropertyAccessor *wxClassInfo::FindAccessor(const char *PropertyName) const
|
||||
{
|
||||
const wxPropertyInfo* info = FindPropertyInfo( PropertyName ) ;
|
||||
|
||||
@@ -417,7 +422,7 @@ const wxPropertyAccessor *wxClassInfo::FindAccessor(const char *PropertyName)
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
const wxPropertyInfo *wxClassInfo::FindPropertyInfo (const char *PropertyName) const
|
||||
const wxPropertyInfo *wxClassInfo::FindPropertyInfoInThisClass (const char *PropertyName) const
|
||||
{
|
||||
const wxPropertyInfo* info = GetFirstProperty() ;
|
||||
|
||||
@@ -428,6 +433,15 @@ const wxPropertyInfo *wxClassInfo::FindPropertyInfo (const char *PropertyName) c
|
||||
info = info->GetNext() ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const wxPropertyInfo *wxClassInfo::FindPropertyInfo (const char *PropertyName) const
|
||||
{
|
||||
const wxPropertyInfo* info = FindPropertyInfoInThisClass( PropertyName ) ;
|
||||
if ( info )
|
||||
return info ;
|
||||
|
||||
const wxClassInfo** parents = GetParents() ;
|
||||
for ( int i = 0 ; parents[i] ; ++ i )
|
||||
{
|
||||
@@ -438,7 +452,7 @@ const wxPropertyInfo *wxClassInfo::FindPropertyInfo (const char *PropertyName) c
|
||||
return 0;
|
||||
}
|
||||
|
||||
const wxHandlerInfo *wxClassInfo::FindHandlerInfo (const char *PropertyName) const
|
||||
const wxHandlerInfo *wxClassInfo::FindHandlerInfoInThisClass (const char *PropertyName) const
|
||||
{
|
||||
const wxHandlerInfo* info = GetFirstHandler() ;
|
||||
|
||||
@@ -449,6 +463,16 @@ const wxHandlerInfo *wxClassInfo::FindHandlerInfo (const char *PropertyName) con
|
||||
info = info->GetNext() ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const wxHandlerInfo *wxClassInfo::FindHandlerInfo (const char *PropertyName) const
|
||||
{
|
||||
const wxHandlerInfo* info = FindHandlerInfoInThisClass( PropertyName ) ;
|
||||
|
||||
if ( info )
|
||||
return info ;
|
||||
|
||||
const wxClassInfo** parents = GetParents() ;
|
||||
for ( int i = 0 ; parents[i] ; ++ i )
|
||||
{
|
||||
@@ -460,7 +484,7 @@ const wxHandlerInfo *wxClassInfo::FindHandlerInfo (const char *PropertyName) con
|
||||
}
|
||||
|
||||
|
||||
void wxClassInfo::SetProperty(wxObject *object, const char *propertyName, const wxxVariant &value)
|
||||
void wxClassInfo::SetProperty(wxObject *object, const char *propertyName, const wxxVariant &value) const
|
||||
{
|
||||
const wxPropertyAccessor *accessor;
|
||||
|
||||
@@ -469,7 +493,7 @@ void wxClassInfo::SetProperty(wxObject *object, const char *propertyName, const
|
||||
accessor->SetProperty( object , value ) ;
|
||||
}
|
||||
|
||||
wxxVariant wxClassInfo::GetProperty(wxObject *object, const char *propertyName)
|
||||
wxxVariant wxClassInfo::GetProperty(wxObject *object, const char *propertyName) const
|
||||
{
|
||||
const wxPropertyAccessor *accessor;
|
||||
|
||||
@@ -491,5 +515,160 @@ wxObject* wxxVariant::GetAsObject()
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDynamicObject support
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Dynamic Objects are objects that have a real superclass instance and carry their
|
||||
// own attributes in a hash map. Like this it is possible to create the objects and
|
||||
// stream them, as if their class information was already available from compiled data
|
||||
|
||||
struct wxDynamicObject::wxDynamicObjectInternal
|
||||
{
|
||||
map<string,wxxVariant> m_properties ;
|
||||
} ;
|
||||
|
||||
// instantiates this object with an instance of its superclass
|
||||
wxDynamicObject::wxDynamicObject(wxObject* superClassInstance, const wxDynamicClassInfo *info)
|
||||
{
|
||||
m_superClassInstance = superClassInstance ;
|
||||
m_classInfo = info ;
|
||||
m_data = new wxDynamicObjectInternal ;
|
||||
}
|
||||
|
||||
wxDynamicObject::~wxDynamicObject()
|
||||
{
|
||||
delete m_data ;
|
||||
delete m_superClassInstance ;
|
||||
}
|
||||
|
||||
void wxDynamicObject::SetProperty (const wxChar *propertyName, const wxxVariant &value)
|
||||
{
|
||||
wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),wxT("Accessing Unknown Property in a Dynamic Object") ) ;
|
||||
m_data->m_properties[propertyName] = value ;
|
||||
}
|
||||
|
||||
wxxVariant wxDynamicObject::GetProperty (const wxChar *propertyName) const
|
||||
{
|
||||
wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),wxT("Accessing Unknown Property in a Dynamic Object") ) ;
|
||||
return m_data->m_properties[propertyName] ;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDynamiClassInfo
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxDynamicClassInfo::wxDynamicClassInfo( const wxChar *unitName, const wxChar *className , const wxClassInfo* superClass ) :
|
||||
wxClassInfo( unitName, className , new const wxClassInfo*[2])
|
||||
{
|
||||
GetParents()[0] = superClass ;
|
||||
GetParents()[1] = NULL ;
|
||||
}
|
||||
|
||||
wxDynamicClassInfo::~wxDynamicClassInfo()
|
||||
{
|
||||
delete[] GetParents() ;
|
||||
}
|
||||
|
||||
wxObject *wxDynamicClassInfo::CreateObject() const
|
||||
{
|
||||
wxObject* parent = GetParents()[0]->CreateObject() ;
|
||||
return new wxDynamicObject( parent , this ) ;
|
||||
}
|
||||
|
||||
void wxDynamicClassInfo::Create (wxObject *object, int paramCount, wxxVariant *params) const
|
||||
{
|
||||
wxDynamicObject *dynobj = dynamic_cast< wxDynamicObject *>( object ) ;
|
||||
wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::Create on an object other than wxDynamicObject") ) ;
|
||||
GetParents()[0]->Create( dynobj->GetSuperClassInstance() , paramCount , params ) ;
|
||||
}
|
||||
|
||||
// get number of parameters for constructor
|
||||
int wxDynamicClassInfo::GetCreateParamCount() const
|
||||
{
|
||||
return GetParents()[0]->GetCreateParamCount() ;
|
||||
}
|
||||
|
||||
// get i-th constructor parameter
|
||||
const wxChar* wxDynamicClassInfo::GetCreateParamName(int i) const
|
||||
{
|
||||
return GetParents()[0]->GetCreateParamName( i ) ;
|
||||
}
|
||||
|
||||
void wxDynamicClassInfo::SetProperty(wxObject *object, const char *propertyName, const wxxVariant &value) const
|
||||
{
|
||||
wxDynamicObject* dynobj = dynamic_cast< wxDynamicObject * >( object ) ;
|
||||
wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ;
|
||||
if ( FindPropertyInfoInThisClass(propertyName) )
|
||||
dynobj->SetProperty( propertyName , value ) ;
|
||||
else
|
||||
GetParents()[0]->SetProperty( dynobj->GetSuperClassInstance() , propertyName , value ) ;
|
||||
}
|
||||
|
||||
wxxVariant wxDynamicClassInfo::GetProperty(wxObject *object, const char *propertyName) const
|
||||
{
|
||||
wxDynamicObject* dynobj = dynamic_cast< wxDynamicObject * >( object ) ;
|
||||
wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ;
|
||||
if ( FindPropertyInfoInThisClass(propertyName) )
|
||||
return dynobj->GetProperty( propertyName ) ;
|
||||
else
|
||||
return GetParents()[0]->GetProperty( dynobj->GetSuperClassInstance() , propertyName ) ;
|
||||
}
|
||||
|
||||
void wxDynamicClassInfo::AddProperty( const wxChar *propertyName , const wxTypeInfo* typeInfo )
|
||||
{
|
||||
new wxPropertyInfo( m_firstProperty , propertyName , "" , typeInfo , new wxGenericPropertyAccessor( propertyName ) , wxxVariant() ) ;
|
||||
}
|
||||
|
||||
void wxDynamicClassInfo::AddHandler( const wxChar *handlerName , wxObjectEventFunction address , const wxClassInfo* eventClassInfo )
|
||||
{
|
||||
new wxHandlerInfo( m_firstHandler , handlerName , address , eventClassInfo ) ;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGenericPropertyAccessor
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct wxGenericPropertyAccessor::wxGenericPropertyAccessorInternal
|
||||
{
|
||||
wxString m_propertyName ;
|
||||
} ;
|
||||
|
||||
wxGenericPropertyAccessor::wxGenericPropertyAccessor( const wxChar* propertyName )
|
||||
{
|
||||
m_data = new wxGenericPropertyAccessorInternal ;
|
||||
m_data->m_propertyName = propertyName ;
|
||||
}
|
||||
|
||||
wxGenericPropertyAccessor::~wxGenericPropertyAccessor()
|
||||
{
|
||||
delete m_data ;
|
||||
}
|
||||
void wxGenericPropertyAccessor::SetProperty(wxObject *object, const wxxVariant &value) const
|
||||
{
|
||||
wxDynamicObject* dynobj = dynamic_cast< wxDynamicObject * >( object ) ;
|
||||
wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ;
|
||||
dynobj->SetProperty(m_data->m_propertyName , value ) ;
|
||||
}
|
||||
|
||||
wxxVariant wxGenericPropertyAccessor::GetProperty(const wxObject *object) const
|
||||
{
|
||||
const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject * >( object ) ;
|
||||
wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ;
|
||||
return dynobj->GetProperty( m_data->m_propertyName ) ;
|
||||
}
|
||||
|
||||
wxxVariant wxGenericPropertyAccessor::ReadValue( const wxString &value ) const
|
||||
{
|
||||
return wxxVariant(value) ;
|
||||
}
|
||||
|
||||
void wxGenericPropertyAccessor::WriteValue( wxString& value , const wxObject *object ) const
|
||||
{
|
||||
const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject * >( object ) ;
|
||||
wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ;
|
||||
wxxVariant val = dynobj->GetProperty( m_data->m_propertyName ) ;
|
||||
value = val.GetAsString() ;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -63,12 +63,25 @@ void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo
|
||||
{
|
||||
if ( persister->BeforeWriteObject( object , classInfo , name ) )
|
||||
{
|
||||
int oid = m_data->m_nextId++ ;
|
||||
m_data->m_writtenObjects[object] = oid ;
|
||||
DoBeginWriteObject( object , classInfo , oid , name ) ;
|
||||
wxWriterInternalPropertiesData data ;
|
||||
WriteAllProperties( object , classInfo , persister , &data ) ;
|
||||
DoEndWriteObject( object , classInfo , oid , name ) ;
|
||||
if ( object == NULL || IsObjectKnown( object ) )
|
||||
{
|
||||
DoWriteObjectReference( NULL , NULL , object , classInfo , GetObjectID(object) , NULL ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
int oid = m_data->m_nextId++ ;
|
||||
m_data->m_writtenObjects[object] = oid ;
|
||||
// in case this object is a wxDynamicObject we also have to insert is superclass
|
||||
// instance with the same id, so that object relations are streamed out correctly
|
||||
const wxDynamicObject* dynobj = dynamic_cast<const wxDynamicObject *>( object ) ;
|
||||
if ( dynobj )
|
||||
m_data->m_writtenObjects[dynobj->GetSuperClassInstance()] = oid ;
|
||||
|
||||
DoBeginWriteObject( object , classInfo , oid , name ) ;
|
||||
wxWriterInternalPropertiesData data ;
|
||||
WriteAllProperties( object , classInfo , persister , &data ) ;
|
||||
DoEndWriteObject( object , classInfo , oid , name ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +111,15 @@ void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci
|
||||
{
|
||||
int oid = m_data->m_nextId++ ;
|
||||
if ( !embeddedObject)
|
||||
{
|
||||
// insert this object and its id
|
||||
m_data->m_writtenObjects[vobj] = oid ;
|
||||
// in case this object is a wxDynamicObject we also have to insert is superclass
|
||||
// instance with the same id, so that object relations are streamed out correctly
|
||||
const wxDynamicObject* dynobj = dynamic_cast<const wxDynamicObject *>( vobj ) ;
|
||||
if ( dynobj )
|
||||
m_data->m_writtenObjects[dynobj->GetSuperClassInstance()] = oid ;
|
||||
}
|
||||
|
||||
DoBeginWriteParamAsObject( obj , ci , vobj , pci , oid , pi ) ;
|
||||
if ( vobj != NULL )
|
||||
@@ -177,6 +198,11 @@ void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci
|
||||
}
|
||||
pi = pi->GetNext() ;
|
||||
}
|
||||
// in case this object is wxDynamic object we have to hand over the streaming
|
||||
// of the properties of the superclasses to the real super class instance
|
||||
const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject* > (obj ) ;
|
||||
if ( dynobj )
|
||||
obj = dynobj->GetSuperClassInstance() ;
|
||||
const wxClassInfo** parents = ci->GetParents() ;
|
||||
for ( int i = 0 ; parents[i] ; ++ i )
|
||||
{
|
||||
@@ -589,6 +615,13 @@ void wxRuntimeDepersister::CreateObject(int objectID,
|
||||
{
|
||||
wxObject *o;
|
||||
o = m_data->GetObject(objectIdValues[i]);
|
||||
// if this is a dynamic object and we are asked for another class
|
||||
// than wxDynamicObject we cast it down manually.
|
||||
wxDynamicObject *dyno = dynamic_cast< wxDynamicObject * > (o) ;
|
||||
if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) )
|
||||
{
|
||||
o = dyno->GetSuperClassInstance() ;
|
||||
}
|
||||
params[i] = objectClassInfos[i]->InstanceToVariant(o) ;
|
||||
}
|
||||
}
|
||||
@@ -603,25 +636,36 @@ void wxRuntimeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(cla
|
||||
}
|
||||
|
||||
void wxRuntimeDepersister::SetProperty(int objectID,
|
||||
const wxClassInfo *WXUNUSED(classInfo),
|
||||
const wxClassInfo *classInfo,
|
||||
const wxPropertyInfo* propertyInfo,
|
||||
const wxxVariant &value)
|
||||
{
|
||||
wxObject *o;
|
||||
o = m_data->GetObject(objectID);
|
||||
propertyInfo->GetAccessor()->SetProperty( o , value ) ;
|
||||
classInfo->SetProperty( o , propertyInfo->GetName() , value ) ;
|
||||
// propertyInfo->GetAccessor()->SetProperty( o , value ) ;
|
||||
}
|
||||
|
||||
void wxRuntimeDepersister::SetPropertyAsObject(int objectID,
|
||||
const wxClassInfo *WXUNUSED(classInfo),
|
||||
const wxClassInfo *classInfo,
|
||||
const wxPropertyInfo* propertyInfo,
|
||||
int valueObjectId)
|
||||
{
|
||||
wxObject *o, *valo;
|
||||
o = m_data->GetObject(objectID);
|
||||
valo = m_data->GetObject(valueObjectId);
|
||||
propertyInfo->GetAccessor()->SetProperty( o ,
|
||||
(dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo()->InstanceToVariant(valo) ) ;
|
||||
const wxClassInfo* valClassInfo = (dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo() ;
|
||||
// if this is a dynamic object and we are asked for another class
|
||||
// than wxDynamicObject we cast it down manually.
|
||||
wxDynamicObject *dynvalo = dynamic_cast< wxDynamicObject * > (valo) ;
|
||||
if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) )
|
||||
{
|
||||
valo = dynvalo->GetSuperClassInstance() ;
|
||||
}
|
||||
|
||||
classInfo->SetProperty( o , propertyInfo->GetName() , valClassInfo->InstanceToVariant(valo) ) ;
|
||||
// propertyInfo->GetAccessor()->SetProperty( o ,
|
||||
// (dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo()->InstanceToVariant(valo) ) ;
|
||||
}
|
||||
|
||||
void wxRuntimeDepersister::SetConnect(int eventSourceObjectID,
|
||||
|
Reference in New Issue
Block a user