in src/codegen/tool/GenerateFastCppTemplate.cpp [769:1118]
void CGenerateFastCppTemplate::codeGenerate(const schema::CObservableObjectInfo *pPropertyModelInfo)
{
std::wstring typeInfoName = toTypeInfoName(pPropertyModelInfo->getName());
std::wstring typeInfoNameCodeGen = this->toCodeGenTypeName(typeInfoName.c_str());
// default base container class
std::wstring typeInfoBaseNameCodeGen = L"pmod::library::_FastPropertiesContainer<T>";
// default base model class
std::wstring modelClassBaseNameCodeGen = L"pmod::FastModelBase<T, TInterface, TBASE, _ModelContainerType>";
std::wstring modelBaseDefinition = L" pmod::library::_ObservableObjectAdapterBaseImpl\n\
<\n\
foundation::_ObjectAdapterBase\n\
<\n\
pmod::library::_FastBaseHelper<TBASE, TModelPrivateInterface>\n\
>\n\
>\n";
// typedef for base classes that are not inheriting from any class.
std::wstring typeDefBaseClass = FormatW(L"typedef _Fast{0}<> _Fast{0}Base;\n\n",typeInfoNameCodeGen.data(),nullptr);
std::wstring baseAdapterType = L"pmod::library::_ObservableObjectAdapterBase<TInterface, piid>";
std::wstring baseFriendAccess = L"";
std::wstring custombaseTypeQI = L"";
std::wstring initializeMethodName = L"_InitializeModel";
std::wostringstream baseMemberDelegates;
std::wostringstream baseMemberQualifications;
// check for base type
if (pPropertyModelInfo->getBaseType())
{
std::wstring typeInfoBaseName = toTypeInfoName(pPropertyModelInfo->getBaseType()->getName());
baseAdapterType = L"T"+ typeInfoBaseName + L"FastModelAdapter<TInterface, piid>";
//Attach template params
typeInfoBaseNameCodeGen = L"_Fast" + this->toCodeGenTypeName(typeInfoBaseName) + L"Container<T>";
baseFriendAccess = FormatW(_fastModelBaseContainerFriendDecl, this->toCodeGenTypeName(typeInfoBaseName).data(), typeInfoNameCodeGen.data(), nullptr);
modelClassBaseNameCodeGen = FormatW(_fastModelCustomBaseClass_Template, this->toCodeGenTypeName(typeInfoBaseName).data(), pPropertyModelInfo->getBaseType()->getName().data(), nullptr);
// Write Properties and methods for base class delegation
schema::CObservableObjectInfo* baseType = (schema::CObservableObjectInfo *)(pPropertyModelInfo->getBaseType());
if(!baseType->getBaseType())
{
modelBaseDefinition = L"pmod::library::_DelegateFastModelBase<TBASE, TModelPrivateInterface>";
}
else
{
std::wstring baseName = this->toCodeGenTypeName(toTypeInfoName(baseType->getName()).c_str());
modelBaseDefinition = FormatW(L"_Fast{0}<TBASE, TModelPrivateInterface>",baseName.data(),nullptr);
}
baseMemberDelegates << "// " <<pPropertyModelInfo->getBaseType()->getName() << "Interface" << std::endl;
// emit base properties for delegating.
for (schema::_PropertyIteratorType::const_iterator iter = baseType->getProperties().begin();
iter != baseType->getProperties().end();
++iter)
{
emitPropertyBaseTypeDelegate(baseMemberDelegates, baseMemberQualifications,(*iter));
}
// Iterate Methods for the base class to generate the delegated
for (schema::_MethodIteratorType::const_iterator iter = baseType->getMethods().begin();
iter != baseType->getMethods().end();
++iter)
{
// emit method handler for class template
emitMethodBaseTypeDelegate(baseMemberDelegates, baseMemberQualifications, *iter);
}
}
// Emit get/set value cases
std::wostringstream getValueCases;
std::wostringstream setValueCases;
std::wostringstream commandInitializations;
std::wostringstream commandTypedefs;
std::wostringstream commandVirtualMethods;
std::wostringstream propertyContainers;
std::wostringstream ancestorPropertyContainers;
std::wostringstream osPropertyContainersInitializers;
std::wostringstream osPublicAccess;
std::wostringstream osInternalAccess;
std::wostringstream osPrivateAccess;
std::wostringstream osPrivateAccessDeclare;
std::wostringstream osAncestorFriendContainerDeclare;
std::wostringstream osOngetPropertyInternalCases;
std::wostringstream osEnsurePropertyActivation;
std::wostringstream osPropertiesRuntimeClassOptionsInitializers;
std::wostringstream osContainerReleaseStatements;
// Iterate Properties
for (schema::_PropertyIteratorType::const_iterator iter = pPropertyModelInfo->getProperties().begin();
iter != pPropertyModelInfo->getProperties().end();
++iter)
{
emitGetSetValuePropertyCases(getValueCases, setValueCases, (*iter));
bool isAncestor = ((*iter)->getFlags() & PropertyFlagType_IsAncestor) != 0;
// generate Command Internal support
if ((*iter)->getModelType() != nullptr &&
(*iter)->getModelType()->getModelType() == schema::ModelTypeInfoType_Command)
{
if ((*iter)->isAutoGenerate())
{
CGenerateCppLibrary::emitPropertyCommandHandler(
_osFastModelBaseClassTemplates,
(*iter),
FormatW(L"_WeakRefCommandClass<T,{0}>", pPropertyModelInfo->getName().data(),nullptr).c_str(),
L"_Fast");
}
}
// Generation activation for dynamic properties
emitActivationSupport(osOngetPropertyInternalCases,osEnsurePropertyActivation,(*iter));
// validate if we need to generate the container
// it will not be generated for parent property or custom container
if (!(*iter)->isParent() && !(*iter)->isCustomContainer())
{
emitPropertyInitializer(osPropertyContainersInitializers, (*iter));
}
emitPropertyAccessMethods(osPublicAccess, osInternalAccess, osPrivateAccess, osPrivateAccessDeclare, (*iter));
// we dont not need contaiers for parent properties
if (!(*iter)->isParent() && !(*iter)->isCustomContainer() && !isAncestor )
{
emitPropertyContainer(propertyContainers, (*iter));
emitContainerReleaseStatement(osContainerReleaseStatements, (*iter));
}
if (isAncestor)
{
ancestorPropertyContainers << "\tfoundation::InspectablePtr " << toAncestorContainerName((*iter)->getName().c_str()) << ";" << std::endl;
}
// only generate commands if they are not marked as auto generate
if ((*iter)->isAutoGenerate())
{
if ((*iter)->getModelType() && (*iter)->getModelType()->getModelType() == schema::ModelTypeInfoType_Command)
{
emitCommandInitializer(commandInitializations, commandTypedefs, (*iter));
emitPropertyCommandHandler(commandVirtualMethods, (*iter));
}
}
if ((*iter)->getRuntimeClassOptions() != 0)
{
UINT32 runtimeClassOptions = (*iter)->getRuntimeClassOptions();
std::wstring libraryRuntimeClassOptions;
if ((runtimeClassOptions & 1) != 0)
{
libraryRuntimeClassOptions += FormatW(_propertyRuntimeClassOptions_Template, getCoreNamespace(), L"UseWorkingDispatcherOnGetProperty", nullptr);
}
// note: put extra code here to continue constructing the options
if ((runtimeClassOptions & 2) != 0)
{
if (libraryRuntimeClassOptions.size())
{
libraryRuntimeClassOptions += L" | ";
}
libraryRuntimeClassOptions += FormatW(_propertyRuntimeClassOptions_Template, getCoreNamespace(), L"UseWorkingDispatcherOnSetProperty", nullptr);
}
osPropertiesRuntimeClassOptionsInitializers <<
FormatW(_setPropertyRuntimeClassOptions_Template,
getNamespace().c_str(),
typeInfoName.c_str(),
(*iter)->getName().c_str(),
FormatW(L"({0}::library::PropertyRuntimeClassOptions)({1})", getCoreNamespace(),libraryRuntimeClassOptions.c_str(),nullptr).c_str(),
nullptr);
}
}
// Generate Source Property if this is a viewmodel
if (pPropertyModelInfo->getModelType() == schema::ModelTypeInfoType_ViewModel)
{
initializeMethodName = L"_Initialize_viewmodel";
const schema::CObservableObjectInfo *pSourceType = ((const schema::CPropertyViewModelInfo *)pPropertyModelInfo)->getSourceType();
// Emit Header
osPrivateAccessDeclare << "\tvirtual HRESULT GetSource(";
this->emitModelTypeInfo(osPrivateAccessDeclare, pSourceType);
osPrivateAccessDeclare << "** ppValue) = 0;" << std::endl;
// Emit Source
osPublicAccess << "\tHRESULT GetSource(";
this->emitModelTypeInfo(osPublicAccess, pSourceType);
osPublicAccess << "** ppValue)" << std::endl;
osPublicAccess << "\t{" << std::endl;
osPublicAccess << "\t\treturn this->GetModelProperty(" << getCoreNamespace() << "::Property_Source,ppValue);" << std::endl;
osPublicAccess << "\t}" << std::endl;
}
// emit property containers
_osFastModelContainersTemplates << FormatW(_fastModelContainerClass_Template,
typeInfoNameCodeGen.data(),
typeInfoBaseNameCodeGen.data(),
getValueCases.str().length() != 0 ? FormatW(_fastModelGetSetValueSwitchTemplate, getValueCases.str().data(), nullptr).data() : L"",
setValueCases.str().length() != 0 ? FormatW(_fastModelGetSetValueSwitchTemplate, setValueCases.str().data(), nullptr).data() : L"",
ancestorPropertyContainers.str().data(),// Ancestor Containers
nullptr
);
//generate initialize method for base class
std::wstring fastModelInitialization = FormatW(_fastModelInitializeProperties_Template,
commandInitializations.str().data(),
osPropertyContainersInitializers.str().c_str(),
osPropertiesRuntimeClassOptionsInitializers.str().c_str(),
nullptr);
std::wostringstream osMethodHandler;
std::wostringstream osAbstractMethods;
// Iterate Methods
for (schema::_MethodIteratorType::const_iterator iter = pPropertyModelInfo->getMethods().begin();
iter != pPropertyModelInfo->getMethods().end();
++iter)
{
if ((*iter)->getIsAsync() || _generateMethodInternal)
{
emitWrapperMethod(osAbstractMethods, (*iter));
}
// emit method handler for class template
emitMethodHandler(osMethodHandler, osAbstractMethods, *iter, false);
}
std::wstring methodInvokeOverride;
if (pPropertyModelInfo->getMethods().size())
{
methodInvokeOverride = FormatW(
_fastModelMethodInvokeOverride_Template,
typeInfoName.data(),
osMethodHandler.str().data(),
this->getFoundationNamespace(),
nullptr);
}
std::wstring strPrivateAccessDeclare = osPrivateAccessDeclare.str();
std::wstring strCustomInterfaceName = pPropertyModelInfo->getCustomInterfaceName();
_osFastModelPrivateInterfaceDeclares << FormatW(_fastModelPrivateInterfaceDeclare_Template,
(pPropertyModelInfo->getName() + L"Private").data(),
strPrivateAccessDeclare.data(),
pPropertyModelInfo->getName().data(),
nullptr);
if (strCustomInterfaceName.size() != 0)
{
_osFastModelPrivateInterfaceDeclares << FormatW(_fastModelInterfaceExternDeclare_Template,
strCustomInterfaceName.data(),
L"", // Postfix not used
L"_VOID_MACRO", // No need for exporting this ID
nullptr);
std::wstring customIdValue = L"IID_" + strCustomInterfaceName;
custombaseTypeQI = FormatW(_fastModelBaseClassQI_Template, strCustomInterfaceName.data()
,customIdValue.data(), nullptr);
}
// generate the unique iid for the private access interface
IID iidPrivateModeTypeAccess = createUniqueIId(pPropertyModelInfo);
std::wostringstream osIIDGuidData;
formatIIDType(osIIDGuidData, iidPrivateModeTypeAccess);
_osFastModelPrivateInterfaceIIDs << FormatW(_fastModelPrivateInterfaceIId_Template,
getNativeNamespace().data(),
pPropertyModelInfo->getName().data(),
toIdlIIDType(iidPrivateModeTypeAccess).data(),
osIIDGuidData.str().data(),
L"Private",
nullptr);
bool hasCustomInterfaceName = false;
bool isCustomPrivateInterface = true;
if (strCustomInterfaceName.size() != 0)
{
hasCustomInterfaceName = true;
isCustomPrivateInterface = pPropertyModelInfo->isCustomPrivateInterface();
// generate the unique iid for the custom access interface
IID iidCustomModeTypeAccess = createUniqueIId(pPropertyModelInfo, L"Custom");
std::wostringstream osCustomIIDGuidData;
formatIIDType(osCustomIIDGuidData, iidCustomModeTypeAccess);
_osFastModelPrivateInterfaceIIDs << FormatW(_fastModelPrivateInterfaceIId_Template,
getNativeNamespace().data(),
strCustomInterfaceName.data(),
toIdlIIDType(iidCustomModeTypeAccess).data(),
osCustomIIDGuidData.str().data(),
L"", // Postfix not used
nullptr);
}
emitAncestorContainerFriendDecl(osAncestorFriendContainerDeclare, pPropertyModelInfo);
std::wstring ensureActivation = L"";
std::wstring onGetPropetyInternal = L"";
if (osEnsurePropertyActivation.tellp())
{
ensureActivation = osEnsurePropertyActivation.str();
onGetPropetyInternal = FormatW(_fastModelOnPropertyGetInternal_Template, osOngetPropertyInternalCases.str().data(), nullptr);;
}
std::wstring privateInterfaceName = pPropertyModelInfo->getName() + L"Private";
// emit base internal templates
_osFastModelBaseClassTemplates << FormatW(_fastModelInternalCoreBaseClass_Template,
typeInfoNameCodeGen.data(),
modelClassBaseNameCodeGen.data(),
privateInterfaceName.data(),
fastModelInitialization.data(),
commandTypedefs.str().data(),
pPropertyModelInfo->getBaseType() == nullptr ?
FormatW(L" = {0}::library::_FastModelBase<>", getCoreNamespace(), nullptr).c_str():
L"",
methodInvokeOverride.data(),
FormatW(L"{0}\n{1}\nprotected:\n{2}\n",osPublicAccess.str().data(),
osAbstractMethods.str().data(),
commandVirtualMethods.str().data(),
nullptr).data(),
osPrivateAccess.str().data(),
osInternalAccess.str().data(),
propertyContainers.str().data(),
custombaseTypeQI.data(),
pPropertyModelInfo->getName().data(),
FormatW(_fastModelInnerAdpaterName_Template, typeInfoName.data(), nullptr).data(),
typeInfoNameCodeGen.data(),
osAncestorFriendContainerDeclare.str().data(),
onGetPropetyInternal.data(),
ensureActivation.data(),
hasCustomInterfaceName && !isCustomPrivateInterface ? (L",\n\tpublic " + strCustomInterfaceName).data() : L"",
initializeMethodName.data(),
(L"public " + modelBaseDefinition).data(),
baseMemberDelegates.tellp() ? baseMemberDelegates.str().data() : L"",
pPropertyModelInfo->getName().data(),
pPropertyModelInfo->getBaseType() == nullptr ? L"" : (L":" + modelBaseDefinition + L"(params...)\n").data(),
pPropertyModelInfo->getBaseType() == nullptr ? L"" : (L":" + modelBaseDefinition + L"(parameter)\n").data(),
hasCustomInterfaceName && isCustomPrivateInterface ? strCustomInterfaceName.data() : privateInterfaceName.data(),
osContainerReleaseStatements.str().data(),
pPropertyModelInfo->getBaseType() == nullptr ? typeDefBaseClass.data() : L"",
nullptr
);
}