bool canSerializeField(const GMetaArchiveConfig & config, IMetaAccessible * accessible, IMetaService * service) { if(accessible == NULL) { return false; } if(! accessible->canGet()) { return false; } if(! accessible->canSet()) { return false; } GMetaType metaType = metaGetItemType(accessible); if(! canSerializeMetaType(metaType)) { return false; } if(metaType.getBaseName() != NULL) { GScopedInterface<IMetaClass> metaClass(service->findClassByName(metaType.getBaseName())); if(! canSerializeObject(config, metaClass.get())) { return false; } } return canSerializeItem(config, accessible); }
GScriptValue doCreateScriptValueFromVariant( const GContextPointer & context, const GVariant & value, const GMetaType & type, const bool transferOwnership ) { const GVariantType vt = static_cast<GVariantType>((GVtType)value.getType() & ~(GVtType)GVariantType::maskByReference); if(! type.isEmpty() && type.getPointerDimension() <= 1) { GScopedInterface<IMetaTypedItem> typedItem(context->getService()->findTypedItemByName(type.getBaseName())); if(typedItem) { GASSERT_MSG(!! metaIsClass(typedItem->getCategory()), "Unknown type"); return GScriptValue::fromObject(value, gdynamic_cast<IMetaClass *>(typedItem.get()), transferOwnership, metaTypeToCV(type)); } else { if(vtIsInterface(vt)) { IObject * obj = fromVariant<IObject *>(value); if(IMetaClass * metaClass = dynamic_cast<IMetaClass *>(obj)) { return GScriptValue::fromClass(metaClass); } } } } return GScriptValue::fromPrimary(value); }
bool canSerializeMetaType(const GMetaType & metaType) { if(metaType.getPointerDimension() > 1) { return false; } if(metaType.getPointerDimension() > 0) { return metaType.baseIsClass(); } return true; }
GVariant GMetaCore::cast(const GVariant & instance, IMetaClass * targetMetaClass) { GVariant value = getVariantRealValue(instance); GMetaType type = getVariantRealMetaType(instance); if(canFromVariant<void *>(value) && type.getBaseName() != NULL) { GScopedInterface<IMetaService> metaService(this->scriptObject->getMetaService()); GScopedInterface<IMetaClass> sourceClass(metaService->findClassByName(type.getBaseName())); if(sourceClass) { void * ptr = objectAddressFromVariant(instance); void * oldPtr = ptr; if(ptr != NULL) { GMetaType targetType; if(targetMetaClass != NULL) { ptr = metaCastToDerived(oldPtr, sourceClass.get(), targetMetaClass); if(ptr == NULL) { ptr = metaCastToBase(oldPtr, sourceClass.get(), targetMetaClass); } targetType = metaGetItemType(targetMetaClass); } else { GScopedInterface<IMetaClass> derivedClass(findAppropriateDerivedClass(oldPtr, sourceClass.get(), &ptr)); if(derivedClass) { targetType = metaGetItemType(derivedClass.get()); } else { ptr = NULL; } } if(ptr != NULL) { targetType.addPointer(); return createTypedVariant(pointerToObjectVariant(ptr), targetType); } } } } return (void *)0; }
void writeFundamental(void * address, const GMetaType & metaType, const GVariant & v) { size_t size = metaType.getVariantSize();; if(vtIsReal(metaType.getVariantType())) { switch(size) { case 4: *(GFixedTypeFloat32::Signed *)(address) = fromVariant<GFixedTypeFloat32::Signed>(v); break; case 8: *(GFixedTypeFloat64::Signed *)(address) = fromVariant<GFixedTypeFloat64::Signed>(v); break; default: if(metaType.getVariantType() == vtLongDouble) { // long double has vary size on GCC... *(GFixedTypeFloat80::Signed *)(address) = fromVariant<GFixedTypeFloat80::Signed>(v); break; } GASSERT(false); break; } } else { switch(metaType.getVariantType()) { case vtBool: doWriteInteger<bool>(address, size, v); break; case vtChar: doWriteInteger<char>(address, size, v); break; case vtWchar: doWriteInteger<wchar_t>(address, size, v); break; case vtSignedChar: doWriteInteger<signed char>(address, size, v); break; case vtUnsignedChar: doWriteInteger<unsigned char>(address, size, v); break; case vtSignedShort: doWriteInteger<signed short>(address, size, v); break; case vtUnsignedShort: doWriteInteger<unsigned short>(address, size, v); break; case vtSignedInt: doWriteInteger<signed int>(address, size, v); break; case vtUnsignedInt: doWriteInteger<unsigned int>(address, size, v); break; case vtSignedLong: doWriteInteger<signed long>(address, size, v); break; case vtUnsignedLong: doWriteInteger<unsigned long>(address, size, v); break; case vtSignedLongLong: doWriteInteger<signed long long>(address, size, v); break; case vtUnsignedLongLong: doWriteInteger<unsigned long long>(address, size, v); break; default: GASSERT(false); break; } } }
GVariant readFundamental(const void * address, const GMetaType & metaType) { size_t size = metaType.getVariantSize(); if(vtIsReal(metaType.getVariantType())) { switch(size) { case 4: return *(GFixedTypeFloat32::Signed *)(address); case 8: return *(GFixedTypeFloat64::Signed *)(address); default: if(metaType.getVariantType() == vtLongDouble) { // long double has vary size on GCC... return *(GFixedTypeFloat80::Signed *)(address); break; } GASSERT(false); break; } } else { switch(metaType.getVariantType()) { case vtBool: return doReadInteger<bool>(address, size); case vtChar: return doReadInteger<char>(address, size); case vtWchar: return doReadInteger<wchar_t>(address, size); case vtSignedChar: return doReadInteger<signed char>(address, size); case vtUnsignedChar: return doReadInteger<unsigned char>(address, size); case vtSignedShort: return doReadInteger<signed short>(address, size); case vtUnsignedShort: return doReadInteger<unsigned short>(address, size); case vtSignedInt: return doReadInteger<signed int>(address, size); case vtUnsignedInt: return doReadInteger<unsigned int>(address, size); case vtSignedLong: return doReadInteger<signed long>(address, size); case vtUnsignedLong: return doReadInteger<unsigned long>(address, size); case vtSignedLongLong: return doReadInteger<signed long long>(address, size); case vtUnsignedLongLong: return doReadInteger<unsigned long long>(address, size); default: GASSERT(false); break; } } return GVariant(); }