in src/codegen/tool/GenerateCSharpClasses.cpp [425:855]
void CGenerateCSharpClasses::codeGenerate(const schema::CObservableObjectInfo *pPropertyModelInfo)
{
bool isViewModel = pPropertyModelInfo->getModelType() == schema::ModelTypeInfoType_ViewModel;
std::wstring typeInfoName = toTypeInfoName(pPropertyModelInfo->getName());
_typeInfoClasses[pPropertyModelInfo->getType()] = typeInfoName;
std::wstring baseClass;
std::wostringstream osInternalProperties;
std::wostringstream osInitializeCommandProperties;
std::wostringstream osInitializeCollectionProperties;
std::wostringstream osInvokeInternalMethods;
std::wostringstream osCommandCallbackInterface;
std::wostringstream osExecuteCommandPropertyCallback;
std::wostringstream osCanExecuteCommandPropertyCallback;
std::wostringstream osInitializeCommandPropertiesCallback;
const schema::CObservableObjectInfo *pBaseType = (schema::CObservableObjectInfo *)pPropertyModelInfo->getBaseType();
if (pBaseType != nullptr)
{
baseClass = this->getNamespaceLookup(pBaseType->getParent().getNamespace());
baseClass += L".";
baseClass += toTypeInfoName(pBaseType->getName());
}
else
{
baseClass = isViewModel ? L"ViewModel" : L"ObservableObject";
}
// Iterate Properties
for(schema::_PropertyIteratorType::const_iterator iter = pPropertyModelInfo->getProperties().begin();
iter != pPropertyModelInfo->getProperties().end();
++iter)
{
bool isAncestorProperty = ((*iter)->getFlags() & PropertyFlagType_IsAncestor) != 0;
bool isParentProperty = (*iter)->isParent();
bool isCoreReadyOnly = isAncestorProperty || isParentProperty;
// Emit Internal Property Access
std::wstring propertyAccessName = (*iter)->getName();
if (propertyAccessName == L"Invoke")
{
// workaround to prevent compiler to fail on this keyword
propertyAccessName += L"_";
}
osInternalProperties << FormatW(
_internalProperty_Template,
(*iter)->getName().data(),
toCSharpPropertyTypeInfo(*iter).data(),
this->getNamespace().data(),
typeInfoName.data(),
propertyAccessName.data(),
nullptr);
// Emit Initialize Property
if(!isCoreReadyOnly && (*iter)->getModelType())
{
schema::ModelTypeInfoType modelTypeInfoType = (*iter)->getModelType()->getModelType();
if(modelTypeInfoType == schema::ModelTypeInfoType_Command)
{
const schema::CCommandTypeInfo *pCommmandModelInfo = (schema::CCommandTypeInfo *)((*iter)->getModelType());
const schema::CPropertyTypeInfo *pParameterTypeInfo = pCommmandModelInfo->getParameterTypeInfo();
const schema::CPropertyTypeInfo *pResutTypeInfo = pCommmandModelInfo->getResultTypeInfo();
const bool isAsync = pCommmandModelInfo->getIsAsync();
std::wstring typeIID;
if (isSimpleCommand(pCommmandModelInfo))
{
typeIID = FormatW(
L"new Guid(\"{0}\")",
isAsync ? _simpleAsyncCommandTypeId : _simpleCommandTypeId,
nullptr);
}
else if (isObjectObjectCommand(pCommmandModelInfo))
{
typeIID = FormatW(
L"new Guid(\"{0}\")",
isAsync ? _objectObjectAsyncCommandTypeId : _objectObjectCommandTypeId,
nullptr);
}
else
{
std::wstring commandModelInfoNameInc = getModelTypeInfoIncName(pCommmandModelInfo);
typeIID = FormatW(L"{0}.TypeInfoClass.IID_{1}",
this->getNamespaceLookup(pCommmandModelInfo->getParent().getNamespace()).c_str(),
commandModelInfoNameInc.c_str(),
nullptr);
}
std::wstring commandModelOptions = isAsync ?
L"(CommandOptions)(CommonModelOptions.IsFreeThreadApartment)":
L"CommandOptions.None";
std::wstring cSharpParameterTypeInfo = toCSharpInterfacePropertyTypeInfo(pParameterTypeInfo);
std::wstring cSharpResultTypeInfo = toCSharpInterfacePropertyTypeInfo(pResutTypeInfo);
if (!_useClassInterfaceCallback)
{
osInitializeCommandProperties << "\t\t\t" <<
FormatW(L"{0} = new ContainedCommand<{1},{2},{3}>({4},{5},\"{0}\");",
propertyAccessName.data(),
typeInfoName.data(),
cSharpParameterTypeInfo.data(),
cSharpResultTypeInfo.data(),
commandModelOptions.data(),
typeIID.data(),
nullptr) << std::endl;
}
osCommandCallbackInterface << "\t\t";
bool isVoidResult = pResutTypeInfo->getPropertyType() == foundation::PropertyType_Empty;
bool isVoidParameter = pParameterTypeInfo->getPropertyType() == foundation::PropertyType_Empty;
if (isAsync || isVoidResult)
{
osCommandCallbackInterface << "void";
}
else
{
osCommandCallbackInterface << cSharpResultTypeInfo;
}
osCommandCallbackInterface << " Execute" << propertyAccessName << "(";
std::wstring executeCallbackParams;
if (!isVoidParameter)
{
osCommandCallbackInterface << cSharpParameterTypeInfo << " parameter";
executeCallbackParams = FormatW(
L"parameter.{0}<{1}>()",
isAsync ? L"GetAsyncCommandParameter" : L"AssertCast",
cSharpParameterTypeInfo.c_str(),
nullptr);
}
if (isAsync)
{
if (!isVoidParameter)
{
osCommandCallbackInterface << ",";
executeCallbackParams += L",";
}
osCommandCallbackInterface << "AsyncOperation asyncOperation";
executeCallbackParams += L"parameter.GetAsyncCommandOperation()";
}
osCommandCallbackInterface << ");" << std::endl;
osExecuteCommandPropertyCallback << FormatW(_onExecuteCommandPropertyCallbackInternal_Template,
toTypeInfoName(pPropertyModelInfo->getName()).c_str(),
(*iter)->getName().data(),
executeCallbackParams.c_str(),
isAsync || isVoidResult ? L"" : L"result =",
nullptr);
if (pCommmandModelInfo->getIsUnknownState())
{
osCommandCallbackInterface << "\t\tbool CanExecute" << propertyAccessName << "(";
if (!isVoidParameter)
{
osCommandCallbackInterface << cSharpParameterTypeInfo << " parameter";
}
osCommandCallbackInterface << ");" << std::endl;
osCanExecuteCommandPropertyCallback << FormatW(
_onCanExecuteCommandPropertyCallbackInternal_Template,
toTypeInfoName(pPropertyModelInfo->getName()).c_str(),
(*iter)->getName().data(),
isVoidParameter ? L"" : FormatW(L"parameter.AssertCast<{0}>()", cSharpParameterTypeInfo.c_str(), nullptr).c_str(),
nullptr);
}
osInitializeCommandPropertiesCallback << "\t\t\t" <<
FormatW(L"model.SetPropertyInternal((uint){3}Properties.{0},PropertyModelHelper.CreatePropertyCommand({1},{2},(uint){3}Properties.{0},callbacks));",
propertyAccessName.data(),
commandModelOptions.data(),
typeIID.data(),
typeInfoName.data(),
nullptr) << std::endl;
}
else if(modelTypeInfoType == schema::ModelTypeInfoType_ObservableCollection || modelTypeInfoType == schema::ModelTypeInfoType_ObservableList)
{
std::wstring typeIID;
const schema::CEnumerableTypeInfo *pCollectionModelInfo = (schema::CEnumerableTypeInfo *)((*iter)->getModelType());
const schema::CPropertyTypeInfo *pItemTypeInfo = pCollectionModelInfo->getItemTypeInfo();
if(pItemTypeInfo->getModelType() != nullptr)
{
std::wstring collectionModelInfoNameInc = getModelTypeInfoIncName(pCollectionModelInfo);
typeIID = FormatW(L"{0}.TypeInfoClass.IID_{1}",
this->getNamespaceLookup(pCollectionModelInfo->getParent().getNamespace()).c_str(),
collectionModelInfoNameInc.c_str(),
nullptr);
}
else
{
// a 'Core' type
foundation::PropertyType propertyType = pItemTypeInfo->getPropertyType();
// lookup for supported 'Core' types
if(propertyType == foundation::PropertyType::PropertyType_String)
{
typeIID = L"StringType";
}
else if(propertyType == foundation::PropertyType::PropertyType_Int16)
{
typeIID = L"Int16Type";
}
else if(propertyType == foundation::PropertyType::PropertyType_UInt16)
{
typeIID = L"UInt16Type";
}
else if(propertyType == foundation::PropertyType::PropertyType_Int32)
{
typeIID = L"Int32Type";
}
else if(propertyType == foundation::PropertyType::PropertyType_UInt32)
{
typeIID = L"UInt32Type";
}
else if(propertyType == foundation::PropertyType::PropertyType_Boolean)
{
typeIID = L"BooleanType";
}
else if(propertyType == foundation::PropertyType::PropertyType_DateTime)
{
typeIID = L"DateTimeType";
}
else if(propertyType == foundation::PropertyType::PropertyType_UInt8)
{
typeIID = L"ByteType";
}
else
{
typeIID = L"ObjectType";
}
typeIID = L"CollectionModel." + typeIID;
}
osInitializeCollectionProperties << "\t\t\t" <<
FormatW(L"{0} = new CollectionModel({1},ObservableCollectionOptions.None);",propertyAccessName.data(),typeIID.data(),nullptr) << std::endl;
}
}
}
if (osCommandCallbackInterface.tellp())
{
const schema::CObservableObjectInfo *pCommandCallbackBaseType = nullptr;
for (pCommandCallbackBaseType = pBaseType;
pCommandCallbackBaseType != nullptr;
pCommandCallbackBaseType = (const schema::CObservableObjectInfo *)pCommandCallbackBaseType->getBaseType())
{
if (countCommandProperties(pCommandCallbackBaseType))
{
break;
}
}
_osCSharpClassesSrc << FormatW(
_commandPropertyCallbackInterface_Template,
typeInfoName.data(),
osCommandCallbackInterface.str().data(),
pCommandCallbackBaseType ?
FormatW(L": {0}.I{1}CommandCallback",
this->getNamespaceLookup(pCommandCallbackBaseType->getParent().getNamespace()).c_str(),
toTypeInfoName(pCommandCallbackBaseType->getName()).c_str(),
nullptr
).c_str() :
L"",
nullptr
);
_osCSharpClassesSrc << FormatW(
_commandPropertyCallbackClass_Template,
typeInfoName.data(),
osExecuteCommandPropertyCallback.str().data(),
osCanExecuteCommandPropertyCallback.str().data(),
pCommandCallbackBaseType ?
FormatW(L" {0}.{1}",
this->getNamespaceLookup(pCommandCallbackBaseType->getParent().getNamespace()).c_str(),
toTypeInfoName(pCommandCallbackBaseType->getName()).c_str(),
nullptr
).c_str() :
L"",
osInitializeCommandPropertiesCallback.str().c_str(),
nullptr
);
}
std::wostringstream osMethodCallbackInterface;
std::wostringstream osMethodCallbackInvokeCallback;
// Iterate Methods
for(schema::_MethodIteratorType::const_iterator iter = pPropertyModelInfo->getMethods().begin();
iter != pPropertyModelInfo->getMethods().end();
++iter)
{
bool isVoidResult =
(*iter)->getResultType()->getPropertyType() == foundation::PropertyType_Empty;
osMethodCallbackInterface << "\t\t";
if ((*iter)->getIsAsync() || isVoidResult)
{
osMethodCallbackInterface << "void";
}
else
{
osMethodCallbackInterface << toCSharpInterfacePropertyTypeInfo((*iter)->getResultType());
}
osMethodCallbackInterface << " ";
osMethodCallbackInterface << (*iter)->getName();
osMethodCallbackInterface << "(";
std::wostringstream osInvokeParameters;
for(schema::_MethodParamIteratorType::const_iterator iterParam = (*iter)->getParameters().begin();
iterParam != (*iter)->getParameters().end();
++iterParam)
{
std::wstring cSharpTypeInfo = toCSharpInterfacePropertyTypeInfo(*iterParam);
if (iterParam != (*iter)->getParameters().begin())
{
osMethodCallbackInterface << ",";
osInvokeParameters << "," << std::endl;
}
osMethodCallbackInterface << cSharpTypeInfo << " " << (*iterParam)->getParameterName();
osInvokeParameters << "\t\t\t\t\t";
osInvokeParameters << "parameters[" << (int)(iterParam-(*iter)->getParameters().begin())
<< "].AssertCast<" << cSharpTypeInfo << ">()";
}
if ((*iter)->getIsAsync())
{
if ((*iter)->getParameters().size())
{
osInvokeParameters << "," << std::endl;
osMethodCallbackInterface << ",";
}
osMethodCallbackInterface << "AsyncOperation asyncOperation";
osInvokeParameters << "\t\t\t\t\t";
osInvokeParameters << "parameters[" << (int)((*iter)->getParameters().size()) << "].AssertCast<AsyncOperation>()";
}
osMethodCallbackInterface << ");" << std::endl;
std::wstring invokeName = L"\"Invoke" + (*iter)->getName() + L"\"";
if ((*iter)->getIsAsync() || (*iter)->getParameters().size())
{
invokeName += L",";
}
bool isVoidResultCallback = (*iter)->getIsAsync() || isVoidResult;
osMethodCallbackInvokeCallback << FormatW(_onInvokeCallbackInternal_Template,
toTypeInfoName(pPropertyModelInfo->getName()).c_str(),
(*iter)->getName().data(),
osInvokeParameters.str().data(),
isVoidResultCallback ? L"":L"result =",
nullptr);
osInvokeInternalMethods << FormatW(_onInvokeInternal_Template,
toTypeInfoName(pPropertyModelInfo->getName()).c_str(),
(*iter)->getName().data(),
invokeName.data(),
osInvokeParameters.str().data(),
nullptr);
}
if (pPropertyModelInfo->getMethods().size())
{
const schema::CObservableObjectInfo *pMethodCallbackBaseType =
pBaseType && pBaseType->getMethods().size() ? pBaseType :
nullptr;
_osCSharpClassesSrc << FormatW(
_methodCallbackInterface_Template,
typeInfoName.data(),
osMethodCallbackInterface.str().data(),
pMethodCallbackBaseType ?
FormatW(L": {0}.I{1}MethodCallback",
this->getNamespaceLookup(pBaseType->getParent().getNamespace()).c_str(),
toTypeInfoName(pBaseType->getName()).c_str(),
nullptr
).c_str() :
L"",
nullptr
);
_osCSharpClassesSrc << FormatW(
_methodCallbackClass_Template,
typeInfoName.data(),
osMethodCallbackInvokeCallback.str().data(),
pMethodCallbackBaseType ?
FormatW(L"{0}.{1}",
this->getNamespaceLookup(pBaseType->getParent().getNamespace()).c_str(),
toTypeInfoName(pBaseType->getName()).c_str(),
nullptr
).c_str() :
L"",
pMethodCallbackBaseType ? L"new" : L"",
nullptr
);
}
// Emit C# Class implementation
_osCSharpClassesSrc << FormatW(
isViewModel ? _implementViewModelClass_Template:_implementModelClass_Template,
typeInfoName.data(),
baseClass.data(),
L"",
_useClassInterfaceCallback && osCommandCallbackInterface.tellp() ?
FormatW(_initializeCommandPropertyCallbackInternal_Template,
typeInfoName.data(),
nullptr).c_str() :
osInitializeCommandProperties.str().data(),
osInitializeCollectionProperties.str().data(),
osInternalProperties.str().data(),
!_useClassInterfaceCallback && pPropertyModelInfo->getMethods().size() ?
FormatW(_onInvokeImplement_Template,osInvokeInternalMethods.str().data(),nullptr).data():
L"",
_useClassInterfaceCallback && pPropertyModelInfo->getMethods().size() ?
FormatW(_initializeMethodCallbackInternal_Template, typeInfoName.data(), nullptr).data() :
L"",
pPropertyModelInfo->getBaseType() ? L"new" : L"",
nullptr
);
}