in src/codegen/tool/GenerateWindowsRuntimeAdapter.cpp [528:873]
void CGenerateWindowsRuntimeAdapter::codeGenerate(const schema::CObservableObjectInfo *pPropertyModelInfo)
{
bool isViewModel = pPropertyModelInfo->getModelType() == ::schema::ModelTypeInfoType_ViewModel;
_osInterfaceForwardIdl << "\t" << "interface "<< pPropertyModelInfo->getName() <<";" << std::endl;
std::wstring typeInfoName = toTypeInfoName(pPropertyModelInfo->getName());
#if 0
_osRuntimeClassesIdl << FormatW(_winRTRuntimeClass_Template,
typeInfoName.c_str(),
pPropertyModelInfo->getName().c_str(),
nullptr);
#endif
std::wostringstream osIdlProperties;
std::wostringstream osIdlMethods;
std::wostringstream osIdlPropertiesEnums;
std::wostringstream osIdlMethodEnums;
std::wostringstream osIdlEventsEnums;
std::wostringstream ocClassAdapterContent;
std::vector<const schema::CObservableObjectInfo *> descendents;
pPropertyModelInfo->getDescendents(descendents);
// TODO: we are only generating 'Source' property for 'final'
// interfaces to avoid the duplication of property names
if (isViewModel && descendents.size() == 0 )
{
const schema::CObservableObjectInfo *pSourceType = ((const schema::CPropertyViewModelInfo *)pPropertyModelInfo)->getSourceType();
if (!pSourceType->getParent().isFactorySchema())
{
// Generate IDL source code
osIdlProperties << FormatW(_getSourceModelIdl_Template,
toIdlModelTypeInfo(pSourceType).data(),
nullptr);
// Generate Model Adapter source code
ocClassAdapterContent << FormatW(_getSourceModel_Template,
toNativeModelTypeName(pSourceType).data(),
getCoreNamespace(),
nullptr);
}
}
// Iterate Events
for(schema::_EventIteratorType::const_iterator iter = pPropertyModelInfo->getEvents().begin();
iter != pPropertyModelInfo->getEvents().end();
++iter)
{
// Emit Enum Events
osIdlEventsEnums << "\t\t" << (*iter)->getName() << " = " << (*iter)->getId() << "," << std::endl;
}
// Iterate Properties
for(schema::_PropertyIteratorType::const_iterator iter = pPropertyModelInfo->getProperties().begin();
iter != pPropertyModelInfo->getProperties().end();
++iter)
{
bool isPropertyArray = ((*iter)->getPropertyType() & 0x400) != 0;
// Emit Enum Properties
osIdlPropertiesEnums << "\t\t" << (*iter)->getName() << " = ";
if((*iter)->isParent())
{
osIdlPropertiesEnums << "0x2001";
}
else
{
osIdlPropertiesEnums << (*iter)->getId();
}
if(isViewModel)
{
osIdlPropertiesEnums << " + 0x1000";
}
osIdlPropertiesEnums << "," << std::endl;
UINT32 flags = (*iter)->getFlags();
if((flags & PropertyFlagType_CanRead))
{
// Idl generation
osIdlProperties << FormatW(isPropertyArray ? _getPropertyArrayIdl_Template:_getPropertyIdl_Template,
(*iter)->getName().data(),
toIdlPropertyTypeInfo(*iter).data(),
nullptr);
// class adapter generation
ocClassAdapterContent << FormatW(isPropertyArray ? _getPropertyArray_Template: _getProperty_Template,
(*iter)->getName().data(),
toNativePropertyTypeInfo(*iter).data(),
typeInfoName.data(),
nullptr);
}
if((flags & PropertyFlagType_CanWrite))
{
// Idl generation
osIdlProperties << FormatW(isPropertyArray ? _setPropertyArrayIdl_Template:_setPropertyIdl_Template,
(*iter)->getName().data(),
toIdlPropertyTypeInfo(*iter).data(),
nullptr);
std::wstring castValue = L"";
if((flags & PropertyFlagType_IsEnum) && !isPropertyTypeInfoArray(*iter))
{
castValue = L"(UINT32)";
}
// class adapter generation
ocClassAdapterContent << FormatW(isPropertyArray ? _setPropertyArrayTemplate: _setPropertyTemplate,
(*iter)->getName().data(),
toNativePropertyTypeInfo(*iter).data(),
typeInfoName.data(),
castValue.data(),
nullptr);
}
}
// Iterate Methods
for(schema::_MethodIteratorType::const_iterator iter = pPropertyModelInfo->getMethods().begin();
iter != pPropertyModelInfo->getMethods().end();
++iter)
{
// Emit Enum Methods
osIdlMethodEnums << "\t\t" << (*iter)->getName() << " = " << (*iter)->getId();
if(isViewModel)
{
osIdlMethodEnums << " + 0x1000";
}
osIdlMethodEnums << "," << std::endl;
// Emit Idl declare method & Adapter Class Content
osIdlMethods << "\t\t" << "HRESULT " << (*iter)->getName() << "(";
ocClassAdapterContent << "\t" << "HRESULT STDMETHODCALLTYPE " << (*iter)->getName() << "(";
std::wostringstream osAdapterParams;
if((*iter)->getParameters().size())
{
osAdapterParams << "\t\t" << "foundation::InspectablePtr parameters[" << (*iter)->getParameters().size() << "];" << std::endl;
}
int parameterIndex = 1;
for(schema::_MethodParamIteratorType::const_iterator iterParam = (*iter)->getParameters().begin();
iterParam != (*iter)->getParameters().end();
++iterParam)
{
bool isParamerterArray = ((*iterParam)->getPropertyType() & 0x400) != 0;
if(iterParam != (*iter)->getParameters().begin())
{
osIdlMethods << ",";
ocClassAdapterContent << ",";
}
if(isParamerterArray)
{
osIdlMethods << "[in]UINT32 length_" << parameterIndex << ",";
ocClassAdapterContent << "UINT32 length_" << parameterIndex << ",";
}
osIdlMethods << "[in";
if(isParamerterArray)
{
osIdlMethods << ",size_is(length_" << parameterIndex << ")";
}
osIdlMethods << "]" << toIdlPropertyTypeInfo(*iterParam) << " " << (*iterParam)->getParameterName();
ocClassAdapterContent << toNativePropertyTypeInfo(*iterParam) << " " << (*iterParam)->getParameterName();
if ((*iterParam)->getPropertyType() == foundation::PropertyType_Inspectable)
{
osAdapterParams
<< "\t\tparameters["
<< (int)(iterParam - (*iter)->getParameters().begin())
<< "] = " << (*iterParam)->getParameterName() << ";" << std::endl;
}
else
{
osAdapterParams << "\t\t" << "IFHR_ASSERT(foundation::pv_util::GetPropertyValueStatics()->Create"
<< toPropertyTypeName((*iterParam)->getPropertyType()) << "(";
if (isParamerterArray)
{
osAdapterParams << "length_" << parameterIndex << ",";
}
// TODO: workaround to force an Enum type to be casted as UINT32
// the Parameter Info does not give me a way to know a type if an Enum
if ((*iterParam)->getPropertyType() == foundation::PropertyType_UInt32)
{
osAdapterParams << "(UINT32)";
}
if (isParamerterArray && hasPropertyTypeInfoModel(*iterParam))
{
osAdapterParams << "reinterpret_cast<IInspectable **>(" << (*iterParam)->getParameterName() << ")";
}
else
{
osAdapterParams << (*iterParam)->getParameterName();
}
osAdapterParams
<< ",parameters["
<< (int)(iterParam - (*iter)->getParameters().begin())
<< "].GetAddressOfPtr()));" << std::endl;
}
++parameterIndex;
}
bool hasResult = (*iter)->getResultType()->getPropertyType() != foundation::PropertyType::PropertyType_Empty;
bool isAsync = (*iter)->getIsAsync();
bool isResultArray = ((*iter)->getResultType()->getPropertyType() & 0x400) != 0;
if (hasResult || isAsync)
{
if((*iter)->getParameters().size())
{
osIdlMethods << ",";
ocClassAdapterContent << ",";
}
if(isResultArray)
{
osIdlMethods << "[out]UINT32 *length,";
ocClassAdapterContent << "UINT32 *length,";
}
osIdlMethods << "[out,";
if(!(*iter)->getIsAsync() && isResultArray)
{
osIdlMethods << "size_is(,*length),";
}
osIdlMethods << "retval]" << toIdlResultTypeInfo((*iter)->getResultType(),(*iter)->getIsAsync()) << "*result";
ocClassAdapterContent << toNativeResultTypeInfo((*iter)->getResultType(),(*iter)->getIsAsync()) << "*result";
}
osIdlMethods << ");" << std::endl;
ocClassAdapterContent << ")" << std::endl;
ocClassAdapterContent << "\t" << "{" <<std::endl;
ocClassAdapterContent << "\t\t" << "HRESULT hr = S_OK;" <<std::endl;
ocClassAdapterContent << "\t\t" << "foundation::InspectablePtr spResult;" <<std::endl;
ocClassAdapterContent << osAdapterParams.str();
ocClassAdapterContent << "\t\t" << "IFHR(__super::Invoke(" << typeInfoName << "::Method_"
<< (*iter)->getName() << "," << (*iter)->getParameters().size() << ",";
if((*iter)->getParameters().size())
{
ocClassAdapterContent << "parameters[0].GetAddressOfPtr()";
}
else
{
ocClassAdapterContent << "nullptr";
}
ocClassAdapterContent << ",spResult.GetAddressOf()));" <<std::endl;
if (hasResult || isAsync)
{
if((*iter)->getIsAsync())
{
ocClassAdapterContent << FormatW(
_returnModelAdapter,
toNativeAsyncOperation((*iter)->getResultType()).data(),
nullptr);
}
else if((*iter)->getResultType()->getPropertyType() == foundation::PropertyType::PropertyType_Inspectable)
{
ocClassAdapterContent << FormatW(_returnModelAdapter,
toNativePropertyTypeInfo((*iter)->getResultType()).data(),
nullptr);
}
else
{
if (isPropertyTypeInfoEnum((*iter)->getResultType()))
{
ocClassAdapterContent << FormatW(_returnEnumValueAdapter,
toNativePropertyTypeInfo((*iter)->getResultType()).c_str(),
nullptr);
}
else
{
ocClassAdapterContent << FormatW(_returnValueAdapter,
toPropertyTypeName((*iter)->getResultType()->getPropertyType()).c_str(),
isResultArray ? L"length," : L"",
nullptr);
}
}
}
ocClassAdapterContent << "\t\t" << "return S_OK;" <<std::endl;
ocClassAdapterContent << "\t" << "}" <<std::endl;
}
std::wstring idlBaseType;
if(pPropertyModelInfo->getBaseType())
{
idlBaseType = toIdlModelTypeName(pPropertyModelInfo->getBaseType());
}
else
{
idlBaseType = _idlCoreNamespace;
idlBaseType += L".IObservableObject";
}
_osInterfacesIdl << FormatW(_winRTInterface_Template,
pPropertyModelInfo->getName().data(),
toIdlIIDType(pPropertyModelInfo).data(),
idlBaseType.data(),
osIdlProperties.str().data(),
osIdlMethods.str().data(),
nullptr);
if(pPropertyModelInfo->getProperties().size())
{
_osInterfacesIdl << FormatW(_winRTEnum_Template,
(typeInfoName + L"Properties").data(),
osIdlPropertiesEnums.str().data(),
nullptr);
}
if(pPropertyModelInfo->getMethods().size())
{
_osInterfacesIdl << FormatW(_winRTEnum_Template,
(typeInfoName + L"Methods").data(),
osIdlMethodEnums.str().data(),
nullptr);
}
if(pPropertyModelInfo->getEvents().size())
{
_osInterfacesIdl << FormatW(_winRTEnum_Template,
(typeInfoName + L"Events").data(),
osIdlEventsEnums.str().data(),
nullptr);
}
// Emit Source Adapter Class
_osModelAdapterSrc << FormatW(
_classPropertyModelAdapter_Template,
typeInfoName.data(),
toNativeModelTypeName(pPropertyModelInfo).data(),
ocClassAdapterContent.str().data(),
nullptr);
// Emit type adapter factory entry
_osModelAdapterFactoryEntries << FormatW(
_modelAdapterEntryFactory_Template,
toNativeModelTypeName(pPropertyModelInfo).data(),
typeInfoName.data(),
getFoundationNamespace(),
nullptr);
}