xtixml.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 542 行 · 第 1/2 页
CPP
542 行
return wxInvalidObjectID ;
}
// new object, start with allocation
// first make the object know to our internal registry
SetObjectClassInfo( objectID , classInfo ) ;
wxxVariantArray metadata ;
wxXmlProperty *xp = node->GetProperties() ;
while ( xp )
{
if ( xp->GetName() != wxString(wxT("class")) && xp->GetName() != wxString(wxT("id")) )
{
metadata.Add( new wxxVariant( xp->GetValue() , xp->GetName() ) ) ;
}
xp = xp->GetNext() ;
}
if ( !classInfo->NeedsDirectConstruction() )
callbacks->AllocateObject(objectID, classInfo, metadata);
//
// stream back the Create parameters first
createParams = new wxxVariant[ classInfo->GetCreateParamCount() ] ;
createParamOids = new int[classInfo->GetCreateParamCount() ] ;
createClassInfos = new const wxClassInfo*[classInfo->GetCreateParamCount() ] ;
#if wxUSE_UNICODE
typedef map<wstring, wxXmlNode *> PropertyNodes ;
typedef vector<wstring> PropertyNames ;
#else
typedef map<string, wxXmlNode *> PropertyNodes ;
typedef vector<string> PropertyNames ;
#endif
PropertyNodes propertyNodes ;
PropertyNames propertyNames ;
while( children )
{
wxString name ;
children->GetPropVal( wxT("name") , &name ) ;
propertyNames.push_back( name.c_str() ) ;
propertyNodes[name.c_str()] = children->GetChildren() ;
children = children->GetNext() ;
}
for ( int i = 0 ; i <classInfo->GetCreateParamCount() ; ++i )
{
const wxChar* paramName = classInfo->GetCreateParamName(i) ;
PropertyNodes::iterator propiter = propertyNodes.find( paramName ) ;
const wxPropertyInfo* pi = classInfo->FindPropertyInfo( paramName ) ;
if ( pi == 0 )
{
wxLogError( wxString::Format(_("Unkown Property %s"),paramName) ) ;
}
// if we don't have the value of a create param set in the xml
// we use the default value
if ( propiter != propertyNodes.end() )
{
wxXmlNode* prop = propiter->second ;
if ( pi->GetTypeInfo()->IsObjectType() )
{
createParamOids[i] = ReadComponent( prop , callbacks ) ;
createClassInfos[i] = dynamic_cast<const wxClassTypeInfo*>(pi->GetTypeInfo())->GetClassInfo() ;
}
else
{
createParamOids[i] = wxInvalidObjectID ;
createParams[i] = ReadValue( prop , pi->GetTypeInfo() ) ;
if( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
{
const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
if ( eti )
{
long realval ;
eti->ConvertToLong( createParams[i] , realval ) ;
createParams[i] = wxxVariant( realval ) ;
}
else
{
wxLogError( _("Type must have enum - long conversion") ) ;
}
}
createClassInfos[i] = NULL ;
}
for ( size_t j = 0 ; j < propertyNames.size() ; ++j )
{
if ( propertyNames[j] == paramName )
{
propertyNames[j] = wxEmptyString ;
break ;
}
}
}
else
{
if ( pi->GetTypeInfo()->IsObjectType() )
{
createParamOids[i] = wxNullObjectID ;
createClassInfos[i] = dynamic_cast<const wxClassTypeInfo*>(pi->GetTypeInfo())->GetClassInfo() ;
}
else
{
createParams[i] = pi->GetDefaultValue() ;
createParamOids[i] = wxInvalidObjectID ;
}
}
}
// got the parameters. Call the Create method
if ( classInfo->NeedsDirectConstruction() )
callbacks->ConstructObject(objectID, classInfo,
classInfo->GetCreateParamCount(),
createParams, createParamOids, createClassInfos, metadata );
else
callbacks->CreateObject(objectID, classInfo,
classInfo->GetCreateParamCount(),
createParams, createParamOids, createClassInfos, metadata );
// now stream in the rest of the properties, in the sequence their properties were written in the xml
for ( size_t j = 0 ; j < propertyNames.size() ; ++j )
{
if ( propertyNames[j].length() )
{
PropertyNodes::iterator propiter = propertyNodes.find( propertyNames[j] ) ;
if ( propiter != propertyNodes.end() )
{
wxXmlNode* prop = propiter->second ;
const wxPropertyInfo* pi = classInfo->FindPropertyInfo( propertyNames[j].c_str() ) ;
if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
{
const wxCollectionTypeInfo* collType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() ) ;
const wxTypeInfo * elementType = collType->GetElementType() ;
while( prop )
{
if ( prop->GetName() != wxT("element") )
{
wxLogError( _("A non empty collection must consist of 'element' nodes" ) ) ;
break ;
}
wxXmlNode* elementContent = prop->GetChildren() ;
if ( elementContent )
{
// we skip empty elements
if ( elementType->IsObjectType() )
{
int valueId = ReadComponent( elementContent , callbacks ) ;
if ( valueId != wxInvalidObjectID )
{
if ( pi->GetAccessor()->HasAdder() )
callbacks->AddToPropertyCollectionAsObject( objectID , classInfo , pi , valueId ) ;
// TODO for collections we must have a notation on taking over ownership or not
if ( elementType->GetKind() == wxT_OBJECT && valueId != wxNullObjectID )
callbacks->DestroyObject( valueId , GetObjectClassInfo( valueId ) ) ;
}
}
else
{
wxxVariant elementValue = ReadValue( elementContent , elementType ) ;
if ( pi->GetAccessor()->HasAdder() )
callbacks->AddToPropertyCollection( objectID , classInfo ,pi , elementValue ) ;
}
}
prop = prop->GetNext() ;
}
}
else if ( pi->GetTypeInfo()->IsObjectType() )
{
// and object can either be streamed out a string or as an object
// in case we have no node, then the object's streaming out has been vetoed
if ( prop )
{
if ( prop->GetName() == wxT("object") )
{
int valueId = ReadComponent( prop , callbacks ) ;
if ( valueId != wxInvalidObjectID )
{
callbacks->SetPropertyAsObject( objectID , classInfo , pi , valueId ) ;
if ( pi->GetTypeInfo()->GetKind() == wxT_OBJECT && valueId != wxNullObjectID )
callbacks->DestroyObject( valueId , GetObjectClassInfo( valueId ) ) ;
}
}
else
{
wxASSERT( pi->GetTypeInfo()->HasStringConverters() ) ;
wxxVariant nodeval = ReadValue( prop , pi->GetTypeInfo() ) ;
callbacks->SetProperty( objectID, classInfo ,pi , nodeval ) ;
}
}
}
else if ( pi->GetTypeInfo()->IsDelegateType() )
{
if ( prop )
{
wxString resstring = prop->GetContent() ;
wxInt32 pos = resstring.Find('.') ;
if ( pos != wxNOT_FOUND )
{
int sinkOid = atol(resstring.Left(pos).ToAscii()) ;
wxString handlerName = resstring.Mid(pos+1) ;
wxClassInfo* sinkClassInfo = GetObjectClassInfo( sinkOid ) ;
callbacks->SetConnect( objectID , classInfo , pi , sinkClassInfo ,
sinkClassInfo->FindHandlerInfo(handlerName) , sinkOid ) ;
}
else
{
wxLogError( _("incorrect event handler string, missing dot") ) ;
}
}
}
else
{
wxxVariant nodeval = ReadValue( prop , pi->GetTypeInfo() ) ;
if( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
{
const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
if ( eti )
{
long realval ;
eti->ConvertToLong( nodeval , realval ) ;
nodeval = wxxVariant( realval ) ;
}
else
{
wxLogError( _("Type must have enum - long conversion") ) ;
}
}
callbacks->SetProperty( objectID, classInfo ,pi , nodeval ) ;
}
}
}
}
delete[] createParams ;
delete[] createParamOids ;
delete[] createClassInfos ;
return objectID;
}
wxxVariant wxXmlReader::ReadValue(wxXmlNode *node,
const wxTypeInfo *type )
{
wxString content ;
if ( node )
content = node->GetContent() ;
wxxVariant result ;
type->ConvertFromString( content , result ) ;
return result ;
}
int wxXmlReader::ReadObject( const wxString &name , wxDepersister *callbacks)
{
wxXmlNode *iter = m_parent->GetChildren() ;
while ( iter )
{
wxString entryName ;
if ( iter->GetPropVal(wxT("name"), &entryName) )
{
if ( entryName == name )
return ReadComponent( iter->GetChildren() , callbacks ) ;
}
iter = iter->GetNext() ;
}
return wxInvalidObjectID ;
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?