/*********************************************************************** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY DEVELOPER: Zihan Chen(vczh) ***********************************************************************/ #include "GacUICompiler.h" /*********************************************************************** .\GUICPPGEN.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace stream; using namespace filesystem; using namespace workflow; using namespace workflow::cppcodegen; bool WriteErrors( collections::List& errors, const filesystem::FilePath& errorPath) { List output; GuiResourceError::SortAndLog(errors, output); return File(errorPath).WriteAllLines(output, true, BomEncoder::Utf8); } Ptr PrecompileResource( Ptr resource, GuiResourceCpuArchitecture targetCpuArchitecture, IGuiResourcePrecompileCallback* callback, collections::List& errors) { auto precompiledFolder = resource->Precompile(targetCpuArchitecture, callback, errors); return precompiledFolder; } Ptr WriteWorkflowScript( Ptr precompiledFolder, const WString& assemblyResourcePath, const filesystem::FilePath& workflowPath) { if (precompiledFolder) { if (auto compiled = precompiledFolder->GetValueByPath(assemblyResourcePath).Cast()) { WString text; if (compiled->assembly) { auto& codes = compiled->assembly->insAfterCodegen->moduleCodes; for (auto [code, codeIndex] : indexed(codes)) { text += L"================================(" + itow(codeIndex + 1) + L"/" + itow(codes.Count()) + L")================================\r\n"; text += code + L"\r\n"; } } else { for (auto [moduleRecord, codeIndex] : indexed(compiled->modules)) { WString code = GenerateToStream([&, module = moduleRecord.module](StreamWriter& writer) { WfPrint(module, L"", writer); }); text += L"================================(" + itow(codeIndex + 1) + L"/" + itow(compiled->modules.Count()) + L")================================\r\n"; text += code + L"\r\n"; } } if (File(workflowPath).WriteAllText(text, true, BomEncoder::Utf8)) { return compiled; } } } return nullptr; } Ptr WriteCppCodesToFile( Ptr resource, Ptr compiled, Ptr cppInput, const filesystem::FilePath& cppFolder, collections::List& errors) { auto output = GenerateCppFiles(cppInput, compiled->metadata.Obj()); if (compiled->metadata->errors.Count() > 0) { for (auto error : compiled->metadata->errors) { errors.Add(GuiResourceError({ {resource} }, error.message)); } return nullptr; } // TODO: (enumerable) foreach on dictionary for (auto [fileName, index] : indexed(output->cppFiles.Keys())) { WString code = output->cppFiles.Values()[index]; File file(cppFolder / fileName); if (file.Exists()) { WString inputText; BomEncoder::Encoding inputEncoding; bool inputBom; file.ReadAllTextWithEncodingTesting(inputText, inputEncoding, inputBom); code = MergeCppFileContent(inputText, code); } if (file.Exists()) { WString inputText; BomEncoder::Encoding inputEncoding; bool inputBom; file.ReadAllTextWithEncodingTesting(inputText, inputEncoding, inputBom); if (inputText == code) { continue; } } file.WriteAllText(code, true, BomEncoder::Utf8); } return output; } bool WriteBinaryResource( Ptr resource, bool compress, bool includeAssemblyInResource, Nullable resourceOutput, Nullable assemblyOutput) { auto precompiled = resource->GetFolder(L"Precompiled"); auto folder = precompiled->GetFolder(L"Workflow"); if (resourceOutput) { FileStream fileStream(resourceOutput.Value().GetFullPath(), FileStream::WriteOnly); if (!fileStream.IsAvailable()) return false; if (!includeAssemblyInResource) precompiled->RemoveFolder(L"Workflow"); if (compress) { LzwEncoder encoder; EncoderStream encoderStream(fileStream, encoder); resource->SavePrecompiledBinary(encoderStream); } else { resource->SavePrecompiledBinary(fileStream); } if (!includeAssemblyInResource) precompiled->AddFolder(L"Workflow", folder); } if (assemblyOutput) { if (auto item = folder->GetItem(L"InstanceClass")) { if (auto compiled = item->GetContent().Cast()) { if (compiled->assembly) { FileStream fileStream(assemblyOutput.Value().GetFullPath(), FileStream::WriteOnly); if (!fileStream.IsAvailable()) return false; compiled->assembly->Serialize(fileStream); } } } } return true; } void WriteEmbeddedBinaryClass(MemoryStream& binaryStream, bool compress, const WString& className, const WString& prefix, StreamWriter& writer) { MemoryStream compressedStream; binaryStream.SeekFromBegin(0); if (compress) { CompressStream(binaryStream, compressedStream); } else { CopyStream(binaryStream, compressedStream); } compressedStream.SeekFromBegin(0); vint lengthBeforeCompressing = (vint)binaryStream.Size(); vint length = (vint)compressedStream.Size(); const vint block = 1024; vint remain = length % block; vint solidRows = length / block; vint rows = solidRows + (remain ? 1 : 0); #define PREFIX writer.WriteString(prefix); PREFIX writer.WriteLine(L"class " + className); PREFIX writer.WriteLine(L"{"); PREFIX writer.WriteLine(L"public:"); PREFIX writer.WriteLine(L"\tstatic const vint parserBufferLength = " + itow(length) + L"; // " + itow(lengthBeforeCompressing) + L" bytes before compressing"); PREFIX writer.WriteLine(L"\tstatic const vint parserBufferBlock = " + itow(block) + L";"); PREFIX writer.WriteLine(L"\tstatic const vint parserBufferRemain = " + itow(remain) + L";"); PREFIX writer.WriteLine(L"\tstatic const vint parserBufferRows = " + itow(rows) + L";"); PREFIX writer.WriteLine(L"\tstatic const char* parserBuffer[" + itow(rows) + L"];"); writer.WriteLine(L""); PREFIX writer.WriteLine(L"\tstatic void ReadToStream(vl::stream::MemoryStream& stream)"); PREFIX writer.WriteLine(L"\t{"); PREFIX writer.WriteLine(L"\t\tDecompressStream(parserBuffer, " + WString(compress ? L"true" : L"false") + L", parserBufferRows, parserBufferBlock, parserBufferRemain, stream);"); PREFIX writer.WriteLine(L"\t}"); PREFIX writer.WriteLine(L"};"); writer.WriteLine(L""); PREFIX writer.WriteLine(L"const char* " + className + L"::parserBuffer[] = {"); char buffer[block]; const wchar_t* hex = L"0123456789ABCDEF"; for (vint i = 0; i < rows; i++) { vint size = i == solidRows ? remain : block; compressedStream.Read(buffer, size); PREFIX writer.WriteString(L"\t\""); for (vint j = 0; j < size; j++) { vuint8_t byte = buffer[j]; writer.WriteString(L"\\x"); writer.WriteChar(hex[byte / 16]); writer.WriteChar(hex[byte % 16]); } writer.WriteLine(L"\","); } PREFIX writer.WriteLine(L"\t};"); #undef PREFIX } bool WriteEmbeddedResource(Ptr resource, Ptr cppInput, Ptr cppOutput, bool compress, const filesystem::FilePath& filePath) { WString code = GenerateToStream([&](StreamWriter& writer) { writer.WriteLine(L"#include \"" + cppOutput->entryFileName + L".h\""); writer.WriteLine(L""); writer.WriteLine(L"namespace vl"); writer.WriteLine(L"{"); writer.WriteLine(L"\tnamespace presentation"); writer.WriteLine(L"\t{"); writer.WriteLine(L"\t\tnamespace user_resource"); writer.WriteLine(L"\t\t{"); writer.WriteLine(L"\t\t\tusing namespace collections;"); writer.WriteLine(L"\t\t\tusing namespace stream;"); writer.WriteLine(L"\t\t\tusing namespace controls;"); writer.WriteLine(L""); { MemoryStream resourceStream; { auto precompiled = resource->GetFolder(L"Precompiled"); auto folder = precompiled->GetFolder(L"Workflow"); precompiled->RemoveFolder(L"Workflow"); resource->SavePrecompiledBinary(resourceStream); precompiled->AddFolder(L"Workflow", folder); } WriteEmbeddedBinaryClass(resourceStream, compress, cppInput->assemblyName + L"ResourceReader", L"\t\t\t", writer); writer.WriteLine(L""); } { writer.WriteLine(L"\t\t\tclass " + cppInput->assemblyName + L"ResourceLoaderPlugin : public Object, public IGuiPlugin"); writer.WriteLine(L"\t\t\t{"); writer.WriteLine(L"\t\t\tpublic:"); writer.WriteLine(L""); writer.WriteLine(L"\t\t\t\tGUI_PLUGIN_NAME(GacGen_" + cppInput->assemblyName + L"ResourceLoader)"); writer.WriteLine(L"\t\t\t\t{"); writer.WriteLine(L"\t\t\t\t\tGUI_PLUGIN_DEPEND(GacUI_Res_Resource);"); writer.WriteLine(L"\t\t\t\t\tGUI_PLUGIN_DEPEND(GacUI_Res_TypeResolvers);"); writer.WriteLine(L"#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA"); writer.WriteLine(L"\t\t\t\t\tGUI_PLUGIN_DEPEND(GacUI_Instance_Reflection);"); writer.WriteLine(L"\t\t\t\t\tGUI_PLUGIN_DEPEND(GacUI_Compiler_WorkflowTypeResolvers);"); writer.WriteLine(L"#endif"); writer.WriteLine(L"\t\t\t\t}"); writer.WriteLine(L""); writer.WriteLine(L"\t\t\t\tvoid Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override"); writer.WriteLine(L"\t\t\t\t{"); writer.WriteLine(L"\t\t\t\t\tif (controllerRelatedPlugins)"); writer.WriteLine(L"\t\t\t\t\t{"); writer.WriteLine(L"\t\t\t\t\t\tList errors;"); writer.WriteLine(L"\t\t\t\t\t\tMemoryStream resourceStream;"); writer.WriteLine(L"\t\t\t\t\t\t" + cppInput->assemblyName + L"ResourceReader::ReadToStream(resourceStream);"); writer.WriteLine(L"\t\t\t\t\t\tresourceStream.SeekFromBegin(0);"); writer.WriteLine(L"\t\t\t\t\t\tGetResourceManager()->LoadResourceOrPending(resourceStream, GuiResourceUsage::InstanceClass);"); writer.WriteLine(L"\t\t\t\t\t}"); writer.WriteLine(L"\t\t\t\t}"); writer.WriteLine(L""); writer.WriteLine(L"\t\t\t\tvoid Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override"); writer.WriteLine(L"\t\t\t\t{"); writer.WriteLine(L"\t\t\t\t}"); writer.WriteLine(L"\t\t\t};"); writer.WriteLine(L"\t\t\tGUI_REGISTER_PLUGIN(" + cppInput->assemblyName + L"ResourceLoaderPlugin)"); } writer.WriteLine(L"\t\t}"); writer.WriteLine(L"\t}"); writer.WriteLine(L"}"); }); File file(filePath); if (file.Exists()) { WString inputText; BomEncoder::Encoding inputEncoding; bool inputBom; file.ReadAllTextWithEncodingTesting(inputText, inputEncoding, inputBom); if (inputText == code) { return true; } } return file.WriteAllText(code, true, BomEncoder::Utf8); } } } /*********************************************************************** .\GUIINSTANCEANIMATION.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace reflection::description; using namespace collections; using namespace glr::xml; using namespace workflow; using namespace workflow::analyzer; using namespace presentation::controls; /*********************************************************************** GuiInstanceGradientAnimation::LoadFromXml ***********************************************************************/ Ptr GuiInstanceGradientAnimation::LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors) { auto animation = Ptr(new GuiInstanceGradientAnimation); animation->tagPosition = { {resource},xml->rootElement->codeRange.start }; if (auto classAttr = XmlGetAttribute(xml->rootElement, L"ref.Class")) { animation->className = classAttr->value.value; animation->classPosition = { {resource},classAttr->value.codeRange.start }; animation->classPosition.column += 1; } else { errors.Add({ {{resource},xml->rootElement->codeRange.start}, L"Precompile: Missing required attribute: \"ref.Class\"." }); } if (auto typeAttr = XmlGetAttribute(xml->rootElement, L"Type")) { animation->typeName = typeAttr->value.value; animation->typePosition = { { resource },typeAttr->value.codeRange.start }; animation->typePosition.column += 1; } else { errors.Add({ { { resource },xml->rootElement->codeRange.start }, L"Precompile: Missing required attribute: \"Type\"." }); } if (auto interpolationElement = XmlGetElement(xml->rootElement, L"Interpolation")) { if (auto cdata = interpolationElement->subNodes[0].Cast()) { animation->interpolation = cdata->content.value; animation->interpolationPosition = { { resource },cdata->codeRange.start }; animation->interpolationPosition.column += 9; // codeRange.start }, L"Precompile: Interpolation function should be contained in a CDATA section." }); } } if (auto targetsElement = XmlGetElement(xml->rootElement, L"Targets")) { for (auto targetElement : XmlGetElements(targetsElement, L"Target")) { Target target; if (auto nameAttr = XmlGetAttribute(targetElement, L"Name")) { target.name = nameAttr->value.value; target.namePosition = { { resource },nameAttr->value.codeRange.start }; target.namePosition.column += 1; } else { errors.Add({ { { resource },targetElement->codeRange.start }, L"Precompile: Missing required attribute: \"Name\"." }); } if (auto interpolationElement = XmlGetElement(targetElement, L"Interpolation")) { if (auto cdata = interpolationElement->subNodes[0].Cast()) { target.interpolation = cdata->content.value; target.interpolationPosition = { { resource },cdata->codeRange.start }; target.interpolationPosition.column += 9; // codeRange.start }, L"Precompile: Interpolation function should be contained in a CDATA section." }); } } animation->targets.Add(target); } if (animation->targets.Count() == 0) { errors.Add({ { { resource },targetsElement->codeRange.start }, L"Precompile: Missing required element: \"Target\" in \"Targets\"." }); } } else { errors.Add({ { { resource },xml->rootElement->codeRange.start }, L"Precompile: Missing required element: \"Targets\"." }); } return animation; } /*********************************************************************** GuiInstanceGradientAnimation::SaveToXml ***********************************************************************/ Ptr GuiInstanceGradientAnimation::SaveToXml() { auto gradientElement = Ptr(new XmlElement); { auto classAttr = Ptr(new XmlAttribute); classAttr->name.value = L"ref.Class"; classAttr->value.value = className; gradientElement->attributes.Add(classAttr); } { auto typeAttr = Ptr(new XmlAttribute); typeAttr->name.value = L"Type"; typeAttr->value.value = typeName; gradientElement->attributes.Add(typeAttr); } if (interpolation != L"") { auto interpolationElement = Ptr(new XmlElement); interpolationElement->name.value = L"Interpolation"; gradientElement->subNodes.Add(interpolationElement); auto cdata = Ptr(new XmlCData); cdata->content.value = interpolation; interpolationElement->subNodes.Add(cdata); } { auto targetsElement = Ptr(new XmlElement); targetsElement->name.value = L"Targets"; gradientElement->subNodes.Add(targetsElement); for (auto target : targets) { auto targetElement = Ptr(new XmlElement); targetElement->name.value = L"Target"; targetsElement->subNodes.Add(targetElement); { auto nameAttr = Ptr(new XmlAttribute); nameAttr->name.value = L"Name"; nameAttr->value.value = target.name; targetElement->attributes.Add(nameAttr); } if (target.interpolation != L"") { auto interpolationElement = Ptr(new XmlElement); interpolationElement->name.value = L"Interpolation"; targetElement->subNodes.Add(interpolationElement); auto cdata = Ptr(new XmlCData); cdata->content.value = target.interpolation; interpolationElement->subNodes.Add(cdata); } } } return gradientElement; } /*********************************************************************** GuiInstanceGradientAnimation::ValidatePropertyType ***********************************************************************/ bool GuiInstanceGradientAnimation::IsSupportedPrimitiveType(description::ITypeDescriptor* td) { if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; if (td == description::GetTypeDescriptor()) return true; return false; } vint GuiInstanceGradientAnimation::ValidateStructMembers(GuiResourceTextPos namePosition, description::ITypeDescriptor* td, const WString& prefix, GuiResourceError::List& errors) { vint members = 0; vint count = td->GetPropertyCount(); for (vint i = 0; i < count; i++) { auto propInfo = td->GetProperty(i); members += ValidatePropertyType(namePosition, propInfo->GetReturn(), prefix + L"." + propInfo->GetName(), errors); } count = td->GetBaseTypeDescriptorCount(); for (vint i = 0; i < count; i++) { members += ValidateStructMembers(namePosition, td->GetBaseTypeDescriptor(i), prefix, errors); } return members; } vint GuiInstanceGradientAnimation::ValidatePropertyType(GuiResourceTextPos namePosition, description::ITypeInfo* typeInfo, const WString& prefix, GuiResourceError::List& errors, bool rootValue) { auto td = typeInfo->GetTypeDescriptor(); switch (td->GetTypeDescriptorFlags()) { case TypeDescriptorFlags::Primitive: if (IsSupportedPrimitiveType(td)) { return 1; } break; case TypeDescriptorFlags::Struct: { vint members = ValidateStructMembers(namePosition, td, prefix, errors); if (rootValue && members == 0) { errors.Add({ namePosition,L"Precompile: Property \"" + prefix + L"\" of type \"" + typeInfo->GetTypeFriendlyName() + L"\" in class \"" + typeName + L"\" is not supported. A struct should at least has one numeric primitive member to perform gradual changing." }); } return members; } default:; } errors.Add({ namePosition,L"Precompile: Property \"" + prefix + L"\" of type \"" + typeInfo->GetTypeFriendlyName() + L"\" in class \"" + typeName + L"\" is not supported. Only numeric types and structs are able to perform gradual changing." }); return 0; } /*********************************************************************** GuiInstanceGradientAnimation::EnumerateMembers ***********************************************************************/ void GuiInstanceGradientAnimation::EnumerateMembers(EnumerateMemberCallback callback, EnumerateMemberAccessor accessor, description::IPropertyInfo* propInfo, description::IPropertyInfo* originPropInfo) { auto td = propInfo->GetReturn()->GetTypeDescriptor(); auto newAccessor = [=](Ptr expression) { auto member = Ptr(new WfMemberExpression); member->parent = accessor(expression); member->name.value = propInfo->GetName(); return member; }; switch (td->GetTypeDescriptorFlags()) { case TypeDescriptorFlags::Primitive: callback(newAccessor, propInfo, originPropInfo); break; case TypeDescriptorFlags::Struct: EnumerateMembers(callback, newAccessor, td, originPropInfo); break; default:; } } void GuiInstanceGradientAnimation::EnumerateMembers(EnumerateMemberCallback callback, EnumerateMemberAccessor accessor, description::ITypeDescriptor* td, description::IPropertyInfo* originPropInfo) { vint count = td->GetPropertyCount(); for (vint i = 0; i < count; i++) { auto propInfo = td->GetProperty(i); if (propInfo->GetName() == L"value" && propInfo->GetOwnerTypeDescriptor() == description::GetTypeDescriptor()) { continue; } EnumerateMembers(callback, accessor, propInfo, originPropInfo); } count = td->GetBaseTypeDescriptorCount(); for (vint i = 0; i < count; i++) { EnumerateMembers(callback, accessor, td->GetBaseTypeDescriptor(i), originPropInfo); } } void GuiInstanceGradientAnimation::EnumerateProperties(EnumerateMemberCallback callback, description::ITypeDescriptor* td) { for (auto target : targets) { auto propInfo = td->GetPropertyByName(target.name, true); EnumerateMembers(callback, [](auto x) {return x; }, propInfo, propInfo); } } /*********************************************************************** GuiInstanceGradientAnimation::InitStruct ***********************************************************************/ Ptr GuiInstanceGradientAnimation::InitStruct(description::IPropertyInfo* propInfo, const WString& prefix, collections::SortedList& varNames) { auto td = propInfo->GetReturn()->GetTypeDescriptor(); auto name = prefix + L"_" + propInfo->GetName(); if (td->GetTypeDescriptorFlags() == TypeDescriptorFlags::Primitive) { if (!varNames.Contains(name)) { return nullptr; } auto ref = Ptr(new WfReferenceExpression); ref->name.value = L"" + name; return ref; } else { List tds; tds.Add(td); auto ref = Ptr(new WfConstructorExpression); // TODO: (enumerable) foreach:alterable for (vint i = 0; i < tds.Count(); i++) { auto currentTd = tds[i]; vint count = currentTd->GetBaseTypeDescriptorCount(); for (vint j = 0; j < count; j++) { tds.Add(currentTd->GetBaseTypeDescriptor(j)); } count = currentTd->GetPropertyCount(); for (vint j = 0; j < count; j++) { auto currentPropInfo = currentTd->GetProperty(j); if (auto expr = InitStruct(currentPropInfo, name, varNames)) { auto pair = Ptr(new WfConstructorArgument); auto refName = Ptr(new WfReferenceExpression); refName->name.value = currentPropInfo->GetName(); pair->key = refName; pair->value = expr; ref->arguments.Add(pair); } } } return ref; } } /*********************************************************************** GuiInstanceGradientAnimation::Compile ***********************************************************************/ Ptr GuiInstanceGradientAnimation::Compile(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, bool generateImpl, GuiResourceError::List& errors) { if (auto td = description::GetTypeDescriptor(typeName)) { if (td->GetTypeDescriptorFlags() == TypeDescriptorFlags::Class) { { if (auto ctorGroup = td->GetConstructorGroup()) { vint count = ctorGroup->GetMethodCount(); for (vint i = 0; i < count; i++) { auto ctor = ctorGroup->GetMethod(i); if (ctor->GetReturn()->GetDecorator() == ITypeInfo::SharedPtr && ctor->GetParameterCount() == 0) { goto CTOR_CHECK_PASS; } } } errors.Add({ typePosition,L"Precompile: Class \"" + typeName + L"\" should have a default constructor which returns a shared pointer and has no arguments." }); CTOR_CHECK_PASS:; } auto module = Ptr(new WfModule); module->moduleType = WfModuleType::Module; module->name.value = moduleName; auto animationClass = Workflow_InstallClass(className, module); auto typeInfo = Ptr(new SharedPtrTypeInfo(Ptr(new TypeDescriptorTypeInfo(td, TypeInfoHint::Normal)))); auto typeInfoDouble = CreateTypeInfoFromTypeFlag(TypeFlag::F8); auto notImplemented = []() { auto block = Ptr(new WfBlockStatement); auto stringExpr = Ptr(new WfStringExpression); stringExpr->value.value = L"Not Implemented"; auto raiseStat = Ptr(new WfRaiseExceptionStatement); raiseStat->expression = stringExpr; block->statements.Add(raiseStat); return block; }; { // prop Begin : = {} auto prop = Ptr(new WfAutoPropertyDeclaration); animationClass->declarations.Add(prop); prop->functionKind = WfFunctionKind::Normal; prop->name.value = L"Begin"; prop->type = GetTypeFromTypeInfo(typeInfo.Obj()); prop->expression = CreateDefaultValue(typeInfo.Obj()); prop->configConst = WfAPConst::Writable; prop->configObserve = WfAPObserve::Observable; } { // prop End : = {} auto prop = Ptr(new WfAutoPropertyDeclaration); animationClass->declarations.Add(prop); prop->functionKind = WfFunctionKind::Normal; prop->name.value = L"End"; prop->type = GetTypeFromTypeInfo(typeInfo.Obj()); prop->expression = CreateDefaultValue(typeInfo.Obj()); prop->configConst = WfAPConst::Writable; prop->configObserve = WfAPObserve::Observable; } { // prop Current : = {} auto prop = Ptr(new WfAutoPropertyDeclaration); animationClass->declarations.Add(prop); prop->functionKind = WfFunctionKind::Normal; prop->name.value = L"Current"; prop->type = GetTypeFromTypeInfo(typeInfo.Obj()); prop->expression = CreateDefaultValue(typeInfo.Obj()); prop->configConst = WfAPConst::Writable; prop->configObserve = WfAPObserve::Observable; } auto createIntVar = [&](const WString& name, const WString& interpolation, GuiResourceTextPos interpolationPosition) { // prop : (func(double):double) = {const, not observe} auto var = Ptr(new WfVariableDeclaration); animationClass->declarations.Add(var); auto att = Ptr(new WfAttribute); att->category.value = L"cpp"; att->name.value = L"Private"; var->attributes.Add(att); var->name.value = L"" + name; var->type = GetTypeFromTypeInfo(TypeInfoRetriver>::CreateTypeInfo().Obj()); if (interpolation == L"" || !generateImpl) { auto ref = Ptr(new WfOrderedNameExpression); ref->name.value = L"$1"; auto lambda = Ptr(new WfOrderedLambdaExpression); lambda->body = ref; var->expression = lambda; } else { var->expression = Workflow_ParseExpression(precompileContext, interpolationPosition.originalLocation, interpolation, interpolationPosition, errors); } }; createIntVar(L"", interpolation, interpolationPosition); for (auto target : targets) { if (target.interpolation != L"") { createIntVar(target.name, target.interpolation, target.interpolationPosition); } } List props; List> interpolations; for (auto target : targets) { if (auto propInfo = td->GetPropertyByName(target.name, true)) { if (!propInfo->GetGetter()) { errors.Add({ target.namePosition,L"Precompile: Variable \"" + target.name + L"\" is not supported. An writable property with event is expected." }); } else if (!propInfo->GetSetter()) { errors.Add({ target.namePosition,L"Precompile: Readonly property \"" + target.name + L"\" is not supported. An writable property with event is expected." }); } else if (!propInfo->GetValueChangedEvent()) { errors.Add({ target.namePosition,L"Precompile: Property \"" + target.name + L"\" is not supported. An writable property with event is expected." }); } ValidatePropertyType(target.namePosition, propInfo->GetReturn(), propInfo->GetName(), errors, true); Ptr interpolation; if (target.interpolation != L"" && generateImpl) { interpolation = Workflow_ParseExpression(precompileContext, target.interpolationPosition.originalLocation, target.interpolation, target.interpolationPosition, errors); } props.Add(propInfo); interpolations.Add(interpolation); } else { errors.Add({ target.namePosition,L"Precompile: Property \"" + target.name + L"\" does not exist." }); } } { // func GetTimeScale(begin : , end : , current : ) : double auto func = Ptr(new WfFunctionDeclaration); animationClass->declarations.Add(func); func->functionKind = WfFunctionKind::Normal; func->anonymity = WfFunctionAnonymity::Named; func->name.value = L"GetTimeScale"; { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"begin"; argument->type = GetTypeFromTypeInfo(typeInfo.Obj()); func->arguments.Add(argument); } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"end"; argument->type = GetTypeFromTypeInfo(typeInfo.Obj()); func->arguments.Add(argument); } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"current"; argument->type = GetTypeFromTypeInfo(typeInfo.Obj()); func->arguments.Add(argument); } func->returnType = GetTypeFromTypeInfo(typeInfoDouble.Obj()); if (generateImpl) { auto block = Ptr(new WfBlockStatement); func->statement = block; { auto refZero = Ptr(new WfFloatingExpression); refZero->value.value = L"0.0"; auto varScale = Ptr(new WfVariableDeclaration); varScale->name.value = L"scale"; varScale->expression = refZero; auto declStat = Ptr(new WfVariableStatement); declStat->variable = varScale; block->statements.Add(declStat); } EnumerateProperties([&](EnumerateMemberAccessor accessor, description::IPropertyInfo*, description::IPropertyInfo* propInfo) { auto subBlock = Ptr(new WfBlockStatement); block->statements.Add(subBlock); auto createVariable = [=](const WString& first, const WString& second, const WString& variable) { auto refBegin = Ptr(new WfReferenceExpression); refBegin->name.value = first; auto firstExpr = Ptr(new WfTypeCastingExpression); firstExpr->expression = accessor(refBegin); firstExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); firstExpr->strategy = WfTypeCastingStrategy::Strong; auto refEnd = Ptr(new WfReferenceExpression); refEnd->name.value = second; auto secondExpr = Ptr(new WfTypeCastingExpression); secondExpr->expression = accessor(refEnd); secondExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); secondExpr->strategy = WfTypeCastingStrategy::Strong; auto subExpr = Ptr(new WfBinaryExpression); subExpr->first = firstExpr; subExpr->second = secondExpr; subExpr->op = WfBinaryOperator::Sub; auto refAbs = Ptr(new WfChildExpression); refAbs->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); refAbs->name.value = L"Abs"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refAbs; callExpr->arguments.Add(subExpr); auto varRef = Ptr(new WfVariableDeclaration); varRef->name.value = variable; varRef->expression = callExpr; auto declStat = Ptr(new WfVariableStatement); declStat->variable = varRef; subBlock->statements.Add(declStat); }; createVariable(L"begin", L"end", L"ref"); createVariable(L"current", L"end", L"cur"); { auto refRef = Ptr(new WfReferenceExpression); refRef->name.value = L"ref"; auto refEpsilon = Ptr(new WfFloatingExpression); refEpsilon->value.value = L"0.000001"; auto refMaxEpsilon = Ptr(new WfChildExpression); refMaxEpsilon->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); refMaxEpsilon->name.value = L"Max"; auto callExprEpsilon = Ptr(new WfCallExpression); callExprEpsilon->function = refMaxEpsilon; callExprEpsilon->arguments.Add(refRef); callExprEpsilon->arguments.Add(refEpsilon); auto refCur = Ptr(new WfReferenceExpression); refCur->name.value = L"cur"; auto divExpr = Ptr(new WfBinaryExpression); divExpr->first = refCur; divExpr->second = callExprEpsilon; divExpr->op = WfBinaryOperator::Div; auto refMax = Ptr(new WfChildExpression); refMax->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); refMax->name.value = L"Max"; auto refScale = Ptr(new WfReferenceExpression); refScale->name.value = L"scale"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refMax; callExpr->arguments.Add(refScale); callExpr->arguments.Add(divExpr); auto refScale2 = Ptr(new WfReferenceExpression); refScale2->name.value = L"scale"; auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->first = refScale2; assignExpr->second = callExpr; assignExpr->op = WfBinaryOperator::Assign; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = assignExpr; subBlock->statements.Add(exprStat); } }, td); { auto refOne = Ptr(new WfFloatingExpression); refOne->value.value = L"1.0"; auto refScale = Ptr(new WfReferenceExpression); refScale->name.value = L"scale"; auto refMin = Ptr(new WfChildExpression); refMin->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); refMin->name.value = L"Min"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refMin; callExpr->arguments.Add(refOne); callExpr->arguments.Add(refScale); auto returnStat = Ptr(new WfReturnStatement); returnStat->expression = callExpr; block->statements.Add(returnStat); } } else { func->statement = notImplemented(); } } { // func Interpolate(begin : , end : , current : , ratio : double) : void auto func = Ptr(new WfFunctionDeclaration); animationClass->declarations.Add(func); func->functionKind = WfFunctionKind::Normal; func->anonymity = WfFunctionAnonymity::Named; func->name.value = L"Interpolate"; { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"begin"; argument->type = GetTypeFromTypeInfo(typeInfo.Obj()); func->arguments.Add(argument); } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"end"; argument->type = GetTypeFromTypeInfo(typeInfo.Obj()); func->arguments.Add(argument); } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"current"; argument->type = GetTypeFromTypeInfo(typeInfo.Obj()); func->arguments.Add(argument); } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"ratio"; argument->type = GetTypeFromTypeInfo(typeInfoDouble.Obj()); func->arguments.Add(argument); } func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); if (generateImpl) { auto block = Ptr(new WfBlockStatement); func->statement = block; SortedList varNames; EnumerateProperties([&](EnumerateMemberAccessor accessor, description::IPropertyInfo* propInfo, description::IPropertyInfo* originPropInfo) { WString intFunc = L""; if (From(targets).Any([=](const Target& target) { return target.name == originPropInfo->GetName() && target.interpolation != L""; })) { intFunc += originPropInfo->GetName(); } Ptr part1, part2, propChain; { auto refParent = Ptr(new WfReferenceExpression); refParent->name.value = L"begin"; auto refProp = Ptr(new WfTypeCastingExpression); refProp->expression = (propChain = accessor(refParent)); refProp->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); refProp->strategy = WfTypeCastingStrategy::Strong; auto refOne = Ptr(new WfFloatingExpression); refOne->value.value = L"1.0"; auto refInt = Ptr(new WfReferenceExpression); refInt->name.value = intFunc; auto refRatio = Ptr(new WfReferenceExpression); refRatio->name.value = L"ratio"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refInt; callExpr->arguments.Add(refRatio); auto subExpr = Ptr(new WfBinaryExpression); subExpr->first = refOne; subExpr->second = callExpr; subExpr->op = WfBinaryOperator::Sub; auto mulExpr = Ptr(new WfBinaryExpression); mulExpr->first = refProp; mulExpr->second = subExpr; mulExpr->op = WfBinaryOperator::Mul; part1 = mulExpr; } { auto refParent = Ptr(new WfReferenceExpression); refParent->name.value = L"end"; auto refProp = Ptr(new WfTypeCastingExpression); refProp->expression = accessor(refParent); refProp->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); refProp->strategy = WfTypeCastingStrategy::Strong; auto refInt = Ptr(new WfReferenceExpression); refInt->name.value = intFunc; auto refRatio = Ptr(new WfReferenceExpression); refRatio->name.value = L"ratio"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refInt; callExpr->arguments.Add(refRatio); auto mulExpr = Ptr(new WfBinaryExpression); mulExpr->first = refProp; mulExpr->second = callExpr; mulExpr->op = WfBinaryOperator::Mul; part2 = mulExpr; } Ptr exprMixed; { auto addExpr = Ptr(new WfBinaryExpression); addExpr->first = part1; addExpr->second = part2; addExpr->op = WfBinaryOperator::Add; if (propInfo->GetReturn()->GetTypeDescriptor() == description::GetTypeDescriptor()) { exprMixed = addExpr; } else if(propInfo->GetReturn()->GetTypeDescriptor() == description::GetTypeDescriptor()) { exprMixed = addExpr; } else { auto refRound = Ptr(new WfChildExpression); refRound->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); refRound->name.value = L"Round"; auto callRoundExpr = Ptr(new WfCallExpression); callRoundExpr->function = refRound; callRoundExpr->arguments.Add(addExpr); exprMixed = callRoundExpr; } } auto castExpr = Ptr(new WfTypeCastingExpression); castExpr->expression = exprMixed; castExpr->type = GetTypeFromTypeInfo(propInfo->GetReturn()); castExpr->strategy = WfTypeCastingStrategy::Strong; auto varRef = Ptr(new WfVariableDeclaration); { WString name = L""; while (auto member = propChain.Cast()) { name = L"_" + member->name.value + name; propChain = member->parent; } varNames.Add(name); varRef->name.value = L"" + name; } varRef->expression = castExpr; auto declStat = Ptr(new WfVariableStatement); declStat->variable = varRef; block->statements.Add(declStat); }, td); for (auto target : targets) { auto refCurrent = Ptr(new WfReferenceExpression); refCurrent->name.value = L"current"; auto refProp = Ptr(new WfMemberExpression); refProp->parent = refCurrent; refProp->name.value = target.name; auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->first = refProp; assignExpr->second = InitStruct(td->GetPropertyByName(target.name, true), L"", varNames); assignExpr->op = WfBinaryOperator::Assign; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = assignExpr; block->statements.Add(exprStat); } } else { func->statement = notImplemented(); } } { // func Interpolate(ratio : double) : void auto func = Ptr(new WfFunctionDeclaration); animationClass->declarations.Add(func); func->functionKind = WfFunctionKind::Normal; func->anonymity = WfFunctionAnonymity::Named; func->name.value = L"Interpolate"; { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"ratio"; argument->type = GetTypeFromTypeInfo(typeInfoDouble.Obj()); func->arguments.Add(argument); } func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); if (generateImpl) { auto block = Ptr(new WfBlockStatement); func->statement = block; auto refBegin = Ptr(new WfReferenceExpression); refBegin->name.value = L"Begin"; auto refEnd = Ptr(new WfReferenceExpression); refEnd->name.value = L"End"; auto refCurrent = Ptr(new WfReferenceExpression); refCurrent->name.value = L"Current"; auto refRatio = Ptr(new WfReferenceExpression); refRatio->name.value = L"ratio"; auto refFunc = Ptr(new WfReferenceExpression); refFunc->name.value = L"Interpolate"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refFunc; callExpr->arguments.Add(refBegin); callExpr->arguments.Add(refEnd); callExpr->arguments.Add(refCurrent); callExpr->arguments.Add(refRatio); auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = callExpr; block->statements.Add(exprStat); } else { func->statement = notImplemented(); } } { // func CreateAnimation(target : , time : UInt64) : IGuiAnimation^ auto func = Ptr(new WfFunctionDeclaration); animationClass->declarations.Add(func); func->functionKind = WfFunctionKind::Normal; func->anonymity = WfFunctionAnonymity::Named; func->name.value = L"CreateAnimation"; { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"target"; argument->type = GetTypeFromTypeInfo(typeInfo.Obj()); func->arguments.Add(argument); } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"time"; argument->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); func->arguments.Add(argument); } func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver>::CreateTypeInfo().Obj()); if (generateImpl) { auto block = Ptr(new WfBlockStatement); func->statement = block; { auto refEnd = Ptr(new WfReferenceExpression); refEnd->name.value = L"End"; auto refTarget = Ptr(new WfReferenceExpression); refTarget->name.value = L"target"; auto refCurrent = Ptr(new WfReferenceExpression); refCurrent->name.value = L"Current"; auto refFunc = Ptr(new WfReferenceExpression); refFunc->name.value = L"GetTimeScale"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refFunc; callExpr->arguments.Add(refEnd); callExpr->arguments.Add(refTarget); callExpr->arguments.Add(refCurrent); auto refTime = Ptr(new WfReferenceExpression); refTime->name.value = L"time"; auto mulExpr = Ptr(new WfBinaryExpression); mulExpr->first = refTime; mulExpr->second = callExpr; mulExpr->op = WfBinaryOperator::Mul; auto refRound = Ptr(new WfChildExpression); refRound->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); refRound->name.value = L"Round"; auto callRoundExpr = Ptr(new WfCallExpression); callRoundExpr->function = refRound; callRoundExpr->arguments.Add(mulExpr); auto castExpr = Ptr(new WfTypeCastingExpression); castExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); castExpr->expression = callRoundExpr; castExpr->strategy = WfTypeCastingStrategy::Strong; auto varDecl = Ptr(new WfVariableDeclaration); varDecl->name.value = L"scaledTime"; varDecl->expression = castExpr; auto varStat = Ptr(new WfVariableStatement); varStat->variable = varDecl; block->statements.Add(varStat); } { for (auto target : targets) { auto refBegin = Ptr(new WfReferenceExpression); refBegin->name.value = L"Begin"; auto refBeginProp = Ptr(new WfMemberExpression); refBeginProp->parent = refBegin; refBeginProp->name.value = target.name; auto refCurrent = Ptr(new WfReferenceExpression); refCurrent->name.value = L"Current"; auto refCurrentProp = Ptr(new WfMemberExpression); refCurrentProp->parent = refCurrent; refCurrentProp->name.value = target.name; auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->first = refBeginProp; assignExpr->second = refCurrentProp; assignExpr->op = WfBinaryOperator::Assign; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = assignExpr; block->statements.Add(exprStat); } } { auto refEnd = Ptr(new WfReferenceExpression); refEnd->name.value = L"End"; auto refTarget = Ptr(new WfReferenceExpression); refTarget->name.value = L"target"; auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->first = refEnd; assignExpr->second = refTarget; assignExpr->op = WfBinaryOperator::Assign; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = assignExpr; block->statements.Add(exprStat); } { auto refCA = Ptr(new WfChildExpression); refCA->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); refCA->name.value = L"CreateAnimation"; auto funcExpr = Ptr(new WfFunctionExpression); { auto funcDecl = Ptr(new WfFunctionDeclaration); funcExpr->function = funcDecl; funcDecl->functionKind = WfFunctionKind::Normal; funcDecl->anonymity = WfFunctionAnonymity::Anonymous; { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"currentTime"; argument->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); funcDecl->arguments.Add(argument); } funcDecl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); auto subBlock = Ptr(new WfBlockStatement); funcDecl->statement = subBlock; { auto refCurrentTime = Ptr(new WfReferenceExpression); refCurrentTime->name.value = L"currentTime"; auto firstExpr = Ptr(new WfTypeCastingExpression); firstExpr->expression = refCurrentTime; firstExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); firstExpr->strategy = WfTypeCastingStrategy::Strong; auto refTime = Ptr(new WfReferenceExpression); refTime->name.value = L"time"; auto secondExpr = Ptr(new WfTypeCastingExpression); secondExpr->expression = refTime; secondExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); secondExpr->strategy = WfTypeCastingStrategy::Strong; auto divExpr = Ptr(new WfBinaryExpression); divExpr->first = firstExpr; divExpr->second = secondExpr; divExpr->op = WfBinaryOperator::Div; auto refInt = Ptr(new WfReferenceExpression); refInt->name.value = L"Interpolate"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refInt; callExpr->arguments.Add(divExpr); auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = callExpr; subBlock->statements.Add(exprStat); } } auto refTime = Ptr(new WfReferenceExpression); refTime->name.value = L"time"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refCA; callExpr->arguments.Add(funcExpr); callExpr->arguments.Add(refTime); auto returnStat = Ptr(new WfReturnStatement); returnStat->expression = callExpr; block->statements.Add(returnStat); } } else { func->statement = notImplemented(); } } { // new (current : ) auto func = Ptr(new WfConstructorDeclaration); animationClass->declarations.Add(func); func->constructorType = WfConstructorType::SharedPtr; { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"current"; argument->type = GetTypeFromTypeInfo(typeInfo.Obj()); func->arguments.Add(argument); } if (generateImpl) { auto block = Ptr(new WfBlockStatement); func->statement = block; { List propNames; propNames.Add(L"Begin"); propNames.Add(L"End"); propNames.Add(L"Current"); for (auto propName : propNames) { { auto newExpr = Ptr(new WfNewClassExpression); newExpr->type = GetTypeFromTypeInfo(typeInfo.Obj()); auto refProp = Ptr(new WfReferenceExpression); refProp->name.value = propName; auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->first = refProp; assignExpr->second = newExpr; assignExpr->op = WfBinaryOperator::Assign; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = assignExpr; block->statements.Add(exprStat); } for (auto target : targets) { auto refProp = Ptr(new WfReferenceExpression); refProp->name.value = propName; auto refPropProp = Ptr(new WfMemberExpression); refPropProp->parent = refProp; refPropProp->name.value = target.name; auto refCurrent = Ptr(new WfReferenceExpression); refCurrent->name.value = L"current"; auto refCurrentProp = Ptr(new WfMemberExpression); refCurrentProp->parent = refCurrent; refCurrentProp->name.value = target.name; auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->first = refPropProp; assignExpr->second = refCurrentProp; assignExpr->op = WfBinaryOperator::Assign; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = assignExpr; block->statements.Add(exprStat); } } } } else { func->statement = notImplemented(); } } return module; } else { errors.Add({ typePosition, L"Precompile: Type \"" + typeName + L"\" is not a class." }); } } else { errors.Add({ typePosition, L"Precompile: Type \"" + typeName + L"\" does not exist." }); } return nullptr; } } } /*********************************************************************** .\GUIINSTANCELOADER.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace glr ::xml; using namespace controls; using namespace regex; using namespace reflection::description; using namespace stream; using namespace workflow; using namespace workflow::analyzer; using namespace workflow::typeimpl; /*********************************************************************** GuiInstancePropertyInfo ***********************************************************************/ Ptr GuiInstancePropertyInfo::Unsupported() { return Ptr(new GuiInstancePropertyInfo); } Ptr GuiInstancePropertyInfo::Assign(Ptr typeInfo) { auto info = Ptr(new GuiInstancePropertyInfo); info->support = SupportAssign; if (typeInfo) info->acceptableTypes.Add(typeInfo); return info; } Ptr GuiInstancePropertyInfo::AssignWithParent(Ptr typeInfo) { auto info = Assign(typeInfo); info->mergability = MergeWithParent; return info; } Ptr GuiInstancePropertyInfo::Collection(Ptr typeInfo) { auto info = Assign(typeInfo); info->support = SupportCollection; return info; } Ptr GuiInstancePropertyInfo::CollectionWithParent(Ptr typeInfo) { auto info = Collection(typeInfo); info->mergability = MergeWithParent; return info; } Ptr GuiInstancePropertyInfo::Set(Ptr typeInfo) { auto info = Ptr(new GuiInstancePropertyInfo); info->support = SupportSet; if (typeInfo) info->acceptableTypes.Add(typeInfo); return info; } Ptr GuiInstancePropertyInfo::Array(Ptr typeInfo) { auto info = Ptr(new GuiInstancePropertyInfo); info->support = SupportArray; if (typeInfo) info->acceptableTypes.Add(typeInfo); return info; } /*********************************************************************** IGuiInstanceLoader ***********************************************************************/ void IGuiInstanceLoader::ClearReflectionCache() { } void IGuiInstanceLoader::GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List& propertyNames) { } void IGuiInstanceLoader::GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List& propertyNames) { } void IGuiInstanceLoader::GetPairedProperties(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo, collections::List& propertyNames) { } Ptr IGuiInstanceLoader::GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo) { return nullptr; } bool IGuiInstanceLoader::CanCreate(const TypeInfo& typeInfo) { return false; } Ptr IGuiInstanceLoader::CreateRootInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, ArgumentMap& arguments, GuiResourceError::List& errors) { CHECK_FAIL(L"IGuiInstanceLoader::CreateRootInstance(GuiResourcePrecompileContext&, types::ResolvingResult&, const TypeInfo&, Ptr, ArgumentMap&, GuiResourceError::List&)#This function is not implemented."); } Ptr IGuiInstanceLoader::InitializeRootInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceError::List& errors) { return nullptr; } Ptr IGuiInstanceLoader::CreateInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos tagPosition, GuiResourceError::List& errors) { CHECK_FAIL(L"IGuiInstanceLoader::CreateInstance(GuiResourcePrecompileContext&, types::ResolvingResult&, const TypeInfo&, GlobalStringKey, ArgumentMap&, GuiResourceTextPos, GuiResourceError::List&)#This function is not implemented."); } Ptr IGuiInstanceLoader::AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors) { CHECK_FAIL(L"IGuiInstanceLoader::AssignParameters(GuiResourcePrecompileContext&, types::ResolvingResult&, const TypeInfo&, GlobalStringKey, ArgumentMap&, GuiResourceTextPos, GuiResourceError::List&)#This function is not implemented."); } Ptr IGuiInstanceLoader::GetParameter(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const PropertyInfo& propertyInfo, GlobalStringKey variableName, GuiResourceTextPos attPosition, GuiResourceError::List& errors) { CHECK_FAIL(L"IGuiInstanceLoader::GetParameter(GuiResourcePrecompileContext&, types::ResolvingResult&, const PropertyInfo&, GlobalStringKey, GuiResourceTextPos, GuiResourceError::List&)#This function is not implemented."); } /*********************************************************************** GuiInstanceContext::ElementName Parser ***********************************************************************/ class GuiInstanceContextElementNameParser : public Object, public IGuiParser { typedef GuiInstanceContext::ElementName ElementName; public: Regex regexElementName; const vint _namespaceName; const vint _category; const vint _name; const vint _binding; GuiInstanceContextElementNameParser() : regexElementName(L"(([a-zA-Z_]/w*):)?(([a-zA-Z_]/w*).)?([a-zA-Z_]/w*)(-([a-zA-Z_]/w*))?") , _namespaceName(regexElementName.CaptureNames().IndexOf(L"namespaceName")) , _category(regexElementName.CaptureNames().IndexOf(L"category")) , _name(regexElementName.CaptureNames().IndexOf(L"name")) , _binding(regexElementName.CaptureNames().IndexOf(L"binding")) { } Ptr ParseInternal(const WString& text, collections::List& errors)override { Ptr match = regexElementName.MatchHead(text); if (!match || match->Result().Length() != text.Length()) { glr::ParsingError error; error.message = L"Failed to parse an element name \"" + text + L"\"."; errors.Add(error); return nullptr; } auto elementName = Ptr(new ElementName); if (match->Groups().Keys().Contains(_namespaceName)) { elementName->namespaceName = match->Groups()[_namespaceName][0].Value(); } if (match->Groups().Keys().Contains(_category)) { elementName->category = match->Groups()[_category][0].Value(); } if (match->Groups().Keys().Contains(_name)) { elementName->name = match->Groups()[_name][0].Value(); } if (match->Groups().Keys().Contains(_binding)) { elementName->binding = match->Groups()[_binding][0].Value(); } return elementName; } }; /*********************************************************************** GuiDefaultInstanceLoader ***********************************************************************/ #define CTOR_PARAM_PREFIX\ static const wchar_t Prefix[] = L"";\ static const vint PrefixLength = (vint)sizeof(Prefix) / sizeof(*Prefix) - 1;\ #define CTOR_PARAM_NAME(NAME) (NAME).Right((NAME).Length() - PrefixLength) class GuiDefaultInstanceLoader : public Object, public IGuiInstanceLoader { protected: typedef Tuple FieldKey; typedef Tuple, IPropertyInfo*> PropertyType; Dictionary propertyTypes; Dictionary defaultConstructors; Dictionary instanceConstructors; public: IMethodInfo* GetDefaultConstructor(ITypeDescriptor* typeDescriptor) { IMethodInfo* ctor = nullptr; vint index = defaultConstructors.Keys().IndexOf(typeDescriptor); if (index == -1) { if (auto ctors = typeDescriptor->GetConstructorGroup()) { vint count = ctors->GetMethodCount(); for (vint i = 0; i < count; i++) { IMethodInfo* method = ctors->GetMethod(i); if (method->GetParameterCount() == 0) { ctor = method; break; } } } defaultConstructors.Add(typeDescriptor, ctor); } else { ctor = defaultConstructors.Values()[index]; } return ctor; } IMethodInfo* GetInstanceConstructor(ITypeDescriptor* typeDescriptor) { CTOR_PARAM_PREFIX IMethodInfo* ctor = nullptr; vint index = instanceConstructors.Keys().IndexOf(typeDescriptor); if (index == -1) { if (dynamic_cast(typeDescriptor)) { if (auto group = typeDescriptor->GetConstructorGroup()) { if (group->GetMethodCount() == 1) { auto method = group->GetMethod(0); vint count = method->GetParameterCount(); for (vint i = 0; i < count; i++) { const auto& name = method->GetParameter(i)->GetName(); if (name.Length() <= PrefixLength || name.Left(PrefixLength) != Prefix) { goto FINISHED; } if (!typeDescriptor->GetPropertyByName(CTOR_PARAM_NAME(name), false)) { goto FINISHED; } } ctor = method; } } } FINISHED: instanceConstructors.Add(typeDescriptor, ctor); } else { ctor = instanceConstructors.Values()[index]; } return ctor; } GlobalStringKey GetTypeName()override { return GlobalStringKey::Empty; } void ClearReflectionCache()override { propertyTypes.Clear(); defaultConstructors.Clear(); instanceConstructors.Clear(); } //*********************************************************************************** ITypeInfo* ProcessGenericType(ITypeInfo* propType, bool& readableList, bool& writableList, bool& collectionType) { readableList = false; writableList = false; collectionType = false; if (propType->GetDecorator() == ITypeInfo::SharedPtr && propType->GetElementType()->GetDecorator() == ITypeInfo::Generic) { auto genericType = propType->GetElementType(); if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { readableList = true; writableList = true; collectionType = true; return genericType->GetGenericArgument(0); } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { readableList = true; writableList = true; collectionType = true; return genericType->GetGenericArgument(0); } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { collectionType = true; return genericType->GetGenericArgument(0); } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { readableList = true; collectionType = true; return genericType->GetGenericArgument(0); } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { readableList = true; collectionType = true; return genericType->GetGenericArgument(0); } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { collectionType = true; return nullptr; } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { collectionType = true; return nullptr; } } return propType; } ITypeInfo* GetPropertyReflectionTypeInfo(const PropertyInfo& propertyInfo, GuiInstancePropertyInfo::Support& support) { support = GuiInstancePropertyInfo::NotSupport; IPropertyInfo* prop = propertyInfo.typeInfo.typeInfo->GetTypeDescriptor()->GetPropertyByName(propertyInfo.propertyName.ToString(), true); if (prop) { ITypeInfo* propType = prop->GetReturn(); bool readableList = false; bool writableList = false; bool collectionType = false; auto propValueType = ProcessGenericType(propType, readableList, writableList, collectionType); if (prop->IsWritable()) { if (collectionType) { if (readableList) { support = GuiInstancePropertyInfo::SupportArray; return propValueType; } } else { support = GuiInstancePropertyInfo::SupportAssign; return propValueType; } } else if (prop->IsReadable()) { if (collectionType) { if (writableList) { support = GuiInstancePropertyInfo::SupportCollection; return propValueType; } } else { if (propType->GetDecorator() == ITypeInfo::SharedPtr || propType->GetDecorator() == ITypeInfo::RawPtr) { if (propType->GetElementType()->GetDecorator() != ITypeInfo::Generic) { support = GuiInstancePropertyInfo::SupportSet; return propValueType; } } } } } return nullptr; } void CollectPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, ITypeDescriptor* typeDescriptor, collections::List& propertyNames) { vint propertyCount = typeDescriptor->GetPropertyCount(); for (vint i = 0; i < propertyCount; i++) { GlobalStringKey propertyName = GlobalStringKey::Get(typeDescriptor->GetProperty(i)->GetName()); if (!propertyNames.Contains(propertyName)) { auto info = GetPropertyType(precompileContext, PropertyInfo(typeInfo, propertyName)); if (info && info->support != GuiInstancePropertyInfo::NotSupport) { propertyNames.Add(propertyName); } } } vint parentCount = typeDescriptor->GetBaseTypeDescriptorCount(); for (vint i = 0; i < parentCount; i++) { CollectPropertyNames(precompileContext, typeInfo, typeDescriptor->GetBaseTypeDescriptor(i), propertyNames); } } //*********************************************************************************** void GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List& propertyNames)override { if (CanCreate(typeInfo)) { CTOR_PARAM_PREFIX if (auto ctor = GetInstanceConstructor(typeInfo.typeInfo->GetTypeDescriptor())) { vint count = ctor->GetParameterCount(); for (vint i = 0; i < count; i++) { const auto& name = ctor->GetParameter(i)->GetName(); propertyNames.Add(GlobalStringKey::Get(CTOR_PARAM_NAME(name))); } } } } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List& propertyNames)override { GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); CollectPropertyNames(precompileContext, typeInfo, typeInfo.typeInfo->GetTypeDescriptor(), propertyNames); } PropertyType GetPropertyTypeCached(const PropertyInfo& propertyInfo) { CTOR_PARAM_PREFIX FieldKey key(propertyInfo.typeInfo.typeInfo->GetTypeDescriptor(), propertyInfo.propertyName); vint index = propertyTypes.Keys().IndexOf(key); if (index == -1) { GuiInstancePropertyInfo::Support support = GuiInstancePropertyInfo::NotSupport; if (ITypeInfo* propType = GetPropertyReflectionTypeInfo(propertyInfo, support)) { auto result = Ptr(new GuiInstancePropertyInfo); result->support = support; result->acceptableTypes.Add(CopyTypeInfo(propType)); if (auto ctor = GetInstanceConstructor(propertyInfo.typeInfo.typeInfo->GetTypeDescriptor())) { vint count = ctor->GetParameterCount(); for (vint i = 0; i < count; i++) { const auto& name = ctor->GetParameter(i)->GetName(); if (CTOR_PARAM_NAME(name) == propertyInfo.propertyName.ToString()) { result->usage = GuiInstancePropertyInfo::ConstructorArgument; result->bindability = GuiInstancePropertyInfo::Bindable; } } } IPropertyInfo* prop = propertyInfo.typeInfo.typeInfo->GetTypeDescriptor()->GetPropertyByName(propertyInfo.propertyName.ToString(), true); PropertyType value(result, prop); propertyTypes.Add(key, value); return value; } else { PropertyType value(GuiInstancePropertyInfo::Unsupported(), nullptr); propertyTypes.Add(key, value); return value; } } else { return propertyTypes.Values()[index]; } } Ptr GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { return GetPropertyTypeCached(propertyInfo).get<0>(); } //*********************************************************************************** bool CanCreate(const TypeInfo& typeInfo)override { return GetDefaultConstructor(typeInfo.typeInfo->GetTypeDescriptor()) != nullptr || GetInstanceConstructor(typeInfo.typeInfo->GetTypeDescriptor()) != nullptr; } Ptr CreateRootInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, ArgumentMap& arguments, GuiResourceError::List& errors)override { CTOR_PARAM_PREFIX if (arguments.Count() > 0) { auto call = Ptr(new WfBaseConstructorCall); auto baseTd = typeInfo.typeInfo->GetTypeDescriptor()->GetBaseTypeDescriptor(0); auto baseTypeInfo = Ptr(new TypeDescriptorTypeInfo(baseTd, TypeInfoHint::Normal)); call->type = GetTypeFromTypeInfo(baseTypeInfo.Obj()); auto ctor = baseTd->GetConstructorGroup()->GetMethod(0); vint count = ctor->GetParameterCount(); for (vint i = 0; i < count; i++) { auto key = GlobalStringKey::Get(CTOR_PARAM_NAME(ctor->GetParameter(0)->GetName())); vint index = arguments.Keys().IndexOf(key); if (index == -1) { return nullptr; } else { call->arguments.Add(arguments.GetByIndex(index)[0].expression); } } return call; } return nullptr; } Ptr CreateInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos tagPosition, GuiResourceError::List& errors)override { CTOR_PARAM_PREFIX auto defaultCtor = GetDefaultConstructor(typeInfo.typeInfo->GetTypeDescriptor()); auto instanceCtor = GetInstanceConstructor(typeInfo.typeInfo->GetTypeDescriptor()); auto create = Ptr(new WfNewClassExpression); if (defaultCtor) { create->type = GetTypeFromTypeInfo(defaultCtor->GetReturn()); } else { create->type = GetTypeFromTypeInfo(instanceCtor->GetReturn()); vint count = instanceCtor->GetParameterCount(); for (vint i = 0; i < count; i++) { const auto& name = instanceCtor->GetParameter(i)->GetName(); auto key = GlobalStringKey::Get(CTOR_PARAM_NAME(name)); vint index = arguments.Keys().IndexOf(key); if (index == -1) { return nullptr; } else { create->arguments.Add(arguments.GetByIndex(index)[0].expression); } } } auto refValue = Ptr(new WfReferenceExpression); refValue->name.value = variableName.ToString(); auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refValue; assign->second = create; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; return stat; } Ptr AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); for (auto [prop, index] : indexed(arguments.Keys())) { PropertyType propertyType = GetPropertyTypeCached(PropertyInfo(typeInfo, prop)); if (propertyType.get<1>()) { switch (propertyType.get<0>()->support) { case GuiInstancePropertyInfo::SupportCollection: { const auto& values = arguments.GetByIndex(index); if (values.Count() > 0) { { auto refValue = Ptr(new WfReferenceExpression); refValue->name.value = variableName.ToString(); auto refProp = Ptr(new WfMemberExpression); refProp->parent = refValue; refProp->name.value = prop.ToString(); auto varDesc = Ptr(new WfVariableDeclaration); varDesc->name.value = L""; varDesc->expression = refProp; auto stat = Ptr(new WfVariableStatement); stat->variable = varDesc; block->statements.Add(stat); } // TODO: (enumerable) foreach for (vint i = 0; i < values.Count(); i++) { auto refCollection = Ptr(new WfReferenceExpression); refCollection->name.value = L""; auto refAdd = Ptr(new WfMemberExpression); refAdd->parent = refCollection; refAdd->name.value = L"Add"; auto call = Ptr(new WfCallExpression); call->function = refAdd; call->arguments.Add(values[i].expression); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } } } break; case GuiInstancePropertyInfo::SupportArray: { auto refArray = Ptr(new WfConstructorExpression); for (auto item : arguments.GetByIndex(index)) { auto argument = Ptr(new WfConstructorArgument); argument->key = item.expression; refArray->arguments.Add(argument); } auto refValue = Ptr(new WfReferenceExpression); refValue->name.value = variableName.ToString(); auto refProp = Ptr(new WfMemberExpression); refProp->parent = refValue; refProp->name.value = prop.ToString(); auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refProp; assign->second = refArray; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; block->statements.Add(stat); } break; case GuiInstancePropertyInfo::SupportAssign: { auto& propertyValue = arguments.GetByIndex(index)[0]; if (propertyValue.expression) { auto refValue = Ptr(new WfReferenceExpression); refValue->name.value = variableName.ToString(); auto refProp = Ptr(new WfMemberExpression); refProp->parent = refValue; refProp->name.value = prop.ToString(); auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refProp; assign->second = propertyValue.expression; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; block->statements.Add(stat); } } break; default: errors.Add(GuiResourceError({ resolvingResult.resource }, attPosition, L"Precompile: Property \"" + prop.ToString() + L"\" of type \"" + typeInfo.typeName.ToString() + L"\" is not assignable.")); } } } if (block->statements.Count() > 0) { return block; } return nullptr; } Ptr GetParameter(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const PropertyInfo& propertyInfo, GlobalStringKey variableName, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto refValue = Ptr(new WfReferenceExpression); refValue->name.value = variableName.ToString(); auto refProp = Ptr(new WfMemberExpression); refProp->parent = refValue; refProp->name.value = propertyInfo.propertyName.ToString(); return refProp; } }; #undef CTOR_PARAM_NAME #undef CTOR_PARAM_PREFIX /*********************************************************************** GuiInstanceLoaderManager ***********************************************************************/ IGuiInstanceLoaderManager* instanceLoaderManager = 0; IGuiInstanceLoaderManager* GetInstanceLoaderManager() { return instanceLoaderManager; } class GuiInstanceLoaderManager : public Object, public IGuiInstanceLoaderManager, public IGuiPlugin { protected: typedef Dictionary> BinderMap; typedef Dictionary> EventBinderMap; typedef List> DeserializerList; struct VirtualTypeInfo { GlobalStringKey typeName; ITypeDescriptor* typeDescriptor = nullptr; GlobalStringKey parentTypeName; // for virtual type only Ptr loader; List parentTypes; // all direct or indirect base types that does not has a type info List parentTypeInfos; // type infos for all registered direct or indirect base types }; typedef Dictionary> VirtualTypeInfoMap; Ptr rootLoader; BinderMap binders; EventBinderMap eventBinders; DeserializerList deserializers; VirtualTypeInfoMap typeInfos; bool IsTypeExists(GlobalStringKey name) { return GetGlobalTypeManager()->GetTypeDescriptor(name.ToString()) != 0 || typeInfos.Keys().Contains(name); } void FindParentTypeInfos(Ptr typeInfo, ITypeDescriptor* searchType) { if (searchType != typeInfo->typeDescriptor) { vint index = typeInfos.Keys().IndexOf(GlobalStringKey::Get(searchType->GetTypeName())); if (index == -1) { typeInfo->parentTypes.Add(searchType); } else { typeInfo->parentTypeInfos.Add(typeInfos.Values()[index].Obj()); return; } } vint count = searchType->GetBaseTypeDescriptorCount(); for (vint i = 0; i < count; i++) { ITypeDescriptor* baseType = searchType->GetBaseTypeDescriptor(i); FindParentTypeInfos(typeInfo, baseType); } } void FillParentTypeInfos(Ptr typeInfo) { if (typeInfo->parentTypeName != GlobalStringKey::Empty) { typeInfo->typeDescriptor = nullptr; } typeInfo->parentTypes.Clear(); typeInfo->parentTypeInfos.Clear(); ITypeDescriptor* searchType = typeInfo->typeDescriptor; if (!searchType) { vint index = typeInfos.Keys().IndexOf(typeInfo->parentTypeName); if (index == -1) { searchType = GetGlobalTypeManager()->GetTypeDescriptor(typeInfo->parentTypeName.ToString()); typeInfo->typeDescriptor = searchType; typeInfo->parentTypes.Add(searchType); } else { VirtualTypeInfo* parentTypeInfo = typeInfos.Values()[index].Obj(); typeInfo->typeDescriptor = parentTypeInfo->typeDescriptor; typeInfo->parentTypeInfos.Add(parentTypeInfo); return; } } if (searchType) { FindParentTypeInfos(typeInfo, searchType); } } IGuiInstanceLoader* GetLoaderFromType(ITypeDescriptor* typeDescriptor) { vint index = typeInfos.Keys().IndexOf(GlobalStringKey::Get(typeDescriptor->GetTypeName())); if (index == -1) { vint count = typeDescriptor->GetBaseTypeDescriptorCount(); for (vint i = 0; i < count; i++) { ITypeDescriptor* baseType = typeDescriptor->GetBaseTypeDescriptor(i); IGuiInstanceLoader* loader = GetLoaderFromType(baseType); if (loader) return loader; } return 0; } else { return typeInfos.Values()[index]->loader.Obj(); } } public: GuiInstanceLoaderManager() { rootLoader = Ptr(new GuiDefaultInstanceLoader); } GUI_PLUGIN_NAME(GacUI_Instance) { GUI_PLUGIN_DEPEND(GacUI_Parser); } void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { if (controllerUnrelatedPlugins) { instanceLoaderManager = this; IGuiParserManager* manager = GetParserManager(); manager->SetParser(L"INSTANCE-ELEMENT-NAME", Ptr(new GuiInstanceContextElementNameParser)); } } void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { if (controllerUnrelatedPlugins) { instanceLoaderManager = nullptr; } } bool AddInstanceBinder(Ptr binder)override { if (binders.Keys().Contains(binder->GetBindingName())) return false; binders.Add(binder->GetBindingName(), binder); return true; } IGuiInstanceBinder* GetInstanceBinder(GlobalStringKey bindingName)override { vint index = binders.Keys().IndexOf(bindingName); return index == -1 ? nullptr : binders.Values()[index].Obj(); } bool AddInstanceEventBinder(Ptr binder)override { if (eventBinders.Keys().Contains(binder->GetBindingName())) return false; eventBinders.Add(binder->GetBindingName(), binder); return true; } IGuiInstanceEventBinder* GetInstanceEventBinder(GlobalStringKey bindingName)override { vint index = eventBinders.Keys().IndexOf(bindingName); return index == -1 ? nullptr : eventBinders.Values()[index].Obj(); } bool AddInstanceDeserializer(Ptr deserializer)override { if (deserializers.Contains(deserializer.Obj())) return false; deserializers.Add(deserializer); return true; } IGuiInstanceDeserializer* GetInstanceDeserializer(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override { for (auto deserializer : deserializers) { if (deserializer->CanDeserialize(propertyInfo, typeInfo)) { return deserializer.Obj(); } } return nullptr; } bool CreateVirtualType(GlobalStringKey parentType, Ptr loader)override { if (IsTypeExists(loader->GetTypeName()) || !IsTypeExists(parentType)) return false; auto typeInfo = Ptr(new VirtualTypeInfo); typeInfo->typeName = loader->GetTypeName(); typeInfo->parentTypeName = parentType; typeInfo->loader = loader; typeInfos.Add(loader->GetTypeName(), typeInfo); FillParentTypeInfos(typeInfo); return true; } bool SetLoader(Ptr loader)override { vint index = typeInfos.Keys().IndexOf(loader->GetTypeName()); if (index != -1) return false; ITypeDescriptor* typeDescriptor = GetGlobalTypeManager()->GetTypeDescriptor(loader->GetTypeName().ToString()); if (typeDescriptor == 0) return false; auto typeInfo = Ptr(new VirtualTypeInfo); typeInfo->typeName = loader->GetTypeName(); typeInfo->typeDescriptor = typeDescriptor; typeInfo->loader = loader; typeInfos.Add(typeInfo->typeName, typeInfo); FillParentTypeInfos(typeInfo); for (auto derived : typeInfos.Values()) { if (derived->parentTypes.Contains(typeInfo->typeDescriptor)) { FillParentTypeInfos(derived); } } return true; } IGuiInstanceLoader* GetLoader(GlobalStringKey typeName)override { vint index = typeInfos.Keys().IndexOf(typeName); if (index != -1) { return typeInfos.Values()[index]->loader.Obj(); } ITypeDescriptor* typeDescriptor = GetGlobalTypeManager()->GetTypeDescriptor(typeName.ToString()); if (typeDescriptor) { IGuiInstanceLoader* loader = GetLoaderFromType(typeDescriptor); return loader ? loader : rootLoader.Obj(); } return 0; } IGuiInstanceLoader* GetParentLoader(IGuiInstanceLoader* loader)override { vint index = typeInfos.Keys().IndexOf(loader->GetTypeName()); if (index != -1) { Ptr typeInfo = typeInfos.Values()[index]; if (typeInfo->parentTypeInfos.Count() > 0) { return typeInfo->parentTypeInfos[0]->loader.Obj(); } return rootLoader.Obj(); } return 0; } Ptr GetTypeInfoForType(GlobalStringKey typeName)override { vint index = typeInfos.Keys().IndexOf(typeName); auto td = index == -1 ? GetGlobalTypeManager()->GetTypeDescriptor(typeName.ToString()) : typeInfos.Values()[index]->typeDescriptor; if (!td) return nullptr; if (auto ctor = td->GetConstructorGroup()) { return CopyTypeInfo(ctor->GetMethod(0)->GetReturn()); } else if (td == description::GetTypeDescriptor()) { return Ptr(new SharedPtrTypeInfo(Ptr(new TypeDescriptorTypeInfo(td, TypeInfoHint::Normal)))); } else { return Ptr(new RawPtrTypeInfo(Ptr(new TypeDescriptorTypeInfo(td, TypeInfoHint::Normal)))); } } void GetVirtualTypes(collections::List& typeNames)override { // TODO: (enumerable) foreach on dictionary for (vint i = 0; i < typeInfos.Count(); i++) { if (typeInfos.Values()[i]->parentTypeName != GlobalStringKey::Empty) { typeNames.Add(typeInfos.Keys()[i]); } } } GlobalStringKey GetParentTypeForVirtualType(GlobalStringKey virtualType)override { vint index = typeInfos.Keys().IndexOf(virtualType); if (index != -1) { auto typeInfo = typeInfos.Values()[index]; return typeInfo->parentTypeName; } return GlobalStringKey::Empty; } void ClearReflectionCache()override { rootLoader->ClearReflectionCache(); for (auto info : typeInfos.Values()) { info->loader->ClearReflectionCache(); } } }; GUI_REGISTER_PLUGIN(GuiInstanceLoaderManager) /*********************************************************************** Helper Functions ***********************************************************************/ void Split(const WString& input, const WString& delimiter, collections::List& fragments) { const wchar_t* attValue = input.Buffer(); while (*attValue) { // split the value by ';' const wchar_t* attSemicolon = wcsstr(attValue, delimiter.Buffer()); WString pattern; if (attSemicolon) { pattern = WString::CopyFrom(attValue, vint(attSemicolon - attValue)); attValue = attSemicolon + delimiter.Length(); } else { vint len = wcslen(attValue); pattern = WString::CopyFrom(attValue, len); attValue += len; } fragments.Add(pattern); } } void SplitTypeName(const WString& input, collections::List& fragments) { Split(input, L"::", fragments); } void SplitBySemicolon(const WString& input, collections::List& fragments) { Split(input, L";", fragments); } } } /*********************************************************************** .\GUIINSTANCELOADER_PREDEFINEDINSTANCEBINDERS.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace reflection::description; using namespace workflow; using namespace workflow::analyzer; using namespace workflow::runtime; using namespace instancequery; using namespace controls; using namespace stream; /*********************************************************************** GuiResourceInstanceBinder (uri) ***********************************************************************/ class GuiResourceInstanceBinder : public Object, public IGuiInstanceBinder { public: GlobalStringKey GetBindingName()override { return GlobalStringKey::_Uri; } bool ApplicableToConstructorArgument()override { return true; } bool RequirePropertyExist()override { return false; } Ptr GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { WString protocol, path; if (!IsResourceUrl(code, protocol, path)) { errors.Add(GuiResourceError({ resolvingResult.resource }, position, L"Precompile: \"" + code + L"\" is not a valid resource uri.")); return nullptr; } else if (!precompileContext.resolver->ResolveResource(protocol, path)) { errors.Add(GuiResourceError({ resolvingResult.resource }, position, L"Precompile: Resource \"" + code + L"\" does not exist.")); return nullptr; } else { return Workflow_GetUriProperty(precompileContext, resolvingResult, loader, prop, propInfo, protocol, path, position, errors); } } Ptr GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { WString protocol, path; if (!IsResourceUrl(code, protocol, path)) { errors.Add(GuiResourceError({ resolvingResult.resource }, position, L"Precompile: \"" + code + L"\" is not a valid resource uri.")); return nullptr; } else if (!precompileContext.resolver->ResolveResource(protocol, path)) { errors.Add(GuiResourceError({ resolvingResult.resource }, position, L"Precompile: Resource \"" + code + L"\" does not exist.")); return nullptr; } else { return Workflow_InstallUriProperty(precompileContext, resolvingResult, variableName, loader, prop, propInfo, protocol, path, position, errors); } } }; /*********************************************************************** GuiReferenceInstanceBinder (ref) ***********************************************************************/ class GuiReferenceInstanceBinder : public Object, public IGuiInstanceBinder { public: GlobalStringKey GetBindingName()override { return GlobalStringKey::_Ref; } bool ApplicableToConstructorArgument()override { return false; } bool RequirePropertyExist()override { return false; } Ptr GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { CHECK_FAIL(L"GuiReferenceInstanceBinder::GenerateConstructorArgument()#This binder does not support binding to constructor arguments. Please call ApplicableToConstructorArgument() to determine before calling this function."); } Ptr GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { auto expression = Ptr(new WfReferenceExpression); expression->name.value = code; return Workflow_InstallEvalProperty(precompileContext, resolvingResult, variableName, loader, prop, propInfo, expression, position, errors); } }; /*********************************************************************** GuiEvalInstanceBinder (eval) ***********************************************************************/ class GuiEvalInstanceBinder : public Object, public IGuiInstanceBinder { public: GlobalStringKey GetBindingName()override { return GlobalStringKey::_Eval; } bool ApplicableToConstructorArgument()override { return true; } bool RequirePropertyExist()override { return false; } Ptr GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { return Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, code, position, errors); } Ptr GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { if(auto expression = Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, code, position, errors)) { return Workflow_InstallEvalProperty(precompileContext, resolvingResult, variableName, loader, prop, propInfo, expression, position, errors); } return nullptr; } }; /*********************************************************************** GuiBindInstanceBinder (bind) ***********************************************************************/ class GuiBindInstanceBinder : public Object, public IGuiInstanceBinder { public: GlobalStringKey GetBindingName()override { return GlobalStringKey::_Bind; } bool ApplicableToConstructorArgument()override { return false; } bool RequirePropertyExist()override { return true; } Ptr GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { CHECK_FAIL(L"GuiBindInstanceBinder::GenerateConstructorArgument()#This binder does not support binding to constructor arguments. Please call ApplicableToConstructorArgument() to determine before calling this function."); } Ptr GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { if(auto expression = Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, code, position, errors)) { auto inferExpr = Ptr(new WfInferExpression); inferExpr->expression = expression; inferExpr->type = GetTypeFromTypeInfo(propertyInfo->GetReturn()); auto bindExpr = Ptr(new WfBindExpression); bindExpr->expression = inferExpr; return Workflow_InstallBindProperty(precompileContext, resolvingResult, variableName, propertyInfo, bindExpr); } return nullptr; } }; /*********************************************************************** GuiFormatInstanceBinder (format) ***********************************************************************/ class GuiFormatInstanceBinder : public Object, public IGuiInstanceBinder { public: GlobalStringKey GetBindingName()override { return GlobalStringKey::_Format; } bool ApplicableToConstructorArgument()override { return false; } bool RequirePropertyExist()override { return true; } Ptr GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { CHECK_FAIL(L"GuiFormatInstanceBinder::GenerateConstructorArgument()#This binder does not support binding to constructor arguments. Please call ApplicableToConstructorArgument() to determine before calling this function."); } Ptr GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { if (auto expression = Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, L"bind($\"" + code + L"\")", position, errors, { 0,7 })) // bind($" { return Workflow_InstallBindProperty(precompileContext, resolvingResult, variableName, propertyInfo, expression); } return nullptr; } }; /*********************************************************************** GuiLocalizedStringInstanceBinder (str) ***********************************************************************/ class GuiLocalizedStringInstanceBinder : public Object, public IGuiInstanceBinder { public: GlobalStringKey GetBindingName()override { return GlobalStringKey::_Str; } bool ApplicableToConstructorArgument()override { return false; } bool RequirePropertyExist()override { return true; } Ptr GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { CHECK_FAIL(L"GuiLocalizedStringInstanceBinder::GenerateConstructorArgument()#This binder does not support binding to constructor arguments. Please call ApplicableToConstructorArgument() to determine before calling this function."); } Ptr GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { if (auto expression = Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, code, position, errors, { 0,0 })) { vint errorCount = errors.Count(); if (auto callExpr = expression.Cast()) { if (auto refExpr = callExpr->function.Cast()) { auto defaultLs=From(resolvingResult.context->localizeds) .Where([](Ptr ls) { return ls->defaultStrings; }) .First(nullptr); if (defaultLs) { auto thisExpr = Ptr(new WfReferenceExpression); thisExpr->name.value = L""; thisExpr->codeRange = refExpr->codeRange; auto thisMember = Ptr(new WfMemberExpression); thisMember->parent = thisExpr; thisMember->name.value = defaultLs->name.ToString(); thisMember->codeRange = refExpr->codeRange; auto refMember = Ptr(new WfMemberExpression); refMember->parent = thisMember; refMember->name.value = refExpr->name.value; refMember->codeRange = refExpr->codeRange; callExpr->function = refMember; goto PASSED; } else { errors.Add({ position,L"Precompiled: Omitting the name of the localized strings requires specifying a default one in by adding a Default=\"true\" attribute." }); } } else if (auto memberExpr = callExpr->function.Cast()) { if (auto refStrings = memberExpr->parent.Cast()) { auto thisExpr = Ptr(new WfReferenceExpression); thisExpr->name.value = L""; thisExpr->codeRange = refStrings->codeRange; auto thisMember = Ptr(new WfMemberExpression); thisMember->parent = thisExpr; thisMember->name.value = refStrings->name.value; thisMember->codeRange = refStrings->codeRange; memberExpr->parent = thisMember; goto PASSED; } } errors.Add({ position,L"Precompiled: The function expression in binding \"-str\" should be a \"\" or \".\"." }); PASSED:; } else { errors.Add({ position,L"Precompiled: Expression in binding \"-str\" should be a function call expression." }); } if (errorCount == errors.Count()) { auto bindExpr = Ptr(new WfBindExpression); bindExpr->expression = expression; bindExpr->codeRange = expression->codeRange; return Workflow_InstallBindProperty(precompileContext, resolvingResult, variableName, propertyInfo, bindExpr); } } return nullptr; } }; /*********************************************************************** GuiEvalInstanceEventBinder (eval) ***********************************************************************/ class GuiEvalInstanceEventBinder : public Object, public IGuiInstanceEventBinder { public: GlobalStringKey GetBindingName()override { return GlobalStringKey::_Eval; } Ptr GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IEventInfo* eventInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override { bool coroutine = false; { auto reading = code.Buffer(); while (true) { switch (*reading) { case ' ': case '\t': case '\r': case '\n': reading++; break; default: goto BEGIN_TESTING; } } BEGIN_TESTING: coroutine = *reading == '$'; } auto parseFunction = coroutine ? &Workflow_ParseCoProviderStatement : &Workflow_ParseStatement; if (auto statement = parseFunction(precompileContext, { resolvingResult.resource }, code, position, errors, { 0,0 })) { return Workflow_InstallEvalEvent(precompileContext, resolvingResult, variableName, eventInfo, statement); } return nullptr; } }; /*********************************************************************** GuiPredefinedInstanceBindersPlugin ***********************************************************************/ class GuiParser_WorkflowType : public IGuiParser { protected: Ptr parser; public: GuiParser_WorkflowType(Ptr _parser) :parser(_parser) { } Ptr ParseInternal(const WString& text, List& errors) override { auto handler = glr::InstallDefaultErrorMessageGenerator(*parser.Obj(), errors); auto ast = ParseType(text, *parser.Obj()); parser->OnError.Remove(handler); return ast; } }; class GuiParser_WorkflowExpression : public IGuiParser { protected: Ptr parser; public: GuiParser_WorkflowExpression(Ptr _parser) :parser(_parser) { } Ptr ParseInternal(const WString& text, List& errors) override { auto handler = glr::InstallDefaultErrorMessageGenerator(*parser.Obj(), errors); auto ast = ParseExpression(text, *parser.Obj()); parser->OnError.Remove(handler); return ast; } }; class GuiParser_WorkflowStatement : public IGuiParser { protected: Ptr parser; public: GuiParser_WorkflowStatement(Ptr _parser) :parser(_parser) { } Ptr ParseInternal(const WString& text, List& errors) override { auto handler = glr::InstallDefaultErrorMessageGenerator(*parser.Obj(), errors); auto ast = ParseStatement(text, *parser.Obj()); parser->OnError.Remove(handler); return ast; } }; class GuiParser_WorkflowCoProviderStatement : public IGuiParser { protected: Ptr parser; public: GuiParser_WorkflowCoProviderStatement(Ptr _parser) :parser(_parser) { } Ptr ParseInternal(const WString& text, List& errors) override { auto handler = glr::InstallDefaultErrorMessageGenerator(*parser.Obj(), errors); auto ast = ParseCoProviderStatement(text, *parser.Obj()); parser->OnError.Remove(handler); return ast; } }; class GuiParser_WorkflowDeclaration : public IGuiParser { protected: Ptr parser; public: GuiParser_WorkflowDeclaration(Ptr _parser) :parser(_parser) { } Ptr ParseInternal(const WString& text, List& errors) override { auto handler = glr::InstallDefaultErrorMessageGenerator(*parser.Obj(), errors); auto ast = ParseDeclaration(text, *parser.Obj()); parser->OnError.Remove(handler); return ast; } }; class GuiParser_WorkflowModule : public IGuiParser { protected: Ptr parser; public: GuiParser_WorkflowModule(Ptr _parser) :parser(_parser) { } Ptr ParseInternal(const WString& text, List& errors) override { auto handler = glr::InstallDefaultErrorMessageGenerator(*parser.Obj(), errors); auto ast = ParseModule(text, *parser.Obj()); parser->OnError.Remove(handler); return ast; } }; class GuiParser_InstanceQuery : public IGuiParser { protected: instancequery::Parser parser; public: Ptr ParseInternal(const WString& text, List& errors) override { auto handler = glr::InstallDefaultErrorMessageGenerator(parser, errors); auto ast = parser.ParseQueryRoot(text); parser.OnError.Remove(handler); return ast; } }; class GuiPredefinedInstanceBindersPlugin : public Object, public IGuiPlugin { public: GUI_PLUGIN_NAME(GacUI_Compiler_ParsersAndBinders) { GUI_PLUGIN_DEPEND(GacUI_Parser); GUI_PLUGIN_DEPEND(GacUI_Res_ResourceResolver); GUI_PLUGIN_DEPEND(GacUI_Instance); GUI_PLUGIN_DEPEND(GacUI_Instance_Reflection); } void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { if (controllerUnrelatedPlugins) { WorkflowAstLoadTypes(); GuiInstanceQueryAstLoadTypes(); { auto workflowParser = Ptr(new workflow::Parser); IGuiParserManager* manager = GetParserManager(); manager->SetParser(L"WORKFLOW-TYPE", Ptr(new GuiParser_WorkflowType(workflowParser))); manager->SetParser(L"WORKFLOW-EXPRESSION", Ptr(new GuiParser_WorkflowExpression(workflowParser))); manager->SetParser(L"WORKFLOW-STATEMENT", Ptr(new GuiParser_WorkflowStatement(workflowParser))); manager->SetParser(L"WORKFLOW-COPROVIDER-STATEMENT", Ptr(new GuiParser_WorkflowCoProviderStatement(workflowParser))); manager->SetParser(L"WORKFLOW-DECLARATION", Ptr(new GuiParser_WorkflowDeclaration(workflowParser))); manager->SetParser(L"WORKFLOW-MODULE", Ptr(new GuiParser_WorkflowModule(workflowParser))); manager->SetParser(L"INSTANCE-QUERY", Ptr(new GuiParser_InstanceQuery)); } { IGuiInstanceLoaderManager* manager = GetInstanceLoaderManager(); manager->AddInstanceBinder(Ptr(new GuiResourceInstanceBinder)); manager->AddInstanceBinder(Ptr(new GuiReferenceInstanceBinder)); manager->AddInstanceBinder(Ptr(new GuiEvalInstanceBinder)); manager->AddInstanceBinder(Ptr(new GuiBindInstanceBinder)); manager->AddInstanceBinder(Ptr(new GuiFormatInstanceBinder)); manager->AddInstanceBinder(Ptr(new GuiLocalizedStringInstanceBinder)); manager->AddInstanceEventBinder(Ptr(new GuiEvalInstanceEventBinder)); } } } void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { } }; GUI_REGISTER_PLUGIN(GuiPredefinedInstanceBindersPlugin) } } /*********************************************************************** .\GUIINSTANCELOADER_PREDEFINEDINSTANCEDESERIALIZERS.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace reflection::description; using namespace workflow; using namespace workflow::analyzer; using namespace controls; using namespace controls::list; using namespace templates; /*********************************************************************** GuiTemplatePropertyDeserializer ***********************************************************************/ class GuiTemplatePropertyDeserializer : public Object, public IGuiInstanceDeserializer { protected: Ptr stringType; bool IsTemplatePropertyType(ITypeInfo* propType) { if (propType->GetDecorator() == ITypeInfo::SharedPtr) { auto genericType = propType->GetElementType(); if (genericType->GetDecorator() == ITypeInfo::Generic && genericType->GetGenericArgumentCount() == 2) { if (genericType->GetElementType()->GetTypeDescriptor() == description::GetTypeDescriptor()) { if (genericType->GetGenericArgument(1)->GetTypeDescriptor() == description::GetTypeDescriptor()) { auto returnType = genericType->GetGenericArgument(0); if (returnType->GetDecorator() == ITypeInfo::RawPtr) { if (returnType->GetElementType()->GetTypeDescriptor()->CanConvertTo(description::GetTypeDescriptor())) { return true; } } } } } } return false; } bool IsDataVisualizerFactoryType(ITypeInfo* propType) { return propType->GetDecorator() == ITypeInfo::SharedPtr && propType->GetTypeDescriptor() == description::GetTypeDescriptor(); } bool IsDataEditorFactoryType(ITypeInfo* propType) { return propType->GetDecorator() == ITypeInfo::SharedPtr && propType->GetTypeDescriptor() == description::GetTypeDescriptor(); } public: GuiTemplatePropertyDeserializer() { stringType = TypeInfoRetriver::CreateTypeInfo(); } bool CanDeserialize(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override { return IsTemplatePropertyType(typeInfo) || IsDataVisualizerFactoryType(typeInfo) || IsDataEditorFactoryType(typeInfo); } description::ITypeInfo* DeserializeAs(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override { return stringType.Obj(); } static void GetItemTemplateType( types::ResolvingResult& resolvingResult, WString typeNamesString, List& tds, GuiResourceTextPos tagPosition, GuiResourceError::List& errors ) { List typeNames; SplitBySemicolon(typeNamesString, typeNames); if (typeNames.Count() == 0) { errors.Add(GuiResourceError({ resolvingResult.resource }, tagPosition, L"Precompile: Template list \"" + typeNamesString + L"\" cannot be empty.")); } for (auto controlTemplateName : typeNames) { auto controlTemplateTd = description::GetTypeDescriptor(controlTemplateName); if (!controlTemplateTd) { auto index = INVLOC.FindFirst(controlTemplateName, L":", Locale::None); GlobalStringKey namespaceName; auto typeName = controlTemplateName; if (index.key != -1) { namespaceName = GlobalStringKey::Get(controlTemplateName.Left(index.key)); typeName = controlTemplateName.Right(controlTemplateName.Length() - index.key - index.value); } auto source = FindInstanceLoadingSource(resolvingResult.context, namespaceName, typeName); if (auto typeInfo = GetInstanceLoaderManager()->GetTypeInfoForType(source.typeName)) { controlTemplateTd = typeInfo->GetTypeDescriptor(); } } if (controlTemplateTd) { tds.Add(controlTemplateTd); } else { errors.Add(GuiResourceError({ resolvingResult.resource }, tagPosition, L"Precompile: Type \"" + controlTemplateName + L"\" does not exist.")); continue; } } } static Ptr CreateTemplateFactory( types::ResolvingResult& resolvingResult, List& controlTemplateTds, ITypeInfo* returnTemplateType, ITypeInfo* expectedTemplateType, GuiResourceTextPos tagPosition, GuiResourceError::List& errors ) { auto funcCreateTemplate = Ptr(new WfFunctionDeclaration); funcCreateTemplate->functionKind = WfFunctionKind::Normal; funcCreateTemplate->anonymity = WfFunctionAnonymity::Anonymous; funcCreateTemplate->returnType = GetTypeFromTypeInfo(returnTemplateType); auto argViewModel = Ptr(new WfFunctionArgument); argViewModel->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); argViewModel->name.value = L""; funcCreateTemplate->arguments.Add(argViewModel); auto block = Ptr(new WfBlockStatement); funcCreateTemplate->statement = block; ITypeDescriptor* stopControlTemplateTd = nullptr; for (auto controlTemplateTd : controlTemplateTds) { if (!controlTemplateTd->CanConvertTo(expectedTemplateType->GetTypeDescriptor())) { errors.Add(GuiResourceError({ resolvingResult.resource }, tagPosition, L"Precompile: Type \"" + controlTemplateTd->GetTypeName() + L"\" cannot be used here because it requires \"" + expectedTemplateType->GetTypeDescriptor()->GetTypeName() + L"\" or its derived classes.")); } if (stopControlTemplateTd) { errors.Add(GuiResourceError({ resolvingResult.resource }, tagPosition, L"Precompile: Type \"" + controlTemplateTd->GetTypeName() + L"\" will never be tried, because \"" + stopControlTemplateTd->GetTypeName() + L"\", which is listed before, has a default constructor. So whatever the view model is, it will be the last choice.")); continue; } ITypeInfo* viewModelType = nullptr; { auto ctors = controlTemplateTd->GetConstructorGroup(); if (!ctors || ctors->GetMethodCount() != 1) { errors.Add(GuiResourceError({ resolvingResult.resource }, tagPosition, L"Precompile: To use type \"" + controlTemplateTd->GetTypeName() + L"\" as a control template or item template, it should have exactly one constructor.")); continue; } auto ctor = ctors->GetMethod(0); if (ctor->GetParameterCount() > 1) { errors.Add(GuiResourceError({ resolvingResult.resource }, tagPosition, L"Precompile: To use type \"" + controlTemplateTd->GetTypeName() + L"\" as a control template or item template, its constructor cannot have more than one parameter.")); continue; } if (ctor->GetParameterCount() != 0) { viewModelType = ctor->GetParameter(0)->GetType(); } } if (!viewModelType) { stopControlTemplateTd = controlTemplateTd; } auto subBlock = Ptr(new WfBlockStatement); block->statements.Add(subBlock); Ptr controlTemplateType; { auto elementType = Ptr(new TypeDescriptorTypeInfo(controlTemplateTd, TypeInfoHint::Normal)); auto pointerType = Ptr(new RawPtrTypeInfo(elementType)); controlTemplateType = pointerType; } Ptr returnStatBlock; if (viewModelType) { auto refViewModel = Ptr(new WfReferenceExpression); refViewModel->name.value = L""; auto condition = Ptr(new WfTypeTestingExpression); condition->test = WfTypeTesting::IsType; condition->expression = refViewModel; condition->type = GetTypeFromTypeInfo(viewModelType); auto ifStat = Ptr(new WfIfStatement); subBlock->statements.Add(ifStat); ifStat->expression = condition; returnStatBlock = Ptr(new WfBlockStatement); ifStat->trueBranch = returnStatBlock; } else { returnStatBlock = subBlock; } { auto createControlTemplate = Ptr(new WfNewClassExpression); createControlTemplate->type = GetTypeFromTypeInfo(controlTemplateType.Obj()); if (viewModelType) { auto refViewModel = Ptr(new WfReferenceExpression); refViewModel->name.value = L""; auto cast = Ptr(new WfTypeCastingExpression); cast->strategy = WfTypeCastingStrategy::Strong; cast->expression = refViewModel; cast->type = GetTypeFromTypeInfo(viewModelType); createControlTemplate->arguments.Add(cast); } auto returnStat = Ptr(new WfReturnStatement); returnStat->expression = createControlTemplate; returnStatBlock->statements.Add(returnStat); } } if (!stopControlTemplateTd) { auto value = Ptr(new WfStringExpression); value->value.value = L"Cannot find a matched control template to create."; auto raiseStat = Ptr(new WfRaiseExceptionStatement); raiseStat->expression = value; block->statements.Add(raiseStat); } auto expr = Ptr(new WfFunctionExpression); expr->function = funcCreateTemplate; return expr; } static Ptr CreateDataVisualizerFactory( types::ResolvingResult& resolvingResult, List& controlTemplateTds, GuiResourceTextPos tagPosition, GuiResourceError::List& errors ) { auto templateType = TypeInfoRetriver::CreateTypeInfo(); Ptr previousFactory; for (auto [controlTemplateTd, index] : indexed(controlTemplateTds)) { List tds; tds.Add(controlTemplateTd); auto refFactory = CreateTemplateFactory(resolvingResult, tds, templateType.Obj(), templateType.Obj(), tagPosition, errors); auto createStyle = Ptr(new WfNewClassExpression); createStyle->type = GetTypeFromTypeInfo(TypeInfoRetriver>::CreateTypeInfo().Obj()); createStyle->arguments.Add(refFactory); if (index > 0) { createStyle->arguments.Add(previousFactory); } else { auto nullExpr = Ptr(new WfLiteralExpression); nullExpr->value = WfLiteralValue::Null; createStyle->arguments.Add(nullExpr); } previousFactory = createStyle; } return previousFactory; } static Ptr CreateDataEditorFactory( types::ResolvingResult& resolvingResult, List& controlTemplateTds, GuiResourceTextPos tagPosition, GuiResourceError::List& errors ) { auto templateType = TypeInfoRetriver::CreateTypeInfo(); auto refFactory = CreateTemplateFactory(resolvingResult, controlTemplateTds, templateType.Obj(), templateType.Obj(), tagPosition, errors); auto createStyle = Ptr(new WfNewClassExpression); createStyle->type = GetTypeFromTypeInfo(TypeInfoRetriver>::CreateTypeInfo().Obj()); createStyle->arguments.Add(refFactory); return createStyle; } Ptr Deserialize( GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo, Ptr valueExpression, GuiResourceTextPos tagPosition, GuiResourceError::List& errors )override { auto stringExpr = valueExpression.Cast(); List tds; GetItemTemplateType(resolvingResult, stringExpr->value.value, tds, tagPosition, errors); if (IsDataVisualizerFactoryType(typeInfo)) { return CreateDataVisualizerFactory(resolvingResult, tds, tagPosition, errors); } else if (IsDataEditorFactoryType(typeInfo)) { return CreateDataEditorFactory(resolvingResult, tds, tagPosition, errors); } else { auto returnTemplateType = typeInfo->GetElementType()->GetGenericArgument(0); auto expectedTemplateType = returnTemplateType; if (propertyInfo.propertyName == GlobalStringKey::_ControlTemplate) { auto td = propertyInfo.typeInfo.typeInfo->GetTypeDescriptor(); if (td != nullptr && td->CanConvertTo(description::GetTypeDescriptor())) { auto methodGroup = td->GetMethodGroupByName(L"GetControlTemplateObject", true); vint count = methodGroup->GetMethodCount(); for (vint i = 0; i < count; i++) { auto methodInfo = methodGroup->GetMethod(i); if (methodInfo->GetParameterCount() == 1) { auto returnType = methodInfo->GetReturn(); if (returnType->GetDecorator() == ITypeInfo::RawPtr) { if (returnType->GetTypeDescriptor()->CanConvertTo(description::GetTypeDescriptor())) { expectedTemplateType = returnType; } } } } } } return CreateTemplateFactory(resolvingResult, tds, returnTemplateType, expectedTemplateType, tagPosition, errors); } } }; /*********************************************************************** GuiItemPropertyDeserializer ***********************************************************************/ class GuiItemPropertyDeserializer : public Object, public IGuiInstanceDeserializer { protected: Ptr stringType; bool IsItemPropertyType(ITypeInfo* propType) { if (propType->GetDecorator() == ITypeInfo::SharedPtr) { auto genericType = propType->GetElementType(); if (genericType->GetDecorator() == ITypeInfo::Generic && genericType->GetGenericArgumentCount() == 2) { if (genericType->GetElementType()->GetTypeDescriptor() == description::GetTypeDescriptor()) { if (genericType->GetGenericArgument(1)->GetTypeDescriptor() == description::GetTypeDescriptor()) { return true; } } } } return false; } bool IsWritableItemPropertyType(ITypeInfo* propType) { if (propType->GetDecorator() == ITypeInfo::SharedPtr) { auto genericType = propType->GetElementType(); if (genericType->GetDecorator() == ITypeInfo::Generic && genericType->GetGenericArgumentCount() == 4) { if (genericType->GetElementType()->GetTypeDescriptor() == description::GetTypeDescriptor()) { if (genericType->GetGenericArgument(1)->GetTypeDescriptor() == description::GetTypeDescriptor() && genericType->GetGenericArgument(3)->GetTypeDescriptor() == description::GetTypeDescriptor()) { if (IsSameType(genericType->GetGenericArgument(0), genericType->GetGenericArgument(2))) { return true; } } } } } return false; } public: GuiItemPropertyDeserializer() { stringType = TypeInfoRetriver::CreateTypeInfo(); } bool CanDeserialize(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override { return IsItemPropertyType(typeInfo) || IsWritableItemPropertyType(typeInfo); } description::ITypeInfo* DeserializeAs(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override { return stringType.Obj(); } Ptr Deserialize( GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo, Ptr valueExpression, GuiResourceTextPos tagPosition, GuiResourceError::List& errors )override { auto stringExpr = valueExpression.Cast(); Ptr propertyExpression; { propertyExpression = Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, stringExpr->value.value, tagPosition, errors); if (!propertyExpression) { return nullptr; } }; vint indexItemType = resolvingResult.envVars.Keys().IndexOf(GlobalStringKey::Get(L"ItemType")); if (indexItemType == -1) { auto error = L"Precompile: env.ItemType must be specified before deserializing \"" + stringExpr->value.value + L"\" to value of type \"" + typeInfo->GetTypeFriendlyName() + L"\"."; errors.Add(GuiResourceError({ resolvingResult.resource }, tagPosition, error)); return nullptr; } Ptr itemType; { const auto& values = resolvingResult.envVars.GetByIndex(indexItemType); auto itemTypeValue = values[values.Count() - 1]; itemType = Workflow_ParseType(precompileContext, { resolvingResult.resource }, itemTypeValue->value, itemTypeValue->valuePosition, errors); if (!itemType) { return nullptr; } }; vint indexItemName = resolvingResult.envVars.Keys().IndexOf(GlobalStringKey::Get(L"ItemName")); WString itemName = WString::Unmanaged(L"item"); if (indexItemName != -1) { const auto& values = resolvingResult.envVars.GetByIndex(indexItemName); itemName = values[values.Count() - 1]->value; } if (auto refExpr = propertyExpression.Cast()) { if (refExpr->name.value != itemName) { auto refItem = Ptr(new WfReferenceExpression); refItem->name.value = itemName; auto member = Ptr(new WfMemberExpression); member->parent = refItem; member->name.value = refExpr->name.value; propertyExpression = member; } } bool isWritableItemProperty = IsWritableItemPropertyType(typeInfo); auto funcDecl = Ptr(new WfFunctionDeclaration); ITypeInfo* acceptValueType = nullptr; funcDecl->functionKind = WfFunctionKind::Normal; funcDecl->anonymity = WfFunctionAnonymity::Anonymous; { auto genericType = typeInfo->GetElementType(); funcDecl->returnType = GetTypeFromTypeInfo(genericType->GetGenericArgument(0)); { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L""; argument->type = GetTypeFromTypeInfo(genericType->GetGenericArgument(1)); funcDecl->arguments.Add(argument); } if (isWritableItemProperty) { { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L""; argument->type = GetTypeFromTypeInfo((acceptValueType = genericType->GetGenericArgument(2))); funcDecl->arguments.Add(argument); } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L""; argument->type = GetTypeFromTypeInfo(genericType->GetGenericArgument(3)); funcDecl->arguments.Add(argument); } } } auto funcBlock = Ptr(new WfBlockStatement); funcDecl->statement = funcBlock; { auto refItem = Ptr(new WfReferenceExpression); refItem->name.value = L""; auto refCast = Ptr(new WfTypeCastingExpression); refCast->strategy = WfTypeCastingStrategy::Strong; refCast->type = itemType; refCast->expression = refItem; auto varDecl = Ptr(new WfVariableDeclaration); varDecl->name.value = itemName; varDecl->expression = refCast; auto varStat = Ptr(new WfVariableStatement); varStat->variable = varDecl; funcBlock->statements.Add(varStat); } Ptr returnStat; { returnStat = Ptr(new WfReturnStatement); returnStat->expression = propertyExpression; } if (isWritableItemProperty) { auto ifStat = Ptr(new WfIfStatement); funcBlock->statements.Add(ifStat); { auto refUpdate = Ptr(new WfReferenceExpression); refUpdate->name.value = L""; ifStat->expression = refUpdate; } { auto block = Ptr(new WfBlockStatement); ifStat->trueBranch = block; { auto refValue = Ptr(new WfReferenceExpression); refValue->name.value = L""; auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->op = WfBinaryOperator::Assign; assignExpr->first = CopyExpression(propertyExpression, true); if (acceptValueType->GetTypeDescriptor()->GetTypeDescriptorFlags() == TypeDescriptorFlags::Object) { auto castExpr = Ptr(new WfExpectedTypeCastExpression); castExpr->strategy = WfTypeCastingStrategy::Strong; castExpr->expression = refValue; assignExpr->second = castExpr; } else { assignExpr->second = refValue; } auto stat = Ptr(new WfExpressionStatement); stat->expression = assignExpr; block->statements.Add(stat); } { auto returnStat = Ptr(new WfReturnStatement); block->statements.Add(returnStat); auto returnType = typeInfo->GetElementType()->GetGenericArgument(0); returnStat->expression = CreateDefaultValue(returnType); } } { auto block = Ptr(new WfBlockStatement); ifStat->falseBranch = block; block->statements.Add(returnStat); } } else { funcBlock->statements.Add(returnStat); } auto funcExpr = Ptr(new WfFunctionExpression); funcExpr->function = funcDecl; return funcExpr; } }; /*********************************************************************** GuiDataProcessorDeserializer ***********************************************************************/ class GuiDataProcessorDeserializer : public Object, public IGuiInstanceDeserializer { protected: Ptr stringType; public: GuiDataProcessorDeserializer() { stringType = TypeInfoRetriver::CreateTypeInfo(); } bool CanDeserialize(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override { return typeInfo->GetTypeDescriptor() == description::GetTypeDescriptor() || typeInfo->GetTypeDescriptor() == description::GetTypeDescriptor(); } description::ITypeInfo* DeserializeAs(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override { return stringType.Obj(); } Ptr Deserialize( GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo, Ptr valueExpression, GuiResourceTextPos tagPosition, GuiResourceError::List& errors )override { auto stringExpr = valueExpression.Cast(); Ptr propertyExpression; { propertyExpression = Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, stringExpr->value.value, tagPosition, errors); if (!propertyExpression) { return nullptr; } }; vint indexItemType = resolvingResult.envVars.Keys().IndexOf(GlobalStringKey::Get(L"ItemType")); if (indexItemType == -1) { auto error = L"Precompile: env.ItemType must be specified before deserializing \"" + stringExpr->value.value + L"\" to value of type \"" + typeInfo->GetTypeFriendlyName() + L"\"."; errors.Add(GuiResourceError({ resolvingResult.resource }, tagPosition, error)); return nullptr; } Ptr itemType; { const auto& values = resolvingResult.envVars.GetByIndex(indexItemType); auto itemTypeValue = values[values.Count() - 1]; itemType = Workflow_ParseType(precompileContext, { resolvingResult.resource }, itemTypeValue->value, itemTypeValue->valuePosition, errors); if (!itemType) { return nullptr; } }; auto newExpr = Ptr(new WfNewInterfaceExpression); newExpr->type = GetTypeFromTypeInfo(typeInfo); { auto decl = Ptr(new WfFunctionDeclaration); newExpr->declarations.Add(decl); decl->functionKind = WfFunctionKind::Override; decl->name.value = L"SetCallback"; decl->anonymity = WfFunctionAnonymity::Named; decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); { auto argument = Ptr(new WfFunctionArgument); argument->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); argument->name.value = L"value"; decl->arguments.Add(argument); } auto block = Ptr(new WfBlockStatement); decl->statement = block; } { auto decl = Ptr(new WfFunctionDeclaration); newExpr->declarations.Add(decl); decl->functionKind = WfFunctionKind::Override; decl->anonymity = WfFunctionAnonymity::Named; List argumentNames; if (typeInfo->GetTypeDescriptor() == description::GetTypeDescriptor()) { decl->name.value = L"Filter"; decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); argumentNames.Add(L""); } else { decl->name.value = L"Compare"; switch (precompileContext.targetCpuArchitecture) { case GuiResourceCpuArchitecture::x86: decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); break; case GuiResourceCpuArchitecture::x64: decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); break; default: CHECK_FAIL(L"The target CPU architecture is unspecified."); } argumentNames.Add(L""); argumentNames.Add(L""); } for (auto name : argumentNames) { auto argument = Ptr(new WfFunctionArgument); argument->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); argument->name.value = name; decl->arguments.Add(argument); } auto block = Ptr(new WfBlockStatement); decl->statement = block; auto inferExpr = Ptr(new WfInferExpression); inferExpr->expression = propertyExpression; { auto funcType = Ptr(new WfFunctionType); inferExpr->type = funcType; funcType->result = CopyType(decl->returnType); // TODO: (enumerable) Linq:Select for (vint i = 0; i < decl->arguments.Count(); i++) { funcType->arguments.Add(CopyType(itemType)); } } auto callExpr = Ptr(new WfCallExpression); callExpr->function = inferExpr; for (auto [name, index] : indexed(argumentNames)) { auto refExpr = Ptr(new WfReferenceExpression); refExpr->name.value = name; auto castExpr = Ptr(new WfTypeCastingExpression); castExpr->strategy = WfTypeCastingStrategy::Strong; castExpr->type = (index == 0 ? itemType : CopyType(itemType)); castExpr->expression = refExpr; callExpr->arguments.Add(castExpr); } auto stat = Ptr(new WfReturnStatement); stat->expression = callExpr; block->statements.Add(stat); } return newExpr; } }; /*********************************************************************** GuiPredefinedInstanceDeserializersPlugin ***********************************************************************/ class GuiPredefinedInstanceDeserializersPlugin : public Object, public IGuiPlugin { public: GUI_PLUGIN_NAME(GacUI_Instance_Deserializers) { GUI_PLUGIN_DEPEND(GacUI_Instance); } void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { if (controllerUnrelatedPlugins) { IGuiInstanceLoaderManager* manager = GetInstanceLoaderManager(); manager->AddInstanceDeserializer(Ptr(new GuiTemplatePropertyDeserializer)); manager->AddInstanceDeserializer(Ptr(new GuiItemPropertyDeserializer)); manager->AddInstanceDeserializer(Ptr(new GuiDataProcessorDeserializer)); } } void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { } }; GUI_REGISTER_PLUGIN(GuiPredefinedInstanceDeserializersPlugin) } } /*********************************************************************** .\GUIINSTANCELOADER_PREDEFINEDTYPERESOLVERS.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace glr::xml; using namespace workflow; using namespace workflow::analyzer; using namespace workflow::emitter; using namespace workflow::runtime; using namespace reflection::description; using namespace collections; using namespace stream; using namespace controls; class WorkflowVirtualScriptPositionVisitor : public workflow::traverse_visitor::AstVisitor { using BaseVisitor = workflow::traverse_visitor::AstVisitor; public: GuiResourcePrecompileContext& context; Ptr sp; WorkflowVirtualScriptPositionVisitor(GuiResourcePrecompileContext& _context) :context(_context) { sp = Workflow_GetScriptPosition(context); } void Visit(WfVirtualCfeExpression* node)override { BaseVisitor::Visit(node); vint index = sp->nodePositions.Keys().IndexOf(node); if (index != -1) { auto record = sp->nodePositions.Values()[index]; Workflow_RecordScriptPosition(context, record.position, node->expandedExpression, record.availableAfter); } } void Visit(WfVirtualCseExpression* node)override { BaseVisitor::Visit(node); vint index = sp->nodePositions.Keys().IndexOf(node); if (index != -1) { auto record = sp->nodePositions.Values()[index]; Workflow_RecordScriptPosition(context, record.position, node->expandedExpression, record.availableAfter); } } void Visit(WfVirtualCseStatement* node)override { BaseVisitor::Visit(node); vint index = sp->nodePositions.Keys().IndexOf(node); if (index != -1) { auto record = sp->nodePositions.Values()[index]; Workflow_RecordScriptPosition(context, record.position, node->expandedStatement, record.availableAfter); } } void Visit(WfVirtualCfeDeclaration* node)override { BaseVisitor::Visit(node); vint index = sp->nodePositions.Keys().IndexOf(node); if (index != -1) { auto record = sp->nodePositions.Values()[index]; for (auto decl : node->expandedDeclarations) { Workflow_RecordScriptPosition(context, record.position, decl, record.availableAfter); } } } void Visit(WfVirtualCseDeclaration* node)override { BaseVisitor::Visit(node); vint index = sp->nodePositions.Keys().IndexOf(node); if (index != -1) { auto record = sp->nodePositions.Values()[index]; for (auto decl : node->expandedDeclarations) { Workflow_RecordScriptPosition(context, record.position, decl, record.availableAfter); } } } }; Ptr Workflow_GetModule(GuiResourcePrecompileContext& context, const WString& path, Nullable assemblyType) { auto compiled = context.targetFolder->GetValueByPath(path).Cast(); if (assemblyType && !compiled) { compiled = Ptr(new GuiInstanceCompiledWorkflow); compiled->type = assemblyType.Value(); context.targetFolder->CreateValueByPath(path, L"Workflow", compiled); } return compiled; } void Workflow_AddModule(GuiResourcePrecompileContext& context, const WString& path, Ptr module, GuiInstanceCompiledWorkflow::AssemblyType assemblyType, GuiResourceTextPos tagPosition) { auto compiled = Workflow_GetModule(context, path, assemblyType); CHECK_ERROR(compiled->type == assemblyType, L"Workflow_AddModule(GuiResourcePrecompiledContext&, const WString&, GuiInstanceCompiledWorkflow::AssemblyType)#Unexpected assembly type."); GuiInstanceCompiledWorkflow::ModuleRecord record; record.module = module; record.position = tagPosition; record.shared = assemblyType == GuiInstanceCompiledWorkflow::Shared; compiled->modules.Add(record); } void Workflow_GenerateAssembly(GuiResourcePrecompileContext& context, const WString& path, GuiResourceError::List& errors, bool keepMetadata, IWfCompilerCallback* compilerCallback) { auto compiled = Workflow_GetModule(context, path, {}); if (!compiled) { return; } if (!compiled->assembly) { List codes; auto manager = Workflow_GetSharedManager(context.targetCpuArchitecture); manager->Clear(false, true); auto addCode = [&codes](TextReader& reader) { vint row = 0; WString code; while (!reader.IsEnd()) { auto rowHeader = itow(++row); while (rowHeader.Length() < 6) { rowHeader = L" " + rowHeader; } code += rowHeader + L" : " + reader.ReadLine() + L"\r\n"; } codes.Add(code); }; // TODO: (enumerable) Linq:Select for (vint i = 0; i < compiled->modules.Count(); i++) { manager->AddModule(compiled->modules[i].module); } if (manager->errors.Count() == 0) { manager->Rebuild(true, compilerCallback); } if (manager->errors.Count() == 0) { compiled->assembly = GenerateAssembly(manager, compilerCallback); WfAssemblyLoadErrors loadErrors; if (!compiled->Initialize(true, loadErrors)) { glr::ParsingError error; error.message = L"Internal error happened during loading an assembly that just passed type verification."; manager->errors.Add(error); } } else { // TODO: (enumerable) foreach for (vint i = 0; i < compiled->modules.Count(); i++) { auto module = compiled->modules[i]; WorkflowVirtualScriptPositionVisitor visitor(context); visitor.InspectInto(module.module.Obj()); Workflow_RecordScriptPosition(context, module.position, module.module); } auto sp = Workflow_GetScriptPosition(context); // TODO: (enumerable) foreach for (vint i = 0; i < manager->errors.Count(); i++) { auto error = manager->errors[i]; errors.Add({ sp->nodePositions[error.node].computedPosition, error.message }); } } if (keepMetadata) { compiled->metadata = Workflow_TransferSharedManager(); } else { manager->Clear(false, true); } } } /*********************************************************************** Shared Script Type Resolver (Script) ***********************************************************************/ #define Path_Shared L"Workflow/Shared" #define Path_TemporaryClass L"Workflow/TemporaryClass" #define Path_InstanceClass L"Workflow/InstanceClass" class GuiResourceSharedScriptTypeResolver : public Object , public IGuiResourceTypeResolver , private IGuiResourceTypeResolver_Precompile , private IGuiResourceTypeResolver_IndirectLoad { public: WString GetType()override { return L"Script"; } bool XmlSerializable()override { return true; } bool StreamSerializable()override { return false; } WString GetPreloadType()override { return L"Xml"; } bool IsDelayLoad()override { return false; } PassSupport GetPrecompilePassSupport(vint passIndex)override { switch (passIndex) { case Workflow_Collect: return PerResource; case Workflow_Compile: return PerPass; default: return NotSupported; } } void PerResourcePrecompile(Ptr resource, GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override { switch (context.passIndex) { case Workflow_Collect: { if (auto obj = resource->GetContent().Cast()) { if (obj->language == L"Workflow") { if (auto module = Workflow_ParseModule(context, obj->codePosition.originalLocation, obj->code, obj->codePosition, errors)) { Workflow_AddModule(context, Path_Shared, module, GuiInstanceCompiledWorkflow::Shared, obj->codePosition); } } } } break; } } void PerPassPrecompile(GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override { switch (context.passIndex) { case Workflow_Compile: Workflow_GenerateAssembly(context, Path_Shared, errors, false, context.compilerCallback); if (auto compiled = Workflow_GetModule(context, Path_Shared, {})) { // TODO: (enumerable) foreach for (vint i = 0; i < compiled->modules.Count(); i++) { auto& module = compiled->modules[i]; if (module.module) { module.module = CopyModule(module.module, true); } } } break; } } IGuiResourceTypeResolver_Precompile* Precompile()override { return this; } IGuiResourceTypeResolver_IndirectLoad* IndirectLoad()override { return this; } Ptr Serialize(Ptr resource, Ptr content)override { if (auto obj = content.Cast()) { return obj->SaveToXml(); } return nullptr; } Ptr ResolveResource(Ptr resource, Ptr resolver, GuiResourceError::List& errors)override { if (auto xml = resource->GetContent().Cast()) { auto schema = GuiInstanceSharedScript::LoadFromXml(resource, xml, errors); return schema; } return nullptr; } }; /*********************************************************************** Instance Type Resolver (Instance) ***********************************************************************/ class GuiResourceInstanceTypeResolver : public Object , public IGuiResourceTypeResolver , private IGuiResourceTypeResolver_Precompile , private IGuiResourceTypeResolver_IndirectLoad { public: WString GetType()override { return L"Instance"; } bool XmlSerializable()override { return true; } bool StreamSerializable()override { return false; } WString GetPreloadType()override { return L"Xml"; } bool IsDelayLoad()override { return false; } PassSupport GetPrecompilePassSupport(vint passIndex)override { switch (passIndex) { case Workflow_Collect: case Instance_CollectInstanceTypes: case Instance_CollectEventHandlers: case Instance_GenerateInstanceClass: return PerResource; case Instance_CompileInstanceTypes: case Instance_CompileEventHandlers: case Instance_CompileInstanceClass: return PerPass; default: return NotSupported; } } #define ENSURE_ASSEMBLY_EXISTS(PATH, ASSEMBLY_TYPE)\ if (auto compiled = Workflow_GetModule(context, PATH, GuiInstanceCompiledWorkflow::ASSEMBLY_TYPE))\ {\ if (!compiled->assembly)\ {\ break;\ }\ }\ else\ {\ break;\ }\ #define UNLOAD_ASSEMBLY(PATH)\ if (auto compiled = Workflow_GetModule(context, PATH, {}))\ {\ compiled->UnloadTypes();\ }\ #define DELETE_ASSEMBLY(PATH)\ if (auto compiled = Workflow_GetModule(context, PATH, {}))\ {\ compiled->UnloadAssembly();\ }\ void PerResourcePrecompile(Ptr resource, GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override { switch (context.passIndex) { case Workflow_Collect: { if (auto obj = resource->GetContent().Cast()) { auto record = context.targetFolder->GetValueByPath(L"ClassNameRecord").Cast(); if (!record) { record = Ptr(new GuiResourceClassNameRecord); context.targetFolder->CreateValueByPath(L"ClassNameRecord", L"ClassNameRecord", record); } if (!record->classResources.Keys().Contains(obj->className)) { record->classNames.Add(obj->className); record->classResources.Add(obj->className, resource); } } } break; case Instance_CollectEventHandlers: ENSURE_ASSEMBLY_EXISTS(Path_TemporaryClass, TemporaryClass) case Instance_CollectInstanceTypes: { if (auto obj = resource->GetContent().Cast()) { if (obj->className == L"") { errors.Add(GuiResourceError({ resource }, obj->tagPosition, L"Precompile: Instance \"" + (obj->instance->typeNamespace == GlobalStringKey::Empty ? obj->instance->typeName.ToString() : obj->instance->typeNamespace.ToString() + L":" + obj->instance->typeName.ToString() ) + L"\" should have the class name specified in the ref.Class attribute.")); } // TODO: (enumerable) Linq:Take for (auto [localized, index] : indexed(From(obj->localizeds).Where([](Ptr ls) {return ls->defaultStrings; })) ) { if (index > 0) { errors.Add(GuiResourceError({ resource }, localized->tagPosition, L"Precompile: Only one can be the default one.")); } } obj->ApplyStyles(resource, context.resolver, errors); types::ResolvingResult resolvingResult; resolvingResult.resource = resource; resolvingResult.context = obj; if (auto module = Workflow_GenerateInstanceClass(context, L"" + obj->className, resolvingResult, errors, context.passIndex)) { Workflow_AddModule(context, Path_TemporaryClass, module, GuiInstanceCompiledWorkflow::TemporaryClass, obj->tagPosition); } } } break; case Instance_GenerateInstanceClass: { ENSURE_ASSEMBLY_EXISTS(Path_TemporaryClass, TemporaryClass) if (auto obj = resource->GetContent().Cast()) { vint previousErrorCount = errors.Count(); types::ResolvingResult resolvingResult; resolvingResult.resource = resource; resolvingResult.context = obj; resolvingResult.rootTypeInfo = Workflow_CollectReferences(context, resolvingResult, errors); if (errors.Count() == previousErrorCount) { if (auto ctorModule = Workflow_PrecompileInstanceContext(context, L"" + obj->className, resolvingResult, errors)) { if (auto instanceModule = Workflow_GenerateInstanceClass(context, L"" + obj->className, resolvingResult, errors, context.passIndex)) { Workflow_AddModule(context, Path_InstanceClass, ctorModule, GuiInstanceCompiledWorkflow::InstanceClass, obj->tagPosition); Workflow_AddModule(context, Path_InstanceClass, instanceModule, GuiInstanceCompiledWorkflow::InstanceClass, obj->tagPosition); } } } } } break; } } void PerPassPrecompile(GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override { WString path; GuiInstanceCompiledWorkflow::AssemblyType assemblyType; switch (context.passIndex) { case Instance_CompileInstanceTypes: DELETE_ASSEMBLY(Path_Shared) path = Path_TemporaryClass; assemblyType = GuiInstanceCompiledWorkflow::TemporaryClass; break; case Instance_CompileEventHandlers: DELETE_ASSEMBLY(Path_TemporaryClass) path = Path_TemporaryClass; assemblyType = GuiInstanceCompiledWorkflow::TemporaryClass; break; case Instance_CompileInstanceClass: UNLOAD_ASSEMBLY(Path_TemporaryClass) path = Path_InstanceClass; assemblyType = GuiInstanceCompiledWorkflow::InstanceClass; break; default: return; } auto sharedCompiled = Workflow_GetModule(context, Path_Shared, {}); auto compiled = Workflow_GetModule(context, path, assemblyType); if (sharedCompiled && compiled) { CopyFrom( compiled->modules, From(sharedCompiled->modules) .Where([](const GuiInstanceCompiledWorkflow::ModuleRecord& module) { return module.shared; }), true ); } switch (context.passIndex) { case Instance_CompileInstanceTypes: Workflow_GenerateAssembly(context, path, errors, false, context.compilerCallback); compiled->modules.Clear(); break; case Instance_CompileEventHandlers: Workflow_GenerateAssembly(context, path, errors, false, context.compilerCallback); break; case Instance_CompileInstanceClass: Workflow_GenerateAssembly(context, path, errors, true, context.compilerCallback); break; default:; } Workflow_ClearScriptPosition(context); GetInstanceLoaderManager()->ClearReflectionCache(); } #undef DELETE_ASSEMBLY #undef UNLOAD_ASSEMBLY #undef ENSURE_ASSEMBLY_EXISTS IGuiResourceTypeResolver_Precompile* Precompile()override { return this; } IGuiResourceTypeResolver_IndirectLoad* IndirectLoad()override { return this; } Ptr Serialize(Ptr resource, Ptr content)override { if (auto obj = content.Cast()) { return obj->SaveToXml(); } return nullptr; } Ptr ResolveResource(Ptr resource, Ptr resolver, GuiResourceError::List& errors)override { if (auto xml = resource->GetContent().Cast()) { Ptr context = GuiInstanceContext::LoadFromXml(resource, xml, errors); return context; } return nullptr; } }; /*********************************************************************** Instance Style Type Resolver (InstanceStyle) ***********************************************************************/ class GuiResourceInstanceStyleTypeResolver : public Object , public IGuiResourceTypeResolver , private IGuiResourceTypeResolver_IndirectLoad { public: WString GetType()override { return L"InstanceStyle"; } bool XmlSerializable()override { return true; } bool StreamSerializable()override { return false; } WString GetPreloadType()override { return L"Xml"; } bool IsDelayLoad()override { return false; } IGuiResourceTypeResolver_IndirectLoad* IndirectLoad()override { return this; } Ptr Serialize(Ptr resource, Ptr content)override { if (auto obj = content.Cast()) { return obj->SaveToXml(); } return nullptr; } Ptr ResolveResource(Ptr resource, Ptr resolver, GuiResourceError::List& errors)override { if (auto xml = resource->GetContent().Cast()) { auto context = GuiInstanceStyleContext::LoadFromXml(resource, xml, errors); return context; } return nullptr; } }; /*********************************************************************** Animation Type Resolver (Animation) ***********************************************************************/ class GuiResourceAnimationTypeResolver : public Object , public IGuiResourceTypeResolver , private IGuiResourceTypeResolver_Precompile , private IGuiResourceTypeResolver_IndirectLoad { public: WString GetType()override { return L"Animation"; } bool XmlSerializable()override { return true; } bool StreamSerializable()override { return false; } WString GetPreloadType()override { return L"Xml"; } bool IsDelayLoad()override { return false; } PassSupport GetPrecompilePassSupport(vint passIndex)override { switch (passIndex) { case Instance_CollectInstanceTypes: case Instance_CollectEventHandlers: case Instance_GenerateInstanceClass: return PerResource; default: return NotSupported; } } void PerResourcePrecompile(Ptr resource, GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override { bool generateImpl = true; auto path = Path_InstanceClass; auto assemblyType = GuiInstanceCompiledWorkflow::InstanceClass; switch (context.passIndex) { case Instance_CollectEventHandlers: case Instance_CollectInstanceTypes: generateImpl = false; path = Path_TemporaryClass; assemblyType = GuiInstanceCompiledWorkflow::TemporaryClass; case Instance_GenerateInstanceClass: { if (auto obj = resource->GetContent().Cast()) { if (auto module = obj->Compile(context, L"" + obj->className, generateImpl, errors)) { Workflow_AddModule(context, path, module, assemblyType, obj->tagPosition); } } } break; } } void PerPassPrecompile(GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override { CHECK_FAIL(L"GuiResourceAnimationTypeResolver::PerPassPrecompile(GuiResourcePrecompileContext&, GuiResourceError::List&)#This function should not be called."); } IGuiResourceTypeResolver_Precompile* Precompile()override { return this; } IGuiResourceTypeResolver_IndirectLoad* IndirectLoad()override { return this; } Ptr Serialize(Ptr resource, Ptr content)override { if (auto obj = content.Cast()) { return obj->SaveToXml(); } return nullptr; } Ptr ResolveResource(Ptr resource, Ptr resolver, GuiResourceError::List& errors)override { if (auto xml = resource->GetContent().Cast()) { if (xml->rootElement->name.value == L"Gradient") { return GuiInstanceGradientAnimation::LoadFromXml(resource, xml, errors); } else { errors.Add({ { {resource }, xml->rootElement->codeRange.start }, L"Precompile: Unknown animation type: \"" + xml->rootElement->name.value + L"\"." }); } } return nullptr; } }; /*********************************************************************** Localized Strings Type Resolver (LocalizedStrings) ***********************************************************************/ class GuiResourceLocalizedStringsTypeResolver : public Object , public IGuiResourceTypeResolver , private IGuiResourceTypeResolver_Precompile , private IGuiResourceTypeResolver_IndirectLoad { public: WString GetType()override { return L"LocalizedStrings"; } bool XmlSerializable()override { return true; } bool StreamSerializable()override { return false; } WString GetPreloadType()override { return L"Xml"; } bool IsDelayLoad()override { return false; } PassSupport GetPrecompilePassSupport(vint passIndex)override { switch (passIndex) { case Workflow_Collect: case Instance_CompileInstanceClass: return PerResource; default: return NotSupported; } } void PerResourcePrecompile(Ptr resource, GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override { switch (context.passIndex) { case Workflow_Collect: { if (auto obj = resource->GetContent().Cast()) { if (auto module = obj->Compile(context, L"" + obj->className, errors)) { Workflow_AddModule(context, Path_Shared, module, GuiInstanceCompiledWorkflow::Shared, obj->tagPosition); } } } break; case Instance_CompileInstanceClass: { if (auto obj = resource->GetContent().Cast()) { if (auto module = obj->Compile(context, L"" + obj->className, errors)) { Workflow_AddModule(context, Path_InstanceClass, module, GuiInstanceCompiledWorkflow::InstanceClass, obj->tagPosition); } } } break; } } void PerPassPrecompile(GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override { CHECK_FAIL(L"GuiResourceLocalizedStringsTypeResolver::PerPassPrecompile(GuiResourcePrecompileContext&, GuiResourceError::List&)#This function should not be called."); } IGuiResourceTypeResolver_Precompile* Precompile()override { return this; } IGuiResourceTypeResolver_IndirectLoad* IndirectLoad()override { return this; } Ptr Serialize(Ptr resource, Ptr content)override { if (auto obj = content.Cast()) { return obj->SaveToXml(); } if (auto obj = content.Cast()) { return obj->SaveToXml(); } return nullptr; } Ptr ResolveResource(Ptr resource, Ptr resolver, GuiResourceError::List& errors)override { if (auto xml = resource->GetContent().Cast()) { if (xml->rootElement->name.value == L"LocalizedStrings") { return GuiInstanceLocalizedStrings::LoadFromXml(resource, xml, errors); } else if (xml->rootElement->name.value == L"LocalizedStringsInjection") { return GuiInstanceLocalizedStringsInjection::LoadFromXml(resource, xml, errors); } else { errors.Add(GuiResourceError({ { resource },xml->rootElement->codeRange.start }, L"Precompile: The root element of localized strings should be \"LocalizedStrings\" or \"LocalizedStringsInjection\".")); } } return nullptr; } }; #undef Path_Shared #undef Path_TemporaryClass #undef Path_InstanceClass /*********************************************************************** Plugin ***********************************************************************/ class GuiCompilerTypeResolversPlugin : public Object, public IGuiPlugin { public: GUI_PLUGIN_NAME(GacUI_Compiler_InstanceTypeResolvers) { GUI_PLUGIN_DEPEND(GacUI_Res_ResourceResolver); } void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { if (controllerUnrelatedPlugins) { IGuiResourceResolverManager* manager = GetResourceResolverManager(); manager->SetTypeResolver(Ptr(new GuiResourceSharedScriptTypeResolver)); manager->SetTypeResolver(Ptr(new GuiResourceInstanceTypeResolver)); manager->SetTypeResolver(Ptr(new GuiResourceInstanceStyleTypeResolver)); manager->SetTypeResolver(Ptr(new GuiResourceAnimationTypeResolver)); manager->SetTypeResolver(Ptr(new GuiResourceLocalizedStringsTypeResolver)); } } void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { } }; GUI_REGISTER_PLUGIN(GuiCompilerTypeResolversPlugin) } } /*********************************************************************** .\GUIINSTANCELOCALIZEDSTRINGS.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace glr::xml; using namespace workflow; using namespace workflow::analyzer; using namespace reflection::description; /*********************************************************************** GuiInstanceLocalizedStringsBase ***********************************************************************/ WString GuiInstanceLocalizedStringsBase::Strings::GetLocalesName() { return From(locales).Aggregate(WString(L""), [](const WString& a, const WString& b) { return a == L"" ? b : a + L";" + b; }); } /*********************************************************************** GuiInstanceLocalizedStringsBase ***********************************************************************/ Ptr GuiInstanceLocalizedStringsBase::LoadStringsFromXml(Ptr resource, Ptr xmlStrings, collections::SortedList& existingLocales, GuiResourceError::List& errors) { if (xmlStrings->name.value != L"Strings") { errors.Add(GuiResourceError({ { resource },xmlStrings->codeRange.start }, L"Precompile: Unknown element \"" + xmlStrings->name.value + L"\", it should be \"Strings\".")); return nullptr; } auto attLocales = XmlGetAttribute(xmlStrings, L"Locales"); if (!attLocales) { errors.Add(GuiResourceError({ { resource },xmlStrings->codeRange.start }, L"Precompile: Missing attribute \"Locales\" in \"Strings\".")); return nullptr; } auto lss = Ptr(new GuiInstanceLocalizedStrings::Strings); lss->tagPosition = { { resource },xmlStrings->name.codeRange.start }; SplitBySemicolon(attLocales->value.value, lss->locales); for (auto locale : lss->locales) { if (!existingLocales.Contains(locale)) { existingLocales.Add(locale); } else { errors.Add(GuiResourceError({ { resource },attLocales->codeRange.start }, L"Precompile: Locale \"" + locale + L"\" already exists.")); } } for (auto xmlString : XmlGetElements(xmlStrings)) { if (xmlString->name.value != L"String") { errors.Add(GuiResourceError({ { resource },xmlString->codeRange.start }, L"Precompile: Unknown element \"" + xmlString->name.value + L"\", it should be \"String\".")); continue; } auto attName = XmlGetAttribute(xmlString, L"Name"); auto attText = XmlGetAttribute(xmlString, L"Text"); if (!attName) { errors.Add(GuiResourceError({ { resource },xmlString->codeRange.start }, L"Precompile: Missing attribute \"Name\" in \"String\".")); } if (!attText) { errors.Add(GuiResourceError({ { resource },xmlString->codeRange.start }, L"Precompile: Missing attribute \"Text\" in \"String\".")); } if (attName && attText) { if (lss->items.Keys().Contains(attName->value.value)) { errors.Add(GuiResourceError({ { resource },xmlString->codeRange.start }, L"Precompile: String \"" + attName->value.value + L"\" already exists.")); } else { auto item = Ptr(new GuiInstanceLocalizedStrings::StringItem); item->name = attName->value.value; item->text = attText->value.value; item->textPosition = { {resource},attText->value.codeRange.start }; item->textPosition.column += 1; lss->items.Add(item->name, item); } } } return lss; } Ptr GuiInstanceLocalizedStringsBase::SaveStringsToXml(Ptr lss) { auto xmlStrings = Ptr(new XmlElement); xmlStrings->name.value = L"Strings"; { auto att = Ptr(new XmlAttribute); att->name.value = L"Strings"; att->value.value = lss->GetLocalesName(); xmlStrings->attributes.Add(att); } for (auto lssi : lss->items.Values()) { auto xmlString = Ptr(new XmlElement); xmlStrings->subNodes.Add(xmlString); { auto att = Ptr(new XmlAttribute); att->name.value = L"Name"; att->value.value = lssi->name; xmlString->attributes.Add(att); } { auto att = Ptr(new XmlAttribute); att->name.value = L"Text"; att->value.value = lssi->text; xmlString->attributes.Add(att); } } return xmlStrings; } Ptr GuiInstanceLocalizedStringsBase::ParseLocalizedText(const WString& text, GuiResourceTextPos pos, GuiResourceError::List& errors) { const wchar_t* reading = text.Buffer(); const wchar_t* textPosCounter = reading; glr::ParsingTextPos formatPos(0, 0); auto textDesc = Ptr(new TextDesc); auto addError = [&](const WString& message) { auto errorPos = pos; errorPos.row += formatPos.row; errorPos.column = (formatPos.row == 0 ? errorPos.column : 0) + formatPos.column; errors.Add({ errorPos,message }); }; bool addedParameter = true; while (*reading) { const wchar_t* begin = wcsstr(reading, L"$("); if (begin) { auto text = WString::CopyFrom(reading, vint(begin - reading)); if (addedParameter) { textDesc->texts.Add(text); } else { textDesc->texts[textDesc->texts.Count() - 1] += text; } } else { break; } const wchar_t* end = wcsstr(begin, L")"); if (!end) { addError(L"Precompile: Does not find matched close bracket."); return nullptr; } while (textPosCounter++ < begin + 2) { switch (textPosCounter[-1]) { case '\n': formatPos.row++; formatPos.column = 0; break; default: formatPos.column++; break; } } if (end - begin == 3 && wcsncmp(begin, L"$($)", 4) == 0) { addedParameter = false; textDesc->texts[textDesc->texts.Count() - 1] += L"$"; } else { addedParameter = true; const wchar_t* number = begin + 2; const wchar_t* numberEnd = number; while (L'0' <= *numberEnd && *numberEnd < L'9') { numberEnd++; } if (number == numberEnd) { addError(L"Precompile: Unexpected character, the correct format is $(index) or $(index:function)."); return nullptr; } Ptr type; WString function; if (*numberEnd == L':') { if (end - numberEnd > 1) { function = WString::CopyFrom(numberEnd + 1, (vint)(end - numberEnd - 1)); if (function == L"ShortDate" || function == L"LongDate" || function == L"YearMonthDate" || function == L"ShortTime" || function == L"LongTime") { type = TypeInfoRetriver::CreateTypeInfo(); } else if (function.Length() >= 5 && (function.Left(5) == L"Date:" || function.Left(5) == L"Time:")) { type = TypeInfoRetriver::CreateTypeInfo(); } else if (function == L"Number" || function == L"Currency") { type = TypeInfoRetriver::CreateTypeInfo(); } else { addError(L"Precompile: Unknown formatting function name \"" + function + L"\"."); return nullptr; } } else { addError(L"Precompile: Unexpected character, the correct format is $(index) or $(index:function)."); return nullptr; } } else if (numberEnd != end) { addError(L"Precompile: Unexpected character, the correct format is $(index) or $(index:function)."); return nullptr; } if (!type) { type = TypeInfoRetriver::CreateTypeInfo(); } textDesc->parameters.Add({ type,function }); textDesc->positions.Add(wtoi(WString::CopyFrom(number, (vint)(numberEnd - number)))); } reading = end + 1; } if (*reading || textDesc->texts.Count() == 0) { textDesc->texts.Add(reading); } for (auto [i, index] : indexed(From(textDesc->positions).OrderBySelf())) { if (i != index) { errors.Add({ pos,L"Precompile: Missing parameter \"" + itow(index) + L"\"." }); return nullptr; } } return textDesc; } void GuiInstanceLocalizedStringsBase::FillStringsToTextDescMap(Ptr lss, TextDescMap& textDescs, GuiResourceError::List& errors) { for (auto lssi : lss->items.Values()) { if (auto textDesc = ParseLocalizedText(lssi->text, lssi->textPosition, errors)) { textDescs.Add({ lss,lssi->name }, textDesc); } } } void GuiInstanceLocalizedStringsBase::ValidateNamesAgainstDefaultStrings(Ptr defaultStrings, Ptr lss, GuiResourceError::List& errors) { auto localesName = lss->GetLocalesName(); auto missing = From(defaultStrings->items.Keys()) .Except(lss->items.Keys()) .Aggregate(WString(L""), [](const WString& a, const WString& b) { return a == L"" ? b : a + L", " + b; }); auto extra = From(lss->items.Keys()) .Except(defaultStrings->items.Keys()) .Aggregate(WString(L""), [](const WString& a, const WString& b) { return a == L"" ? b : a + L", " + b; }); if (missing != L"") { errors.Add({ lss->tagPosition,L"Precompile: Missing strings for locale \"" + localesName + L"\": " + missing + L"." }); } if (extra != L"") { errors.Add({ lss->tagPosition,L"Precompile: Unnecessary strings for locale \"" + localesName + L"\": " + extra + L"." }); } } void GuiInstanceLocalizedStringsBase::ValidateSignatureAgainstDefaultStrings(Ptr defaultStrings, Ptr lss, TextDescMap& textDescs, GuiResourceError::List& errors) { auto defaultLocalesName = defaultStrings->GetLocalesName(); auto localesName = lss->GetLocalesName(); for (auto lssi : lss->items.Values()) { auto defaultDesc = textDescs[{defaultStrings, lssi->name}]; auto textDesc = textDescs[{lss, lssi->name}]; if (defaultDesc->parameters.Count() != textDesc->parameters.Count()) { errors.Add({ lss->tagPosition,L"String \"" + lssi->name + L"\" in locales \"" + defaultLocalesName + L"\" and \"" + localesName + L"\" have different numbers of parameters." }); } else { // TODO: (enumerable) foreach:indexed for (vint i = 0; i < textDesc->parameters.Count(); i++) { auto defaultParameter = defaultDesc->parameters[defaultDesc->positions[i]]; auto parameter = textDesc->parameters[textDesc->positions[i]]; if (defaultParameter.key->GetTypeDescriptor()->GetTypeName() != parameter.key->GetTypeDescriptor()->GetTypeName()) { errors.Add({ lss->tagPosition,L"Parameter \"" + itow(i) + L"\" in String \"" + lssi->name + L"\" in locales \"" + defaultLocalesName + L"\" and \"" + localesName + L"\" are in different types \"" + defaultParameter.key->GetTypeFriendlyName() + L"\" and \"" + parameter.key->GetTypeFriendlyName() + L"\"." }); } } } } } void GuiInstanceLocalizedStringsBase::ValidateAgainstDefaultStrings(Ptr defaultStrings, collections::List>& nonDefaultStrings, TextDescMap& textDescs, GuiResourceError::List& errors) { vint errorCount = errors.Count(); for (auto lss : nonDefaultStrings) { ValidateNamesAgainstDefaultStrings(defaultStrings, lss, errors); } if (errors.Count() != errorCount) { return; } for (auto lss : nonDefaultStrings) { FillStringsToTextDescMap(lss, textDescs, errors); } if (errors.Count() != errorCount) { return; } for (auto lss : nonDefaultStrings) { ValidateSignatureAgainstDefaultStrings(defaultStrings, lss, textDescs, errors); } if (errors.Count() != errorCount) { return; } } WString GuiInstanceLocalizedStringsBase::GetInterfaceTypeName(const WString& className, bool hasNamespace) { auto pair = INVLOC.FindLast(className, L"::", Locale::None); if (pair.key == -1) { return L"I" + className + L"Strings"; } else { auto ns = className.Left(pair.key + 2); auto name = className.Right(className.Length() - ns.Length()); return(hasNamespace ? ns : L"") + L"I" + name + L"Strings"; } } WString GuiInstanceLocalizedStringsBase::GenerateStringsCppName(Ptr lss) { auto encoded = From(lss->locales) .Aggregate( WString::Empty, [](auto&& a, auto&& b) { return a + WString::Unmanaged(L"_") + b; }); return WString::Unmanaged(L"BuildStrings"); } Ptr GuiInstanceLocalizedStringsBase::GenerateTextDescFunctionHeader(Ptr textDesc, const WString& functionName, workflow::WfFunctionKind functionKind) { auto func = Ptr(new WfFunctionDeclaration); func->functionKind = functionKind; func->anonymity = WfFunctionAnonymity::Named; func->name.value = functionName; func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); // TODO: (enumerable) foreach for (vint i = 0; i < textDesc->positions.Count(); i++) { auto type = textDesc->parameters[textDesc->positions[i]]; auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"" + itow(i); argument->type = GetTypeFromTypeInfo(type.key.Obj()); func->arguments.Add(argument); } return func; } Ptr GuiInstanceLocalizedStringsBase::GenerateTextDescArgumentFormatting(Ptr type, const WString& function, vint argumentIndex) { WString argumentName = L"" + itow(argumentIndex); if (function == L"ShortDate" || function == L"LongDate" || function == L"YearMonthDate" || function == L"ShortTime" || function == L"LongTime") { auto refLoc = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); auto refFormats = Ptr(new WfChildExpression); refFormats->parent = refLoc; refFormats->name.value = L"Get" + function + L"Formats"; auto refLocale = Ptr(new WfReferenceExpression); refLocale->name.value = L"locale"; auto callFormats = Ptr(new WfCallExpression); callFormats->function = refFormats; callFormats->arguments.Add(refLocale); auto refFirst = Ptr(new WfChildExpression); refFirst->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); refFirst->name.value = L"FirstOrEmpty"; auto callFirst = Ptr(new WfCallExpression); { callFirst->function = refFirst; callFirst->arguments.Add(callFormats); } auto refLocale2 = Ptr(new WfReferenceExpression); refLocale2->name.value = L"locale"; auto refParameter = Ptr(new WfReferenceExpression); refParameter->name.value = argumentName; auto refLoc2 = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); auto refFD = Ptr(new WfChildExpression); refFD->parent = refLoc2; refFD->name.value = L"Format" + function.Right(4); auto callFD = Ptr(new WfCallExpression); callFD->function = refFD; callFD->arguments.Add(refLocale2); callFD->arguments.Add(callFirst); callFD->arguments.Add(refParameter); return callFD; } else if (function.Length() >= 5 && (function.Left(5) == L"Date:" || function.Left(5) == L"Time:")) { auto refLocale = Ptr(new WfReferenceExpression); refLocale->name.value = L"locale"; auto refFormat = Ptr(new WfStringExpression); refFormat->value.value = function.Right(function.Length() - 5); auto refParameter = Ptr(new WfReferenceExpression); refParameter->name.value = argumentName; auto refLoc2 = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); auto refFD = Ptr(new WfChildExpression); refFD->parent = refLoc2; refFD->name.value = L"Format" + function.Left(4); auto callFD = Ptr(new WfCallExpression); callFD->function = refFD; callFD->arguments.Add(refLocale); callFD->arguments.Add(refFormat); callFD->arguments.Add(refParameter); return callFD; } else if (function == L"Number" || function == L"Currency") { auto refLocale = Ptr(new WfReferenceExpression); refLocale->name.value = L"locale"; auto refParameter = Ptr(new WfReferenceExpression); refParameter->name.value = argumentName; auto refLoc2 = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor()); auto refFD = Ptr(new WfChildExpression); refFD->parent = refLoc2; refFD->name.value = L"Format" + function; auto callFD = Ptr(new WfCallExpression); callFD->function = refFD; callFD->arguments.Add(refLocale); callFD->arguments.Add(refParameter); return callFD; } else { auto refParameter = Ptr(new WfReferenceExpression); refParameter->name.value = argumentName; return refParameter; } } Ptr GuiInstanceLocalizedStringsBase::GenerateTextDescFunctionBody(Ptr textDesc) { auto appendExpr = [](Ptr resultExpr, Ptr strExpr) -> Ptr { if (resultExpr) { auto binaryExpr = Ptr(new WfBinaryExpression); binaryExpr->op = WfBinaryOperator::FlagAnd; binaryExpr->first = resultExpr; binaryExpr->second = strExpr; return binaryExpr; } else { return strExpr; } }; auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach:indexed for (vint i = 0; i < textDesc->parameters.Count(); i++) { auto varDesc = Ptr(new WfVariableDeclaration); varDesc->name.value = L"_" + itow(i); auto varStat = Ptr(new WfVariableStatement); varStat->variable = varDesc; block->statements.Add(varStat); auto type = textDesc->parameters[i].key; auto function = textDesc->parameters[i].value; auto index = textDesc->positions[i]; varDesc->expression = GenerateTextDescArgumentFormatting(type, function, index); } { Ptr resultExpr; // TODO: (enumerable) foreach:indexed for (vint i = 0; i < textDesc->texts.Count(); i++) { if (textDesc->texts[i] != L"") { auto strExpr = Ptr(new WfStringExpression); strExpr->value.value = textDesc->texts[i]; resultExpr = appendExpr(resultExpr, strExpr); } if (i < textDesc->parameters.Count()) { auto refExpr = Ptr(new WfReferenceExpression); refExpr->name.value = L"_" + itow(i); resultExpr = appendExpr(resultExpr, refExpr); } } if (!resultExpr) { resultExpr = Ptr(new WfStringExpression); } auto returnStat = Ptr(new WfReturnStatement); returnStat->expression = resultExpr; block->statements.Add(returnStat); } return block; } template Ptr GenerateFullNameAst(const WString& fullName) { Ptr refClass; { List fragments; SplitTypeName(fullName, fragments); for (auto fragment : fragments) { if (refClass) { auto refType = Ptr(new TChild); refType->parent = refClass; refType->name.value = fragment; refClass = refType; } else { auto refType = Ptr(new TTopQualified); refType->name.value = fragment; refClass = refType; } } } return refClass; } Ptr GuiInstanceLocalizedStringsBase::GenerateStringsConstructor(const WString& interfaceFullName, TextDescMap& textDescs, Ptr lss) { auto lsExpr = Ptr(new WfNewInterfaceExpression); { auto refPointer = Ptr(new WfSharedPointerType); refPointer->element = GenerateFullNameAst(interfaceFullName); lsExpr->type = refPointer; } for (auto lssi : lss->items.Values()) { auto textDesc = textDescs[{lss, lssi->name}]; auto func = GenerateTextDescFunctionHeader(textDesc, lssi->name, WfFunctionKind::Override); func->statement = GenerateTextDescFunctionBody(textDesc); lsExpr->declarations.Add(func); } return lsExpr; } Ptr GuiInstanceLocalizedStringsBase::GenerateBuildStringsFunction(const WString& interfaceFullName, TextDescMap& textDescs, Ptr lss) { auto func = Ptr(new WfFunctionDeclaration); func->functionKind = WfFunctionKind::Static; func->anonymity = WfFunctionAnonymity::Named; func->name.value = GenerateStringsCppName(lss); { auto refPointer = Ptr(new WfSharedPointerType); refPointer->element = GenerateFullNameAst(interfaceFullName); func->returnType = refPointer; } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"locale"; argument->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); func->arguments.Add(argument); } auto block = Ptr(new WfBlockStatement); func->statement = block; auto returnStat = Ptr(new WfReturnStatement); returnStat->expression = GenerateStringsConstructor(interfaceFullName, textDescs, lss); block->statements.Add(returnStat); return func; } Ptr GuiInstanceLocalizedStringsBase::GenerateStaticInit(const WString& stringsClassWithoutNs, const WString& installClassFullName, collections::List>& strings) { auto block = Ptr(new WfBlockStatement); for (auto ls : strings) { auto cppName = GenerateStringsCppName(ls); for (auto locale : ls->locales) { Ptr exprStrings, exprInstall; { auto refClass = Ptr(new WfReferenceExpression); refClass->name.value = stringsClassWithoutNs; auto refStrings = Ptr(new WfChildExpression); refStrings->parent = refClass; refStrings->name.value = GenerateStringsCppName(ls); auto strExpr = Ptr(new WfStringExpression); strExpr->value.value = locale; auto castExpr = Ptr(new WfExpectedTypeCastExpression); castExpr->strategy = WfTypeCastingStrategy::Strong; castExpr->expression = strExpr; auto callStringsExpr = Ptr(new WfCallExpression); callStringsExpr->function = refStrings; callStringsExpr->arguments.Add(castExpr); exprStrings = callStringsExpr; } { auto strExpr = Ptr(new WfStringExpression); strExpr->value.value = locale; auto castExpr = Ptr(new WfExpectedTypeCastExpression); castExpr->strategy = WfTypeCastingStrategy::Strong; castExpr->expression = strExpr; auto refInstall = Ptr(new WfChildExpression); refInstall->parent = GenerateFullNameAst(installClassFullName); refInstall->name.value = L"Install"; auto callInstallExpr = Ptr(new WfCallExpression); callInstallExpr->function = refInstall; callInstallExpr->arguments.Add(castExpr); callInstallExpr->arguments.Add(exprStrings); exprInstall = callInstallExpr; } auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = exprInstall; block->statements.Add(exprStat); } } return block; } /*********************************************************************** GuiInstanceLocalizedStrings ***********************************************************************/ Ptr GuiInstanceLocalizedStrings::LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors) { auto ls = Ptr(new GuiInstanceLocalizedStrings); if (xml->rootElement->name.value!=L"LocalizedStrings") { errors.Add(GuiResourceError({ { resource },xml->rootElement->codeRange.start }, L"Precompile: The root element of localized strings should be \"LocalizedStrings\".")); return nullptr; } ls->tagPosition = { {resource},xml->rootElement->name.codeRange.start }; auto attClassName = XmlGetAttribute(xml->rootElement, L"ref.Class"); if (!attClassName) { errors.Add(GuiResourceError({ { resource },xml->rootElement->codeRange.start }, L"Precompile: Missing attribute \"ref.Class\" in \"LocalizedStrings\".")); } else { ls->className = attClassName->value.value; } auto attDefaultLocale = XmlGetAttribute(xml->rootElement, L"DefaultLocale"); if (!attDefaultLocale) { errors.Add(GuiResourceError({ { resource },xml->rootElement->codeRange.start }, L"Precompile: Missing attribute \"DefaultLocale\" in \"LocalizedStrings\".")); } else { ls->defaultLocale = attDefaultLocale->value.value; } if (!attClassName || !attDefaultLocale) { return nullptr; } SortedList existingLocales; for (auto xmlStrings : XmlGetElements(xml->rootElement)) { if (auto lss = LoadStringsFromXml(resource, xmlStrings, existingLocales, errors)) { ls->strings.Add(lss); if (lss->locales.Contains(ls->defaultLocale)) { ls->defaultStrings = lss; } } } if (!ls->defaultStrings) { errors.Add(GuiResourceError({ { resource },xml->rootElement->codeRange.start }, L"Precompile: Strings for the default locale \"" + ls->defaultLocale + L"\" is not defined.")); } return ls; } Ptr GuiInstanceLocalizedStrings::SaveToXml() { auto xml = Ptr(new XmlElement); xml->name.value = L"LocalizedStrings"; { auto att = Ptr(new XmlAttribute); att->name.value = L"ref.Class"; att->value.value = className; xml->attributes.Add(att); } { auto att = Ptr(new XmlAttribute); att->name.value = L"DefaultLocale"; att->value.value = defaultLocale; xml->attributes.Add(att); } for (auto lss : strings) { xml->subNodes.Add(SaveStringsToXml(lss)); } return xml; } Ptr GuiInstanceLocalizedStrings::GenerateInstallFunction(const WString& cacheName) { auto func = Ptr(new WfFunctionDeclaration); func->functionKind = WfFunctionKind::Static; func->anonymity = WfFunctionAnonymity::Named; func->name.value = L"Install"; { auto refVoid = Ptr(new WfPredefinedType); refVoid->name = WfPredefinedTypeName::Void; func->returnType = refVoid; } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"locale"; argument->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); func->arguments.Add(argument); } { auto refType = Ptr(new WfReferenceType); refType->name.value = GetInterfaceTypeName(className, false); auto refPointer = Ptr(new WfSharedPointerType); refPointer->element = refType; auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"impl"; argument->type = refPointer; func->arguments.Add(argument); } auto block = Ptr(new WfBlockStatement); func->statement = block; { auto ifStat = Ptr(new WfIfStatement); { auto refCache = Ptr(new WfReferenceExpression); refCache->name.value = cacheName; auto refKeys = Ptr(new WfMemberExpression); refKeys->parent = refCache; refKeys->name.value = L"Keys"; auto refContains = Ptr(new WfMemberExpression); refContains->parent = refKeys; refContains->name.value = L"Contains"; auto refLocale = Ptr(new WfReferenceExpression); refLocale->name.value = L"locale"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refContains; callExpr->arguments.Add(refLocale); ifStat->expression = callExpr; } auto trueBlock = Ptr(new WfBlockStatement); ifStat->trueBranch = trueBlock; auto raiseStat = Ptr(new WfRaiseExceptionStatement); trueBlock->statements.Add(raiseStat); { auto errorHead = Ptr(new WfStringExpression); errorHead->value.value = L"Localized strings \"" + className + L"\" has already registered for locale \""; auto refLocale = Ptr(new WfReferenceExpression); refLocale->name.value = L"locale"; auto errorTail = Ptr(new WfStringExpression); errorTail->value.value = L"\"."; auto concat0 = Ptr(new WfBinaryExpression); concat0->op = WfBinaryOperator::FlagAnd; concat0->first = errorHead; concat0->second = refLocale; auto concat1 = Ptr(new WfBinaryExpression); concat1->op = WfBinaryOperator::FlagAnd; concat1->first = concat0; concat1->second = errorTail; raiseStat->expression = concat1; } block->statements.Add(ifStat); } { auto callExpr = Ptr(new WfCallExpression); { auto refCache = Ptr(new WfReferenceExpression); refCache->name.value = cacheName; auto refSet = Ptr(new WfMemberExpression); refSet->parent = refCache; refSet->name.value = L"Set"; callExpr->function = refSet; } { auto refLocale = Ptr(new WfReferenceExpression); refLocale->name.value = L"locale"; callExpr->arguments.Add(refLocale); } { auto refImpl = Ptr(new WfReferenceExpression); refImpl->name.value = L"impl"; callExpr->arguments.Add(refImpl); } auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = callExpr; block->statements.Add(exprStat); } return func; } Ptr GuiInstanceLocalizedStrings::GenerateGetFunction(const WString& cacheName) { auto func = Ptr(new WfFunctionDeclaration); func->functionKind = WfFunctionKind::Static; func->anonymity = WfFunctionAnonymity::Named; func->name.value = L"Get"; { auto refType = Ptr(new WfReferenceType); refType->name.value = GetInterfaceTypeName(className, false); auto refPointer = Ptr(new WfSharedPointerType); refPointer->element = refType; func->returnType = refPointer; } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"locale"; argument->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); func->arguments.Add(argument); } auto block = Ptr(new WfBlockStatement); func->statement = block; { auto ifStat = Ptr(new WfIfStatement); { auto refCache = Ptr(new WfReferenceExpression); refCache->name.value = cacheName; auto refKeys = Ptr(new WfMemberExpression); refKeys->parent = refCache; refKeys->name.value = L"Keys"; auto refContains = Ptr(new WfMemberExpression); refContains->parent = refKeys; refContains->name.value = L"Contains"; auto refLocale = Ptr(new WfReferenceExpression); refLocale->name.value = L"locale"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refContains; callExpr->arguments.Add(refLocale); ifStat->expression = callExpr; } auto trueBlock = Ptr(new WfBlockStatement); ifStat->trueBranch = trueBlock; { auto refCache = Ptr(new WfReferenceExpression); refCache->name.value = cacheName; auto refLocale = Ptr(new WfReferenceExpression); refLocale->name.value = L"locale"; auto refGet = Ptr(new WfBinaryExpression); refGet->op = WfBinaryOperator::Index; refGet->first = refCache; refGet->second = refLocale; auto returnStat = Ptr(new WfReturnStatement); returnStat->expression = refGet; trueBlock->statements.Add(returnStat); } block->statements.Add(ifStat); } { auto refCache = Ptr(new WfReferenceExpression); refCache->name.value = cacheName; auto strExpr = Ptr(new WfStringExpression); strExpr->value.value = defaultLocale; auto castExpr = Ptr(new WfExpectedTypeCastExpression); castExpr->strategy = WfTypeCastingStrategy::Strong; castExpr->expression = strExpr; auto refGet = Ptr(new WfBinaryExpression); refGet->op = WfBinaryOperator::Index; refGet->first = refCache; refGet->second = castExpr; auto returnStat = Ptr(new WfReturnStatement); returnStat->expression = refGet; block->statements.Add(returnStat); } return func; } Ptr GuiInstanceLocalizedStrings::Compile(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, GuiResourceError::List& errors) { vint errorCount = errors.Count(); TextDescMap textDescs; { List> nonDefaultStrings; CopyFrom( nonDefaultStrings, From(strings).Where([this](auto&& lss) { return lss != defaultStrings; }) ); FillStringsToTextDescMap(defaultStrings, textDescs, errors); ValidateAgainstDefaultStrings(defaultStrings, nonDefaultStrings, textDescs, errors); } if (errors.Count() != errorCount) { return nullptr; } WString cacheName; auto module = Ptr(new WfModule); module->moduleType = WfModuleType::Module; module->name.value = moduleName; // interface { auto lsInterface = Workflow_InstallClass(GetInterfaceTypeName(className, true), module); lsInterface->kind = WfClassKind::Interface; lsInterface->constructorType = WfConstructorType::SharedPtr; for (auto functionName : defaultStrings->items.Keys()) { auto func = GenerateTextDescFunctionHeader(textDescs[{defaultStrings, functionName}], functionName, WfFunctionKind::Normal); lsInterface->declarations.Add(func); } } // cache { auto refType = Ptr(new WfReferenceType); refType->name.value = GetInterfaceTypeName(className, false); auto ptrType = Ptr(new WfSharedPointerType); ptrType->element = refType; auto mapType = Ptr(new WfMapType); mapType->writability = WfMapWritability::Writable; mapType->key = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); mapType->value = ptrType; auto lsCache = Ptr(new WfVariableDeclaration); lsCache->type = mapType; lsCache->expression = Ptr(new WfConstructorExpression); cacheName = L"" + Workflow_InstallWithClass(className, module, lsCache); lsCache->name.value = cacheName; } // class { auto lsClass = Workflow_InstallClass(className, module); for (auto ls : strings) { lsClass->declarations.Add(GenerateBuildStringsFunction(GetInterfaceTypeName(className, true), textDescs, ls)); } lsClass->declarations.Add(GenerateInstallFunction(cacheName)); lsClass->declarations.Add(GenerateGetFunction(cacheName)); } // init { auto lsInit = Ptr(new WfStaticInitDeclaration); auto classNameWithoutNs = Workflow_InstallWithClass(className, module, lsInit); lsInit->statement = GenerateStaticInit(classNameWithoutNs, className, strings); } glr::ParsingTextPos pos(tagPosition.row, tagPosition.column); SetCodeRange(module, { pos,pos }); return module; } /*********************************************************************** GuiInstanceLocalizedStringsInjection ***********************************************************************/ Ptr GuiInstanceLocalizedStringsInjection::LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors) { auto ls = Ptr(new GuiInstanceLocalizedStringsInjection); if (xml->rootElement->name.value!=L"LocalizedStringsInjection") { errors.Add(GuiResourceError({ { resource },xml->rootElement->codeRange.start }, L"Precompile: The root element of localized strings should be \"LocalizedStringsInjection\".")); return nullptr; } ls->tagPosition = { {resource},xml->rootElement->name.codeRange.start }; auto attClassName = XmlGetAttribute(xml->rootElement, L"ref.Class"); if (!attClassName) { errors.Add(GuiResourceError({ { resource },xml->rootElement->codeRange.start }, L"Precompile: Missing attribute \"ref.Class\" in \"LocalizedStringsInjection\".")); } else { ls->className = attClassName->value.value; } auto attInjectIntoClassName = XmlGetAttribute(xml->rootElement, L"ref.InjectInto"); if (!attInjectIntoClassName) { errors.Add(GuiResourceError({ { resource },xml->rootElement->codeRange.start }, L"Precompile: Missing attribute \"ref.InjectInto\" in \"LocalizedStringsInjection\".")); } else { ls->injectIntoClassName = attInjectIntoClassName->value.value; } if (!attClassName || !attInjectIntoClassName) { return nullptr; } SortedList existingLocales; for (auto xmlStrings : XmlGetElements(xml->rootElement)) { if (auto lss = LoadStringsFromXml(resource, xmlStrings, existingLocales, errors)) { ls->strings.Add(lss); } } return ls; } Ptr GuiInstanceLocalizedStringsInjection::SaveToXml() { auto xml = Ptr(new XmlElement); xml->name.value = L"LocalizedStringsInjection"; { auto att = Ptr(new XmlAttribute); att->name.value = L"ref.Class"; att->value.value = className; xml->attributes.Add(att); } { auto att = Ptr(new XmlAttribute); att->name.value = L"ref.InjectInto"; att->value.value = injectIntoClassName; xml->attributes.Add(att); } for (auto lss : strings) { xml->subNodes.Add(SaveStringsToXml(lss)); } return xml; } void GuiInstanceLocalizedStringsInjection::DecompileDefaultStrings(description::ITypeDescriptor* td, Ptr defaultStrings, TextDescMap& textDescs, GuiResourceError::List& errors) { auto tdString = description::GetTypeDescriptor(); auto tdDateTime = description::GetTypeDescriptor(); for (vint i = 0; i < td->GetMethodGroupCount(); i++) { auto tdMethodGroup = td->GetMethodGroup(i); if (tdMethodGroup->GetMethodCount() == 1) { vint errorCount = errors.Count(); auto tdMethod = tdMethodGroup->GetMethod(0); auto returnType = tdMethod->GetReturn(); if (returnType->GetDecorator() != ITypeInfo::TypeDescriptor || returnType->GetTypeDescriptor() != tdString) { errors.Add(GuiResourceError(tagPosition, L"Precompile: function \"" + tdMethod->GetName() + L"\" in interface \"" + td->GetTypeName() + L"\" does not return string.")); } for (vint j = 0; j < tdMethod->GetParameterCount(); j++) { auto tdParameter = tdMethod->GetParameter(j); if (tdParameter->GetType()->GetDecorator() != ITypeInfo::TypeDescriptor || ( tdParameter->GetType()->GetTypeDescriptor() != tdString && tdParameter->GetType()->GetTypeDescriptor() != tdDateTime)) { errors.Add(GuiResourceError(tagPosition, L"Precompile: argument \"" + tdParameter->GetName() + L"\" in function \"" + tdMethod->GetName() + L"\" in interface \"" + td->GetTypeName() + L"\" is not string or DateTime.")); } } if (errors.Count() == errorCount) { defaultStrings->items.Add( tdMethod->GetName(), Ptr(new StringItem{ .name = tdMethod->GetName() }) ); auto textDesc = Ptr(new TextDesc); textDescs.Add({ defaultStrings,tdMethod->GetName() }, textDesc); CopyFrom( textDesc->parameters, Range(0, tdMethod->GetParameterCount()) .Select([tdMethod](vint j) -> ParameterPair { return { CopyTypeInfo(tdMethod->GetParameter(j)->GetType()),WString::Empty }; }) ); CopyFrom( textDesc->positions, Range(0, tdMethod->GetParameterCount()) ); } } else { errors.Add(GuiResourceError(tagPosition, L"Precompile: interface \"" + td->GetTypeName() + L"\" has more than one function named \"" + tdMethodGroup->GetName() + L"\".")); } } } Ptr GuiInstanceLocalizedStringsInjection::Compile(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, GuiResourceError::List& errors) { auto tdInjectInto = description::GetTypeDescriptor(injectIntoClassName); if (!tdInjectInto) { errors.Add(GuiResourceError(tagPosition, L"Precompile: attribute \"ref.InjectInto\" specifies an unexisting type \"" + injectIntoClassName + L"\".")); return nullptr; } IMethodGroupInfo* tdGetMethodGroup = nullptr; IMethodInfo* tdGetMethod = nullptr; IParameterInfo* tdGetMethodParameter = nullptr; ITypeDescriptor* tdStringsInterface = nullptr; tdGetMethodGroup = tdInjectInto->GetMethodGroupByName(L"Get", false); if (!tdGetMethodGroup) goto INCORRECT_STRINGS_TYPE; if (tdGetMethodGroup->GetMethodCount() != 1) goto INCORRECT_STRINGS_TYPE; tdGetMethod = tdGetMethodGroup->GetMethod(0); if (!tdGetMethod->IsStatic()) goto INCORRECT_STRINGS_TYPE; if (tdGetMethod->GetParameterCount() != 1) goto INCORRECT_STRINGS_TYPE; if (tdGetMethod->GetReturn()->GetDecorator() != ITypeInfo::SharedPtr) goto INCORRECT_STRINGS_TYPE; tdGetMethodParameter = tdGetMethod->GetParameter(0); if (tdGetMethodParameter->GetType()->GetDecorator() != ITypeInfo::TypeDescriptor) goto INCORRECT_STRINGS_TYPE; if (tdGetMethodParameter->GetType()->GetTypeDescriptor() != description::GetTypeDescriptor()) goto INCORRECT_STRINGS_TYPE; tdStringsInterface = tdGetMethod->GetReturn()->GetTypeDescriptor(); if (tdStringsInterface->GetTypeName() != GetInterfaceTypeName(injectIntoClassName, true)) goto INCORRECT_STRINGS_TYPE; { vint errorCount = errors.Count(); auto defaultStrings = Ptr(new Strings); TextDescMap textDescs; DecompileDefaultStrings(tdStringsInterface, defaultStrings, textDescs, errors); if (errors.Count() != errorCount) { return nullptr; } ValidateAgainstDefaultStrings(defaultStrings, strings, textDescs, errors); if (errors.Count() != errorCount) { return nullptr; } auto module = Ptr(new WfModule); module->moduleType = WfModuleType::Module; module->name.value = moduleName; // class { auto lsClass = Workflow_InstallClass(className, module); for (auto ls : strings) { lsClass->declarations.Add(GenerateBuildStringsFunction(GetInterfaceTypeName(injectIntoClassName, true), textDescs, ls)); } } // init { auto lsInit = Ptr(new WfStaticInitDeclaration); auto classNameWithoutNs = Workflow_InstallWithClass(className, module, lsInit); lsInit->statement = GenerateStaticInit(classNameWithoutNs, injectIntoClassName, strings); } glr::ParsingTextPos pos(tagPosition.row, tagPosition.column); SetCodeRange(module, { pos,pos }); return module; } INCORRECT_STRINGS_TYPE: errors.Add(GuiResourceError(tagPosition, L"Precompile: attribute \"ref.InjectInto\" specifies a type \"" + injectIntoClassName + L"\" that is not generated by .")); return nullptr; } } } /*********************************************************************** .\GUIINSTANCEREPRESENTATION.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace glr::xml; using namespace templates; using namespace stream; /*********************************************************************** GuiValueRepr ***********************************************************************/ void GuiValueRepr::CloneBody(Ptr repr) { repr->fromStyle = fromStyle; repr->tagPosition = tagPosition; } /*********************************************************************** GuiTextRepr ***********************************************************************/ Ptr GuiTextRepr::Clone() { auto repr = Ptr(new GuiTextRepr); GuiValueRepr::CloneBody(repr); repr->text = text; return repr; } void GuiTextRepr::FillXml(Ptr xml) { if (!fromStyle) { auto xmlText = Ptr(new XmlText); xmlText->content.value = text; xml->subNodes.Add(xmlText); } } /*********************************************************************** GuiAttSetterRepr ***********************************************************************/ void GuiAttSetterRepr::CloneBody(Ptr repr) { GuiValueRepr::CloneBody(repr); // TODO: (enumerable) foreach on dictionary for (auto [name, index] : indexed(setters.Keys())) { auto src = setters.Values()[index]; auto dst = Ptr(new SetterValue); dst->binding = src->binding; dst->attPosition = src->attPosition; for (auto value : src->values) { dst->values.Add(value->Clone()); } repr->setters.Add(name, dst); } // TODO: (enumerable) foreach on dictionary for (auto [name, index] : indexed(eventHandlers.Keys())) { auto src = eventHandlers.Values()[index]; auto dst = Ptr(new EventValue); dst->binding = src->binding; dst->value = src->value; dst->fromStyle = src->fromStyle; dst->attPosition = src->attPosition; dst->valuePosition = src->valuePosition; repr->eventHandlers.Add(name, dst); } // TODO: (enumerable) foreach on dictionary for (auto [name, index] : indexed(environmentVariables.Keys())) { auto src = environmentVariables.Values()[index]; auto dst = Ptr(new EnvVarValue); dst->value = src->value; dst->fromStyle = src->fromStyle; dst->attPosition = src->attPosition; dst->valuePosition = src->valuePosition; repr->environmentVariables.Add(name, dst); } repr->instanceName = instanceName; } Ptr GuiAttSetterRepr::Clone() { auto repr = Ptr(new GuiAttSetterRepr); GuiAttSetterRepr::CloneBody(repr); repr->fromStyle = fromStyle; return repr; } void GuiAttSetterRepr::FillXml(Ptr xml) { if (!fromStyle) { if (instanceName != GlobalStringKey::Empty) { auto attName = Ptr(new XmlAttribute); attName->name.value = L"ref.Name"; attName->value.value = instanceName.ToString(); xml->attributes.Add(attName); } // TODO: (enumerable) foreach on dictionary for (vint i = 0; i < setters.Count(); i++) { auto key = setters.Keys()[i]; auto value = setters.Values()[i]; if (key == GlobalStringKey::Empty) { for (auto repr : value->values) { repr->FillXml(xml); } } else if (From(value->values).Any([](Ptr value) {return !value->fromStyle; })) { bool containsElement = From(value->values) .Any([](Ptr value) { return !value->fromStyle && !value.Cast(); }); if (containsElement) { auto xmlProp = Ptr(new XmlElement); xmlProp->name.value = L"att." + key.ToString(); if (value->binding != GlobalStringKey::Empty) { xmlProp->name.value += L"-" + value->binding.ToString(); } for (auto repr : value->values) { if (!repr.Cast()) { repr->FillXml(xmlProp); } } xml->subNodes.Add(xmlProp); } else { for (auto repr : value->values) { if (auto textRepr = repr.Cast()) { if (!textRepr->fromStyle) { auto att = Ptr(new XmlAttribute); att->name.value = key.ToString(); if (value->binding != GlobalStringKey::Empty) { att->name.value += L"-" + value->binding.ToString(); } att->value.value = textRepr->text; xml->attributes.Add(att); break; } } } } } } // TODO: (enumerable) foreach on dictionary for (vint i = 0; i < eventHandlers.Count(); i++) { auto key = eventHandlers.Keys()[i]; auto value = eventHandlers.Values()[i]; if (!value->fromStyle) { auto xmlEvent = Ptr(new XmlElement); xmlEvent->name.value = L"ev." + key.ToString(); if (value->binding != GlobalStringKey::Empty) { xmlEvent->name.value += L"-" + value->binding.ToString(); } xml->subNodes.Add(xmlEvent); auto xmlText = Ptr(new XmlCData); xmlText->content.value = value->value; xmlEvent->subNodes.Add(xmlText); } } // TODO: (enumerable) foreach on dictionary for (vint i = 0; i < environmentVariables.Count(); i++) { auto key = environmentVariables.Keys()[i]; auto value = environmentVariables.Values()[i]; if (!value->fromStyle) { auto xmlEnvVar = Ptr(new XmlElement); xmlEnvVar->name.value = L"env." + key.ToString(); xml->subNodes.Add(xmlEnvVar); auto xmlText = Ptr(new XmlText); xmlText->content.value = value->value; xmlEnvVar->subNodes.Add(xmlText); } } } } /*********************************************************************** GuiConstructorRepr ***********************************************************************/ Ptr GuiConstructorRepr::Clone() { auto repr = Ptr(new GuiConstructorRepr); GuiAttSetterRepr::CloneBody(repr); repr->fromStyle = fromStyle; repr->typeNamespace = typeNamespace; repr->typeName = typeName; repr->styleName = styleName; return repr; } void GuiConstructorRepr::FillXml(Ptr xml) { if (!fromStyle) { auto xmlCtor = Ptr(new XmlElement); if (typeNamespace == GlobalStringKey::Empty) { xmlCtor->name.value = typeName.ToString(); } else { xmlCtor->name.value = typeNamespace.ToString() + L":" + typeName.ToString(); } if (styleName) { auto attStyle = Ptr(new XmlAttribute); attStyle->name.value = L"ref.Style"; attStyle->value.value = styleName.Value(); xml->attributes.Add(attStyle); } GuiAttSetterRepr::FillXml(xmlCtor); xml->subNodes.Add(xmlCtor); } } /*********************************************************************** GuiInstanceContext ***********************************************************************/ void GuiInstanceContext::CollectDefaultAttributes(Ptr resource, GuiAttSetterRepr::ValueList& values, Ptr xml, GuiResourceError::List& errors) { if (auto parser = GetParserManager()->GetParser(L"INSTANCE-ELEMENT-NAME")) { // test if there is only one text value in the xml if (xml->subNodes.Count() == 1) { if (Ptr text = xml->subNodes[0].Cast()) { auto value = Ptr(new GuiTextRepr); value->text = text->content.value; value->tagPosition = { {resource},text->content.codeRange.start }; values.Add(value); } else if (Ptr text = xml->subNodes[0].Cast()) { auto value = Ptr(new GuiTextRepr); value->text = text->content.value; value->tagPosition = { {resource},text->content.codeRange.start }; value->tagPosition.column += 9; // values.Add(value); } } // collect default attributes for (auto element : XmlGetElements(xml)) { if(auto name = parser->Parse({ resource }, element->name.value, element->codeRange.start, errors)) { if (name->IsCtorName()) { // collect constructor values in the default attribute setter auto ctor = LoadCtor(resource, element, errors); if (ctor) { values.Add(ctor); } } else if (!name->IsPropertyElementName() && !name->IsEventElementName()) { errors.Add(GuiResourceError({ {resource},element->codeRange.start }, L"Unknown element name: \"" + element->name.value + L"\".")); } } } } } void GuiInstanceContext::CollectAttributes(Ptr<GuiResourceItem> resource, GuiAttSetterRepr::SetteValuerMap& setters, Ptr<glr::xml::XmlElement> xml, GuiResourceError::List& errors) { if (auto parser = GetParserManager()->GetParser<ElementName>(L"INSTANCE-ELEMENT-NAME")) { auto defaultValue = Ptr(new GuiAttSetterRepr::SetterValue); // collect default attributes CollectDefaultAttributes(resource, defaultValue->values, xml, errors); if (defaultValue->values.Count() > 0) { setters.Add(GlobalStringKey::Empty, defaultValue); } // collect values for (auto element : XmlGetElements(xml)) { if(auto name = parser->Parse({ resource }, element->name.value, element->name.codeRange.start, errors)) { if (name->IsPropertyElementName()) { // collect a value as a new attribute setter if (setters.Keys().Contains(GlobalStringKey::Get(name->name))) { errors.Add(GuiResourceError({ {resource},element->codeRange.start }, L"Duplicated property \"" + name->name + L"\".")); } else { auto sv = Ptr(new GuiAttSetterRepr::SetterValue); sv->binding = GlobalStringKey::Get(name->binding); sv->attPosition = { {resource},element->codeRange.start }; if (name->binding == L"set") { // if the binding is "set", it means that this element is a complete setter element auto setter = Ptr(new GuiAttSetterRepr); FillAttSetter(resource, setter, element, errors); sv->values.Add(setter); } else { // if the binding is not "set", then this is a single-value attribute or a colection attribute // fill all data into this attribute CollectDefaultAttributes(resource, sv->values, element, errors); } if (sv->values.Count() > 0) { setters.Add(GlobalStringKey::Get(name->name), sv); } } } } } } } void GuiInstanceContext::CollectEvents(Ptr<GuiResourceItem> resource, GuiAttSetterRepr::EventHandlerMap& eventHandlers, Ptr<glr::xml::XmlElement> xml, GuiResourceError::List& errors) { if (auto parser = GetParserManager()->GetParser<ElementName>(L"INSTANCE-ELEMENT-NAME")) { // collect values for (auto element : XmlGetElements(xml)) { if(auto name = parser->Parse({ resource }, element->name.value, element->name.codeRange.start, errors)) { if (name->IsEventElementName()) { // collect a value as an event setter if (eventHandlers.Keys().Contains(GlobalStringKey::Get(name->name))) { errors.Add(GuiResourceError({ {resource},element->codeRange.start }, L"Duplicated event \"" + name->name + L"\".")); } else { // test if there is only one text value in the xml if (element->subNodes.Count() == 1) { if (Ptr<XmlText> text = element->subNodes[0].Cast<XmlText>()) { auto value = Ptr(new GuiAttSetterRepr::EventValue); value->binding = GlobalStringKey::Get(name->binding); value->value = text->content.value; value->attPosition = { {resource},element->codeRange.start }; value->valuePosition = { {resource},text->content.codeRange.start }; eventHandlers.Add(GlobalStringKey::Get(name->name), value); if (text->content.codeRange.start.row != text->content.codeRange.end.row) { errors.Add(GuiResourceError({ {resource},element->codeRange.start }, L"Multiple lines script should be contained in a CDATA section.")); } goto EVENT_SUCCESS; } else if (Ptr<XmlCData> text = element->subNodes[0].Cast<XmlCData>()) { auto value = Ptr(new GuiAttSetterRepr::EventValue); value->binding = GlobalStringKey::Get(name->binding); value->value = text->content.value; value->attPosition = { {resource},element->codeRange.start }; value->valuePosition = { {resource},text->content.codeRange.start }; value->valuePosition.column += 9; // <![CDATA[ eventHandlers.Add(GlobalStringKey::Get(name->name), value); } goto EVENT_SUCCESS; } errors.Add(GuiResourceError({ {resource},element->codeRange.start }, L"Event script should be contained in a text or CDATA section.")); EVENT_SUCCESS:; } } } } } } void GuiInstanceContext::FillAttSetter(Ptr<GuiResourceItem> resource, Ptr<GuiAttSetterRepr> setter, Ptr<glr::xml::XmlElement> xml, GuiResourceError::List& errors) { if (auto parser = GetParserManager()->GetParser<ElementName>(L"INSTANCE-ELEMENT-NAME")) { setter->tagPosition = { {resource},xml->codeRange.start }; // collect attributes as setters for (auto att : xml->attributes) { if(auto name = parser->Parse({ resource }, att->name.value, att->name.codeRange.start, errors)) { if (name->IsReferenceAttributeName()) { // collect reference attributes if (name->name == L"Name") { setter->instanceName = GlobalStringKey::Get(att->value.value); } } else if (name->IsEnvironmentAttributeName()) { // collect environment variables if (setter->environmentVariables.Keys().Contains(GlobalStringKey::Get(name->name))) { errors.Add(GuiResourceError({ {resource},att->name.codeRange.start }, L"Duplicated environment variable \"" + name->name + L"\".")); } else { auto value = Ptr(new GuiAttSetterRepr::EnvVarValue); value->value = att->value.value; value->attPosition = { {resource},att->codeRange.start }; value->valuePosition = { {resource},att->value.codeRange.start }; value->valuePosition.column += 1; setter->environmentVariables.Add(GlobalStringKey::Get(name->name), value); } } else if (name->IsPropertyAttributeName()) { // collect attributes setters if (setter->setters.Keys().Contains(GlobalStringKey::Get(name->name))) { errors.Add(GuiResourceError({ {resource},att->name.codeRange.start }, L"Duplicated property \"" + name->name + L"\".")); } else { auto sv = Ptr(new GuiAttSetterRepr::SetterValue); sv->binding = GlobalStringKey::Get(name->binding); sv->attPosition = { {resource},att->codeRange.start }; setter->setters.Add(GlobalStringKey::Get(name->name), sv); auto value = Ptr(new GuiTextRepr); value->text = att->value.value; value->tagPosition = { {resource},att->value.codeRange.start }; value->tagPosition.column += 1; sv->values.Add(value); } } else if (name->IsEventAttributeName()) { // collect event setters if (setter->eventHandlers.Keys().Contains(GlobalStringKey::Get(name->name))) { errors.Add(GuiResourceError({ {resource},att->name.codeRange.start }, L"Duplicated event \"" + name->name + L"\".")); } else { auto value = Ptr(new GuiAttSetterRepr::EventValue); value->binding = GlobalStringKey::Get(name->binding); value->value = att->value.value; value->attPosition = { {resource},att->codeRange.start }; value->valuePosition = { {resource},att->value.codeRange.start }; value->valuePosition.column += 1; setter->eventHandlers.Add(GlobalStringKey::Get(name->name), value); } } else { errors.Add(GuiResourceError({ {resource},att->name.codeRange.start }, L"Unknown attribute name: \"" + att->name.value + L"\".")); } } } // collect attributes and events CollectAttributes(resource, setter->setters, xml, errors); CollectEvents(resource, setter->eventHandlers, xml, errors); } } Ptr<GuiConstructorRepr> GuiInstanceContext::LoadCtor(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlElement> xml, GuiResourceError::List& errors) { if (auto parser = GetParserManager()->GetParser<ElementName>(L"INSTANCE-ELEMENT-NAME")) { if(auto ctorName = parser->Parse({ resource }, xml->name.value, xml->name.codeRange.start, errors)) { if (ctorName->IsCtorName()) { auto ctor = Ptr(new GuiConstructorRepr); ctor->typeNamespace = GlobalStringKey::Get(ctorName->namespaceName); ctor->typeName = GlobalStringKey::Get(ctorName->name); // collect attributes as setters for (auto att : xml->attributes) { if(auto attName = parser->Parse({ resource }, att->name.value, att->name.codeRange.start, errors)) { if (attName->IsReferenceAttributeName()) { if (attName->name == L"Style") { ctor->styleName = att->value.value; } } } } FillAttSetter(resource, ctor, xml, errors); return ctor; } else { errors.Add(GuiResourceError({ {resource},xml->codeRange.start }, L"Wrong constructor name \"" + xml->name.value + L"\".")); } } } return 0; } Ptr<GuiInstanceContext> GuiInstanceContext::LoadFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlDocument> xml, GuiResourceError::List& errors) { auto context = Ptr(new GuiInstanceContext); context->tagPosition = { {resource},xml->rootElement->codeRange.start }; if (xml->rootElement->name.value == L"Instance") { if (auto codeBehindAttr = XmlGetAttribute(xml->rootElement, L"ref.CodeBehind")) { context->codeBehind = codeBehindAttr->value.value == L"true"; } // load type name if (auto classAttr = XmlGetAttribute(xml->rootElement, L"ref.Class")) { context->className = classAttr->value.value; context->classPosition = { {resource},classAttr->codeRange.start }; } // load style names if (auto styleAttr = XmlGetAttribute(xml->rootElement, L"ref.Styles")) { SplitBySemicolon(styleAttr->value.value, context->stylePaths); context->stylePosition = { {resource},styleAttr->codeRange.start }; } // load namespaces List<Ptr<XmlAttribute>> namespaceAttributes; CopyFrom(namespaceAttributes, xml->rootElement->attributes); if (!XmlGetAttribute(xml->rootElement, L"xmlns")) { auto att = Ptr(new XmlAttribute); att->name.value = L"xmlns"; att->value.value = L"presentation::controls::Gui*;" L"presentation::elements::Gui*Element;" L"presentation::compositions::Gui*Composition;" L"presentation::compositions::Gui*;" L"presentation::templates::Gui*;" L"system::*;" L"system::reflection::*;" L"presentation::*;" L"presentation::Gui*;" L"presentation::controls::*;" L"presentation::controls::list::*;" L"presentation::controls::tree::*;" L"presentation::elements::*;" L"presentation::elements::Gui*;" L"presentation::elements::text::*;" L"presentation::compositions::*;" L"presentation::templates::*;" L"presentation::theme::*"; namespaceAttributes.Add(att); } for (auto att : namespaceAttributes) { // check if the attribute defines a namespace WString attName = att->name.value; if (attName.Length() >= 5 && attName.Left(5) == L"xmlns") { GlobalStringKey ns; if (attName.Length() > 6) { if (attName.Left(6) == L"xmlns:") { ns = GlobalStringKey::Get(attName.Sub(6, attName.Length() - 6)); } else { continue; } } // create a data structure for the namespace Ptr<NamespaceInfo> info; vint index = context->namespaces.Keys().IndexOf(ns); if (index == -1) { info = Ptr(new NamespaceInfo); info->name = ns; info->attPosition = { {resource},att->codeRange.start }; context->namespaces.Add(ns, info); } else { info = context->namespaces.Values()[index]; } // extract all patterns in the namespace, split the value by ';' List<WString> patterns; SplitBySemicolon(att->value.value, patterns); for (auto pattern : patterns) { // add the pattern to the namespace auto ns = Ptr(new GuiInstanceNamespace); Pair<vint, vint> star = INVLOC.FindFirst(pattern, L"*", Locale::None); if (star.key == -1) { ns->prefix = pattern; } else { ns->prefix = pattern.Sub(0, star.key); ns->postfix = pattern.Sub(star.key + star.value, pattern.Length() - star.key - star.value); } info->namespaces.Add(ns); } } } // load instance for (auto element : XmlGetElements(xml->rootElement)) { if (element->name.value == L"ref.Parameter") { auto attName = XmlGetAttribute(element, L"Name"); auto attClass = XmlGetAttribute(element, L"Class"); if (attName && attClass) { auto parameter = Ptr(new GuiInstanceParameter); parameter->name = GlobalStringKey::Get(attName->value.value); parameter->className = GlobalStringKey::Get(attClass->value.value); parameter->tagPosition = { {resource},element->codeRange.start }; parameter->classPosition = { {resource},attClass->value.codeRange.start }; parameter->classPosition.column += 1; context->parameters.Add(parameter); } else { errors.Add(GuiResourceError({ {resource},element->codeRange.start }, L"ref.Parameter requires the following attributes existing at the same time: Name, Class.")); } } else if (element->name.value == L"ref.LocalizedStrings") { auto attName = XmlGetAttribute(element, L"Name"); auto attClass = XmlGetAttribute(element, L"Class"); auto attDefault = XmlGetAttribute(element, L"Default"); if (attName && attClass) { auto localized = Ptr(new GuiInstanceLocalized); localized->name = GlobalStringKey::Get(attName->value.value); localized->className = GlobalStringKey::Get(attClass->value.value); localized->tagPosition = { { resource },element->codeRange.start }; localized->classPosition = { { resource },attClass->value.codeRange.start }; localized->classPosition.column += 1; if (attDefault) { localized->defaultStrings = attDefault->value.value == L"true"; } context->localizeds.Add(localized); } else { errors.Add(GuiResourceError({ { resource },element->codeRange.start }, L"ref.LocalizedStrings requires the following attributes existing at the same time: Name, Class.")); } } #define COLLECT_SCRIPT(NAME, SCRIPT, POSITION)\ (element->name.value == L"ref." #NAME)\ {\ if (element->subNodes.Count() == 1)\ {\ if (auto cdata = element->subNodes[0].Cast<XmlCData>())\ {\ context->SCRIPT = cdata->content.value;\ context->POSITION = { {resource},cdata->codeRange.start };\ context->POSITION.column += 9; /* <![CDATA[ */\ goto NAME##_SCRIPT_SUCCESS;\ }\ }\ errors.Add(GuiResourceError({ {resource},element->codeRange.start }, L"Script should be contained in a CDATA section."));\ NAME##_SCRIPT_SUCCESS:;\ }\ else if COLLECT_SCRIPT(Members, memberScript, memberPosition) else if COLLECT_SCRIPT(Ctor, ctorScript, ctorPosition) else if COLLECT_SCRIPT(Dtor, dtorScript, dtorPosition) #undef COLLECT_SCRIPT else if (!context->instance) { context->instance = LoadCtor(resource, element, errors); } } } else { errors.Add(GuiResourceError({ {resource},xml->rootElement->codeRange.start }, L"The root element of instance should be \"Instance\".")); } return context->instance ? context : nullptr; } Ptr<glr::xml::XmlDocument> GuiInstanceContext::SaveToXml() { auto xmlInstance = Ptr(new XmlElement); xmlInstance->name.value = L"Instance"; { auto attCodeBehind = Ptr(new XmlAttribute); attCodeBehind->name.value = L"ref.CodeBehind"; attCodeBehind->value.value = codeBehind ? L"true" : L"false"; xmlInstance->attributes.Add(attCodeBehind); } auto attClass = Ptr(new XmlAttribute); attClass->name.value = L"ref.Class"; attClass->value.value = className; xmlInstance->attributes.Add(attClass); // TODO: (enumerable) foreach on dictionary for (vint i = 0; i < namespaces.Count(); i++) { auto key = namespaces.Keys()[i]; auto value = namespaces.Values()[i]; auto xmlns = Ptr(new XmlAttribute); xmlns->name.value = L"xmlns"; if (key != GlobalStringKey::Empty) { xmlns->name.value += L":" + key.ToString(); } xmlInstance->attributes.Add(xmlns); // TODO: (enumerable) Linq:Aggregate for (vint j = 0; j < value->namespaces.Count(); j++) { auto ns = value->namespaces[j]; if (j != 0) { xmlns->value.value += L";"; } xmlns->value.value += ns->prefix + L"*" + ns->postfix; } } for (auto parameter : parameters) { auto xmlParameter = Ptr(new XmlElement); xmlParameter->name.value = L"ref.Parameter"; xmlInstance->subNodes.Add(xmlParameter); auto attName = Ptr(new XmlAttribute); attName->name.value = L"Name"; attName->value.value = parameter->name.ToString(); xmlParameter->attributes.Add(attName); auto attClass = Ptr(new XmlAttribute); attClass->name.value = L"Class"; attClass->value.value = parameter->className.ToString(); xmlParameter->attributes.Add(attClass); } for (auto localized : localizeds) { auto xmlParameter = Ptr(new XmlElement); xmlParameter->name.value = L"ref.LocalizedStrings"; xmlInstance->subNodes.Add(xmlParameter); auto attName = Ptr(new XmlAttribute); attName->name.value = L"Name"; attName->value.value = localized->name.ToString(); xmlParameter->attributes.Add(attName); auto attClass = Ptr(new XmlAttribute); attClass->name.value = L"Class"; attClass->value.value = localized->className.ToString(); xmlParameter->attributes.Add(attClass); auto attDefault = Ptr(new XmlAttribute); attDefault->name.value = L"Default"; attDefault->value.value = localized->defaultStrings ? L"true" : L"false"; xmlParameter->attributes.Add(attDefault); } #define SERIALIZE_SCRIPT(NAME, SCRIPT)\ if (SCRIPT != L"")\ {\ auto xmlScript = Ptr(new XmlElement);\ xmlScript->name.value = L"ref." #NAME;\ xmlInstance->subNodes.Add(xmlScript);\ auto text = Ptr(new XmlCData);\ text->content.value = SCRIPT;\ xmlScript->subNodes.Add(text);\ }\ SERIALIZE_SCRIPT(Members, memberScript) SERIALIZE_SCRIPT(Ctpr, ctorScript) SERIALIZE_SCRIPT(Dtor, dtorScript) #undef SERIALIZE_SCRIPT if (stylePaths.Count() > 0) { auto attStyles = Ptr(new XmlAttribute); attStyles->name.value = L"ref.Styles"; xmlInstance->attributes.Add(attStyles); // TODO: (enumerable) Linq:Aggregate for (vint j = 0; j < stylePaths.Count(); j++) { if (j != 0) { attStyles->value.value += L";"; } attStyles->value.value += stylePaths[j]; } } instance->FillXml(xmlInstance); auto doc = Ptr(new XmlDocument); doc->rootElement = xmlInstance; return doc; } bool GuiInstanceContext::ApplyStyles(Ptr<GuiResourceItem> resource, Ptr<GuiResourcePathResolver> resolver, GuiResourceError::List& errors) { if (!appliedStyles) { appliedStyles = true; List<Ptr<GuiInstanceStyle>> styles; for (auto uri : stylePaths) { WString protocol, path; if (IsResourceUrl(uri, protocol, path)) { if (auto styleContext = resolver->ResolveResource(protocol, path).Cast<GuiInstanceStyleContext>()) { CopyFrom(styles, styleContext->styles, true); } else { errors.Add(GuiResourceError({ resource }, stylePosition, L"Failed to find the style referred in attribute \"ref.Styles\": \"" + uri + L"\".")); } } else { errors.Add(GuiResourceError({ resource }, stylePosition, L"Invalid path in attribute \"ref.Styles\": \"" + uri + L"\".")); } } for (auto style : styles) { List<Ptr<GuiConstructorRepr>> output; ExecuteQuery(style->query, Ptr(this), output); for (auto ctor : output) { ApplyStyle(style, ctor); } } return true; } else { return false; } } /*********************************************************************** GuiInstanceStyle ***********************************************************************/ namespace visitors { class SetStyleMarkVisitor : public Object, public GuiValueRepr::IVisitor { public: void Visit(GuiTextRepr* repr)override { repr->fromStyle = true; } void Visit(GuiAttSetterRepr* repr)override { repr->fromStyle = true; for (auto value : repr->setters.Values()) { for (auto subValue : value->values) { subValue->Accept(this); } } for (auto value : repr->eventHandlers.Values()) { value->fromStyle = true; } for (auto value : repr->environmentVariables.Values()) { value->fromStyle = true; } } void Visit(GuiConstructorRepr* repr)override { Visit((GuiAttSetterRepr*)repr); } }; } using namespace visitors; Ptr<GuiInstanceStyle> GuiInstanceStyle::LoadFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlElement> xml, GuiResourceError::List& errors) { auto style = Ptr(new GuiInstanceStyle); if (auto pathAttr = XmlGetAttribute(xml, L"ref.Path")) { auto position = pathAttr->value.codeRange.start; position.column += 1; auto parser = GetParserManager()->GetParser<instancequery::GuiIqQuery>(L"INSTANCE-QUERY"); auto query = parser->Parse({ resource }, pathAttr->value.value, position, errors); if (!query) return nullptr; style->query = query; } else { errors.Add(GuiResourceError({ {resource},xml->codeRange.start }, L"Missing attribute \"ref.Path\" in <Style>.")); } style->setter = Ptr(new GuiAttSetterRepr); GuiInstanceContext::FillAttSetter(resource, style->setter, xml, errors); SetStyleMarkVisitor visitor; style->setter->Accept(&visitor); return style; } Ptr<glr::xml::XmlElement> GuiInstanceStyle::SaveToXml() { auto xmlStyle = Ptr(new XmlElement); xmlStyle->name.value = L"Style"; auto attPath = Ptr(new XmlAttribute); attPath->name.value = L"ref.Path"; attPath->value.value = GenerateToStream([&](StreamWriter& writer) { GuiIqPrint(query, writer); }); xmlStyle->attributes.Add(attPath); setter->FillXml(xmlStyle); return xmlStyle; } /*********************************************************************** GuiInstanceStyleContext ***********************************************************************/ Ptr<GuiInstanceStyleContext> GuiInstanceStyleContext::LoadFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlDocument> xml, GuiResourceError::List& errors) { auto context = Ptr(new GuiInstanceStyleContext); if (xml->rootElement->name.value == L"Styles") { for (auto styleElement : XmlGetElements(xml->rootElement)) { if (styleElement->name.value == L"Style") { if (auto style = GuiInstanceStyle::LoadFromXml(resource, styleElement, errors)) { context->styles.Add(style); } } else { errors.Add(GuiResourceError({ {resource},styleElement->codeRange.start }, L"Unknown element in <Styles>: \"" + styleElement->name.value + L"\".")); } } } else { errors.Add(GuiResourceError({ {resource},xml->rootElement->codeRange.start }, L"The root element of instance styles should be \"Styles\".")); } return context; } Ptr<glr::xml::XmlDocument> GuiInstanceStyleContext::SaveToXml() { auto xmlStyles = Ptr(new XmlElement); xmlStyles->name.value = L"Styles"; for (auto style : styles) { xmlStyles->subNodes.Add(style->SaveToXml()); } auto doc = Ptr(new XmlDocument); doc->rootElement = xmlStyles; return doc; } } } /*********************************************************************** .\GUIINSTANCESHAREDSCRIPT.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace glr::xml; /*********************************************************************** GuiInstanceSharedScript ***********************************************************************/ Ptr<GuiInstanceSharedScript> GuiInstanceSharedScript::LoadFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlDocument> xml, GuiResourceError::List& errors) { if (xml->rootElement->subNodes.Count() == 1) { if (auto cdata = xml->rootElement->subNodes[0].Cast<XmlCData>()) { auto script = Ptr(new GuiInstanceSharedScript); script->language = xml->rootElement->name.value; script->code = cdata->content.value; script->codePosition = { {resource},cdata->codeRange.start }; script->codePosition.column += 9; // <![CDATA[ return script; } } errors.Add(GuiResourceError({ {resource},xml->rootElement->codeRange.start }, L"Script should be contained in a CDATA section.")); return nullptr; } Ptr<glr::xml::XmlElement> GuiInstanceSharedScript::SaveToXml() { auto cdata = Ptr(new XmlCData); cdata->content.value = code; auto xml = Ptr(new XmlElement); xml->name.value = language; xml->subNodes.Add(cdata); return xml; } } } /*********************************************************************** .\INSTANCELOADERS\GUIINSTANCELOADER_COMPOSITIONS.CPP ***********************************************************************/ #ifndef VCZH_DEBUG_NO_REFLECTION namespace vl { namespace presentation { namespace instance_loaders { /*********************************************************************** GuiAxisInstanceLoader ***********************************************************************/ class GuiAxisInstanceLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; GlobalStringKey _AxisDirection; public: GuiAxisInstanceLoader() { typeName = GlobalStringKey::Get(description::TypeInfo<GuiAxis>::content.typeName); _AxisDirection = GlobalStringKey::Get(L"AxisDirection"); } GlobalStringKey GetTypeName()override { return typeName; } void GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { if (CanCreate(typeInfo)) { propertyNames.Add(_AxisDirection); } } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _AxisDirection) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<AxisDirection>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } bool CanCreate(const TypeInfo& typeInfo)override { return typeName == typeInfo.typeName; } Ptr<workflow::WfStatement> CreateInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos tagPosition, GuiResourceError::List& errors)override { if (CanCreate(typeInfo)) { vint indexAxisDirection = arguments.Keys().IndexOf(_AxisDirection); if (indexAxisDirection != -1) { auto createExpr = Ptr(new WfNewClassExpression); createExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<GuiAxis>>::CreateTypeInfo().Obj()); createExpr->arguments.Add(arguments.GetByIndex(indexAxisDirection)[0].expression); auto refVariable = Ptr(new WfReferenceExpression); refVariable->name.value = variableName.ToString(); auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->op = WfBinaryOperator::Assign; assignExpr->first = refVariable; assignExpr->second = createExpr; auto assignStat = Ptr(new WfExpressionStatement); assignStat->expression = assignExpr; return assignStat; } } return nullptr; } }; /*********************************************************************** GuiCompositionInstanceLoader ***********************************************************************/ class GuiCompositionInstanceLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; public: GuiCompositionInstanceLoader() { typeName = GlobalStringKey::Get(description::TypeInfo<GuiGraphicsComposition>::content.typeName); } GlobalStringKey GetTypeName()override { return typeName; } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(GlobalStringKey::Empty); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == GlobalStringKey::Empty) { auto info = GuiInstancePropertyInfo::Collection(nullptr); info->acceptableTypes.Add(TypeInfoRetriver<GuiControl*>::CreateTypeInfo()); info->acceptableTypes.Add(TypeInfoRetriver<GuiGraphicsComposition*>::CreateTypeInfo()); info->acceptableTypes.Add(TypeInfoRetriver<Ptr<IGuiGraphicsElement>>::CreateTypeInfo()); if (propertyInfo.typeInfo.typeInfo->GetTypeDescriptor()->CanConvertTo(description::GetTypeDescriptor<GuiInstanceRootObject>())) { info->acceptableTypes.Add(TypeInfoRetriver<GuiComponent*>::CreateTypeInfo()); } return info; } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { const auto& values = arguments.GetByIndex(index); if (prop == GlobalStringKey::Empty) { auto value = values[0].expression; auto td = values[0].typeInfo->GetTypeDescriptor(); Ptr<WfExpression> expr; if (td->CanConvertTo(description::GetTypeDescriptor<GuiComponent>())) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refAddComponent = Ptr(new WfMemberExpression); refAddComponent->parent = refControl; refAddComponent->name.value = L"AddComponent"; auto call = Ptr(new WfCallExpression); call->function = refAddComponent; call->arguments.Add(value); expr = call; } else if (td->CanConvertTo(description::GetTypeDescriptor<GuiControlHost>())) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refAddControlHostComponent = Ptr(new WfMemberExpression); refAddControlHostComponent->parent = refControl; refAddControlHostComponent->name.value = L"AddControlHostComponent"; auto call = Ptr(new WfCallExpression); call->function = refAddControlHostComponent; call->arguments.Add(value); expr = call; } else if (td->CanConvertTo(description::GetTypeDescriptor<IGuiGraphicsElement>())) { auto refComposition = Ptr(new WfReferenceExpression); refComposition->name.value = variableName.ToString(); auto refOwnedElement = Ptr(new WfMemberExpression); refOwnedElement->parent = refComposition; refOwnedElement->name.value = L"OwnedElement"; auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refOwnedElement; assign->second = value; expr = assign; } else if (td->CanConvertTo(description::GetTypeDescriptor<GuiControl>())) { auto refBoundsComposition = Ptr(new WfMemberExpression); refBoundsComposition->parent = value; refBoundsComposition->name.value = L"BoundsComposition"; auto refComposition = Ptr(new WfReferenceExpression); refComposition->name.value = variableName.ToString(); auto refAddChild = Ptr(new WfMemberExpression); refAddChild->parent = refComposition; refAddChild->name.value = L"AddChild"; auto call = Ptr(new WfCallExpression); call->function = refAddChild; call->arguments.Add(refBoundsComposition); expr = call; } else if (td->CanConvertTo(description::GetTypeDescriptor<GuiGraphicsComposition>())) { auto refComposition = Ptr(new WfReferenceExpression); refComposition->name.value = variableName.ToString(); auto refAddChild = Ptr(new WfMemberExpression); refAddChild->parent = refComposition; refAddChild->name.value = L"AddChild"; auto call = Ptr(new WfCallExpression); call->function = refAddChild; call->arguments.Add(value); expr = call; } if (expr) { auto stat = Ptr(new WfExpressionStatement); stat->expression = expr; block->statements.Add(stat); } } } if (block->statements.Count() > 0) { return block; } return nullptr; } }; /*********************************************************************** GuiTableCompositionInstanceLoader ***********************************************************************/ class GuiTableCompositionInstanceLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; GlobalStringKey _Rows, _Columns; public: GuiTableCompositionInstanceLoader() { typeName = GlobalStringKey::Get(description::TypeInfo<GuiTableComposition>::content.typeName); _Rows = GlobalStringKey::Get(L"Rows"); _Columns = GlobalStringKey::Get(L"Columns"); } GlobalStringKey GetTypeName()override { return typeName; } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(_Rows); propertyNames.Add(_Columns); } void GetPairedProperties(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo, collections::List<GlobalStringKey>& propertyNames)override { if (propertyInfo.propertyName == _Rows || propertyInfo.propertyName == _Columns) { propertyNames.Add(_Rows); propertyNames.Add(_Columns); } } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _Rows || propertyInfo.propertyName == _Columns) { return GuiInstancePropertyInfo::Array(TypeInfoRetriver<GuiCellOption>::CreateTypeInfo()); } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { if (prop == _Rows) { auto indexColumns = arguments.Keys().IndexOf(_Columns); if (indexColumns != -1) { auto& rows = arguments.GetByIndex(index); auto& columns = arguments.GetByIndex(indexColumns); { auto refComposition = Ptr(new WfReferenceExpression); refComposition->name.value = variableName.ToString(); auto refSetRowsAndColumns = Ptr(new WfMemberExpression); refSetRowsAndColumns->parent = refComposition; refSetRowsAndColumns->name.value = L"SetRowsAndColumns"; auto rowsExpr = Ptr(new WfIntegerExpression); rowsExpr->value.value = itow(rows.Count()); auto columnsExpr = Ptr(new WfIntegerExpression); columnsExpr->value.value = itow(columns.Count()); auto call = Ptr(new WfCallExpression); call->function = refSetRowsAndColumns; call->arguments.Add(rowsExpr); call->arguments.Add(columnsExpr); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } // TODO: (enumerable) foreach:indexed for (vint i = 0; i < rows.Count(); i++) { auto refComposition = Ptr(new WfReferenceExpression); refComposition->name.value = variableName.ToString(); auto refSetRowOption = Ptr(new WfMemberExpression); refSetRowOption->parent = refComposition; refSetRowOption->name.value = L"SetRowOption"; auto indexExpr = Ptr(new WfIntegerExpression); indexExpr->value.value = itow(i); auto call = Ptr(new WfCallExpression); call->function = refSetRowOption; call->arguments.Add(indexExpr); call->arguments.Add(rows[i].expression); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } // TODO: (enumerable) foreach:indexed for (vint i = 0; i < columns.Count(); i++) { auto refComposition = Ptr(new WfReferenceExpression); refComposition->name.value = variableName.ToString(); auto refSetColumnOption = Ptr(new WfMemberExpression); refSetColumnOption->parent = refComposition; refSetColumnOption->name.value = L"SetColumnOption"; auto indexExpr = Ptr(new WfIntegerExpression); indexExpr->value.value = itow(i); auto call = Ptr(new WfCallExpression); call->function = refSetColumnOption; call->arguments.Add(indexExpr); call->arguments.Add(columns[i].expression); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } } } } if (block->statements.Count() > 0) { return block; } return nullptr; } }; /*********************************************************************** GuiCellCompositionInstanceLoader ***********************************************************************/ class GuiCellCompositionInstanceLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; GlobalStringKey _Site; public: GuiCellCompositionInstanceLoader() { typeName = GlobalStringKey::Get(description::TypeInfo<GuiCellComposition>::content.typeName); _Site = GlobalStringKey::Get(L"Site"); } GlobalStringKey GetTypeName()override { return typeName; } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(_Site); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _Site) { return GuiInstancePropertyInfo::Assign(TypeInfoRetriver<SiteValue>::CreateTypeInfo()); } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { if (prop == _Site) { SiteValue site; { auto siteExpr = arguments.GetByIndex(index)[0].expression; if (auto inferExpr = siteExpr.Cast<WfInferExpression>()) { if (auto ctorExpr = inferExpr->expression.Cast<WfConstructorExpression>()) { auto st = description::GetTypeDescriptor<vint>()->GetSerializableType(); for (auto argument : ctorExpr->arguments) { if (auto keyExpr = argument->key.Cast<WfReferenceExpression>()) { if (auto valueExpr = argument->value.Cast<WfIntegerExpression>()) { Value value; if (st->Deserialize(valueExpr->value.value, value)) { vint propValue = UnboxValue<vint>(value); if (keyExpr->name.value == L"row") { site.row = propValue; } else if (keyExpr->name.value == L"column") { site.column = propValue; } else if (keyExpr->name.value == L"rowSpan") { site.rowSpan = propValue; } else if (keyExpr->name.value == L"columnSpan") { site.columnSpan = propValue; } else { goto ILLEGAL_SITE_PROPERTY; } continue; } } } goto ILLEGAL_SITE_PROPERTY; } goto FINISH_SITE_PROPERTY; } } ILLEGAL_SITE_PROPERTY: errors.Add(GuiResourceError({ resolvingResult.resource }, attPosition, L"Precompile: The value of property \"Site\" of type \"" + typeInfo.typeName.ToString() + L"\" is not in a correct format: \"row:<integer> column:<integer> [rowSpan:<integer>] [columnSpan:<integer>]\".")); continue; } FINISH_SITE_PROPERTY:; { auto refComposition = Ptr(new WfReferenceExpression); refComposition->name.value = variableName.ToString(); auto refSetSite = Ptr(new WfMemberExpression); refSetSite->parent = refComposition; refSetSite->name.value = L"SetSite"; auto call = Ptr(new WfCallExpression); call->function = refSetSite; { auto arg = Ptr(new WfIntegerExpression); arg->value.value = itow(site.row); call->arguments.Add(arg); } { auto arg = Ptr(new WfIntegerExpression); arg->value.value = itow(site.column); call->arguments.Add(arg); } { auto arg = Ptr(new WfIntegerExpression); arg->value.value = itow(site.rowSpan); call->arguments.Add(arg); } { auto arg = Ptr(new WfIntegerExpression); arg->value.value = itow(site.columnSpan); call->arguments.Add(arg); } auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } } } if (block->statements.Count() > 0) { return block; } return nullptr; } }; /*********************************************************************** Initialization ***********************************************************************/ void LoadCompositions(IGuiInstanceLoaderManager* manager) { manager->SetLoader(Ptr(new GuiAxisInstanceLoader)); manager->SetLoader(Ptr(new GuiCompositionInstanceLoader)); manager->SetLoader(Ptr(new GuiTableCompositionInstanceLoader)); manager->SetLoader(Ptr(new GuiCellCompositionInstanceLoader)); } } } } #endif /*********************************************************************** .\INSTANCELOADERS\GUIINSTANCELOADER_DOCUMENT.CPP ***********************************************************************/ #ifndef VCZH_DEBUG_NO_REFLECTION namespace vl { namespace presentation { namespace instance_loaders { /*********************************************************************** GuiDocumentItemInstanceLoader ***********************************************************************/ class GuiDocumentItemInstanceLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; GlobalStringKey _Name; public: GuiDocumentItemInstanceLoader() { typeName = GlobalStringKey::Get(description::TypeInfo<GuiDocumentItem>::content.typeName); _Name = GlobalStringKey::Get(L"Name"); } GlobalStringKey GetTypeName()override { return typeName; } void GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { if (CanCreate(typeInfo)) { propertyNames.Add(_Name); } } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); propertyNames.Add(GlobalStringKey::Empty); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == GlobalStringKey::Empty) { auto info = GuiInstancePropertyInfo::Collection(nullptr); info->acceptableTypes.Add(TypeInfoRetriver<GuiControl*>::CreateTypeInfo()); info->acceptableTypes.Add(TypeInfoRetriver<GuiGraphicsComposition*>::CreateTypeInfo()); return info; } else if (propertyInfo.propertyName == _Name) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<WString>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } bool CanCreate(const TypeInfo& typeInfo)override { return typeName == typeInfo.typeName; } Ptr<workflow::WfStatement> CreateInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos tagPosition, GuiResourceError::List& errors)override { if (CanCreate(typeInfo)) { vint indexName = arguments.Keys().IndexOf(_Name); if (indexName != -1) { auto type = TypeInfoRetriver<Ptr<GuiDocumentItem>>::CreateTypeInfo(); auto createExpr = Ptr(new WfNewClassExpression); createExpr->type = GetTypeFromTypeInfo(type.Obj()); createExpr->arguments.Add(arguments.GetByIndex(indexName)[0].expression); auto refVariable = Ptr(new WfReferenceExpression); refVariable->name.value = variableName.ToString(); auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->op = WfBinaryOperator::Assign; assignExpr->first = refVariable; assignExpr->second = createExpr; auto assignStat = Ptr(new WfExpressionStatement); assignStat->expression = assignExpr; return assignStat; } } return nullptr; } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { const auto& values = arguments.GetByIndex(index); if (prop == GlobalStringKey::Empty) { auto value = values[0].expression; auto td = values[0].typeInfo->GetTypeDescriptor(); Ptr<WfExpression> compositionExpr; if (td->CanConvertTo(description::GetTypeDescriptor<GuiControl>())) { auto member = Ptr(new WfMemberExpression); member->parent = value; member->name.value = L"BoundsComposition"; compositionExpr = member; } else if (td->CanConvertTo(description::GetTypeDescriptor<GuiGraphicsComposition>())) { compositionExpr = value; } if (compositionExpr) { auto refItem = Ptr(new WfReferenceExpression); refItem->name.value = variableName.ToString(); auto refContainer = Ptr(new WfMemberExpression); refContainer->parent = refItem; refContainer->name.value = L"Container"; auto refAddChild = Ptr(new WfMemberExpression); refAddChild->parent = refContainer; refAddChild->name.value = L"AddChild"; auto call = Ptr(new WfCallExpression); call->function = refAddChild; call->arguments.Add(compositionExpr); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } } } if (block->statements.Count() > 0) { return block; } return nullptr; } }; /*********************************************************************** GuiDocumentInstanceLoaderBase ***********************************************************************/ template<typename TBaseType> class GuiDocumentInstanceLoaderBase : public TBaseType { private: using TypeInfo = typename TBaseType::TypeInfo; protected: GlobalStringKey _Behavior; void AddAdditionalArguments(types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, IGuiInstanceLoader::ArgumentMap& arguments, GuiResourceError::List& errors, Ptr<WfNewClassExpression> createControl)override { vint indexBehavior = arguments.Keys().IndexOf(_Behavior); if (indexBehavior != -1) { createControl->arguments.Add(arguments.GetByIndex(indexBehavior)[0].expression); } } public: using PropertyInfo = IGuiInstanceLoader::PropertyInfo; using ArgumentMap = IGuiInstanceLoader::ArgumentMap; GuiDocumentInstanceLoaderBase(const WString& _typeName, theme::ThemeName themeName) :TBaseType(_typeName, themeName) { _Behavior = GlobalStringKey::Get(L"Behavior"); } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(GlobalStringKey::Empty); TBaseType::GetPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == GlobalStringKey::Empty) { return GuiInstancePropertyInfo::CollectionWithParent(TypeInfoRetriver<Ptr<GuiDocumentItem>>::CreateTypeInfo()); } else if(propertyInfo.propertyName == _Behavior && this->CanCreate(propertyInfo.typeInfo)) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<GuiDocumentConfig>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return TBaseType::GetPropertyType(precompileContext, propertyInfo); } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { const auto& values = arguments.GetByIndex(index); if (prop == GlobalStringKey::Empty) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refAddDocumentItem = Ptr(new WfMemberExpression); refAddDocumentItem->parent = refControl; refAddDocumentItem->name.value = L"AddDocumentItem"; auto call = Ptr(new WfCallExpression); call->function = refAddDocumentItem; call->arguments.Add(values[0].expression); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } } if (block->statements.Count() > 0) { return block; } return TBaseType::AssignParameters(precompileContext, resolvingResult, typeInfo, variableName, arguments, attPosition, errors); } }; /*********************************************************************** GuiDocumentViewerInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiDocumentViewer> class GuiDocumentViewerInstanceLoader : public GuiDocumentInstanceLoaderBase<BASE_TYPE> { public: GuiDocumentViewerInstanceLoader() :GuiDocumentInstanceLoaderBase<BASE_TYPE>(description::TypeInfo<GuiDocumentViewer>::content.typeName, theme::ThemeName::DocumentViewer) { } }; #undef BASE_TYPE /*********************************************************************** GuiDocumentLabelInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiDocumentLabel> class GuiDocumentLabelInstanceLoader : public GuiDocumentInstanceLoaderBase<BASE_TYPE> { public: GuiDocumentLabelInstanceLoader() :GuiDocumentInstanceLoaderBase<BASE_TYPE>(description::TypeInfo<GuiDocumentLabel>::content.typeName, theme::ThemeName::DocumentLabel) { } }; #undef BASE_TYPE /*********************************************************************** Initialization ***********************************************************************/ void LoadDocumentControls(IGuiInstanceLoaderManager* manager) { manager->SetLoader(Ptr(new GuiDocumentItemInstanceLoader)); manager->SetLoader(Ptr(new GuiDocumentViewerInstanceLoader)); manager->SetLoader(Ptr(new GuiDocumentLabelInstanceLoader)); manager->CreateVirtualType(GlobalStringKey::Get(description::TypeInfo<GuiDocumentLabel>::content.typeName), Ptr(new GuiDocumentInstanceLoaderBase<GuiTemplateControlInstanceLoader<GuiDocumentLabel>>( L"presentation::controls::GuiDocumentTextBox", theme::ThemeName::DocumentTextBox ))); } } } } #endif /*********************************************************************** .\INSTANCELOADERS\GUIINSTANCELOADER_LIST.CPP ***********************************************************************/ #ifndef VCZH_DEBUG_NO_REFLECTION namespace vl { namespace presentation { namespace instance_loaders { template<typename TItemTemplateStyle> Ptr<WfStatement> CreateSetControlTemplateStyle(types::ResolvingResult& resolvingResult, GlobalStringKey variableName, Ptr<WfExpression> argument, const WString& propertyName) { auto createStyle = Ptr(new WfNewClassExpression); createStyle->type = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<TItemTemplateStyle>>::CreateTypeInfo().Obj()); createStyle->arguments.Add(argument); auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refStyleProvider = Ptr(new WfMemberExpression); refStyleProvider->parent = refControl; refStyleProvider->name.value = propertyName; auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refStyleProvider; assign->second = createStyle; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; return stat; } /*********************************************************************** GuiComboButtonInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiComboButton> class GuiComboButtonInstanceLoader : public BASE_TYPE { protected: GlobalStringKey _DropdownControl; void AddAdditionalArguments(types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceError::List& errors, Ptr<WfNewClassExpression> createControl)override { vint indexListControl = arguments.Keys().IndexOf(_DropdownControl); if (indexListControl != -1) { createControl->arguments.Add(arguments.GetByIndex(indexListControl)[0].expression); } } public: GuiComboButtonInstanceLoader() :BASE_TYPE(L"presentation::controls::GuiComboButton", theme::ThemeName::ComboBox) { _DropdownControl = GlobalStringKey::Get(L"DropdownControl"); } void GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { if (CanCreate(typeInfo)) { propertyNames.Add(_DropdownControl); } BASE_TYPE::GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); BASE_TYPE::GetPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _DropdownControl) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<GuiControl*>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return BASE_TYPE::GetPropertyType(precompileContext, propertyInfo); } }; #undef BASE_TYPE /*********************************************************************** GuiComboBoxInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiComboBoxListControl> class GuiComboBoxInstanceLoader : public BASE_TYPE { protected: GlobalStringKey _ListControl; void AddAdditionalArguments(types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceError::List& errors, Ptr<WfNewClassExpression> createControl)override { vint indexListControl = arguments.Keys().IndexOf(_ListControl); if (indexListControl != -1) { createControl->arguments.Add(arguments.GetByIndex(indexListControl)[0].expression); } } public: GuiComboBoxInstanceLoader() :BASE_TYPE(L"presentation::controls::GuiComboBox", theme::ThemeName::ComboBox) { _ListControl = GlobalStringKey::Get(L"ListControl"); } void GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { if (CanCreate(typeInfo)) { propertyNames.Add(_ListControl); } BASE_TYPE::GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); BASE_TYPE::GetPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _ListControl) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<GuiSelectableListControl*>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return BASE_TYPE::GetPropertyType(precompileContext, propertyInfo); } }; #undef BASE_TYPE /*********************************************************************** GuiTreeViewInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiTreeView> class GuiTreeViewInstanceLoader : public BASE_TYPE { protected: GlobalStringKey _Nodes; public: GuiTreeViewInstanceLoader() :BASE_TYPE(description::TypeInfo<GuiTreeView>::content.typeName, theme::ThemeName::TreeView) { _Nodes = GlobalStringKey::Get(L"Nodes"); } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const typename BASE_TYPE::TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(_Nodes); BASE_TYPE::GetPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const typename BASE_TYPE::PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _Nodes) { return GuiInstancePropertyInfo::Collection(TypeInfoRetriver<Ptr<tree::MemoryNodeProvider>>::CreateTypeInfo()); } return BASE_TYPE::GetPropertyType(precompileContext, propertyInfo); } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const typename BASE_TYPE::TypeInfo& typeInfo, GlobalStringKey variableName, typename BASE_TYPE::ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { if (prop == _Nodes) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refNodes = Ptr(new WfMemberExpression); refNodes->parent = refControl; refNodes->name.value = L"Nodes"; auto refChildren = Ptr(new WfMemberExpression); refChildren->parent = refNodes; refChildren->name.value = L"Children"; auto refAdd = Ptr(new WfMemberExpression); refAdd->parent = refChildren; refAdd->name.value = L"Add"; auto call = Ptr(new WfCallExpression); call->function = refAdd; call->arguments.Add(arguments.GetByIndex(index)[0].expression); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } } if (block->statements.Count() > 0) { return block; } return BASE_TYPE::AssignParameters(precompileContext, resolvingResult, typeInfo, variableName, arguments, attPosition, errors); } }; #undef BASE_TYPE /*********************************************************************** GuiBindableTreeViewInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiBindableTreeView> class GuiBindableTreeViewInstanceLoader : public BASE_TYPE { protected: GlobalStringKey _ReverseMappingProperty; void AddAdditionalArguments(types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceError::List& errors, Ptr<WfNewClassExpression> createControl)override { vint indexReverseMappingProperty = arguments.Keys().IndexOf(_ReverseMappingProperty); if (indexReverseMappingProperty != -1) { createControl->arguments.Add(arguments.GetByIndex(indexReverseMappingProperty)[0].expression); } } public: GuiBindableTreeViewInstanceLoader() :BASE_TYPE(description::TypeInfo<GuiBindableTreeView>::content.typeName, theme::ThemeName::TreeView) { _ReverseMappingProperty = GlobalStringKey::Get(L"ReverseMappingProperty"); } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const typename BASE_TYPE::TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(_ReverseMappingProperty); BASE_TYPE::GetPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const typename BASE_TYPE::PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _ReverseMappingProperty) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<WritableItemProperty<description::Value>>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return BASE_TYPE::GetPropertyType(precompileContext, propertyInfo); } }; #undef BASE_TYPE /*********************************************************************** GuiTreeNodeInstanceLoader ***********************************************************************/ class GuiTreeNodeInstanceLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; GlobalStringKey _Text, _Image, _Tag; public: GuiTreeNodeInstanceLoader() :typeName(GlobalStringKey::Get(L"presentation::controls::tree::TreeNode")) { _Text = GlobalStringKey::Get(L"Text"); _Image = GlobalStringKey::Get(L"Image"); _Tag = GlobalStringKey::Get(L"Tag"); } GlobalStringKey GetTypeName()override { return typeName; } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(_Text); propertyNames.Add(_Image); propertyNames.Add(_Tag); propertyNames.Add(GlobalStringKey::Empty); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _Text) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<WString>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; info->bindability = GuiInstancePropertyInfo::Bindable; return info; } else if (propertyInfo.propertyName == _Image) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<Ptr<GuiImageData>>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; info->bindability = GuiInstancePropertyInfo::Bindable; return info; } else if (propertyInfo.propertyName == _Tag) { return GuiInstancePropertyInfo::Assign(TypeInfoRetriver<Value>::CreateTypeInfo()); } else if (propertyInfo.propertyName == GlobalStringKey::Empty) { return GuiInstancePropertyInfo::Collection(TypeInfoRetriver<Ptr<tree::MemoryNodeProvider>>::CreateTypeInfo()); } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } bool CanCreate(const TypeInfo& typeInfo)override { return typeInfo.typeName == GetTypeName(); } Ptr<workflow::WfStatement> CreateInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos tagPosition, GuiResourceError::List& errors)override { if (CanCreate(typeInfo)) { auto createItem = Ptr(new WfNewClassExpression); createItem->type = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<tree::TreeViewItem>>::CreateTypeInfo().Obj()); vint imageIndex = arguments.Keys().IndexOf(_Image); vint textIndex = arguments.Keys().IndexOf(_Text); if (imageIndex != -1 || textIndex != -1) { if (imageIndex == -1) { auto nullExpr = Ptr(new WfLiteralExpression); nullExpr->value = WfLiteralValue::Null; createItem->arguments.Add(nullExpr); } else { createItem->arguments.Add(arguments.GetByIndex(imageIndex)[0].expression); } if (textIndex == -1) { createItem->arguments.Add(Ptr(new WfStringExpression)); } else { createItem->arguments.Add(arguments.GetByIndex(textIndex)[0].expression); } } auto createNode = Ptr(new WfNewClassExpression); createNode->type = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<tree::MemoryNodeProvider>>::CreateTypeInfo().Obj()); createNode->arguments.Add(createItem); auto refNode = Ptr(new WfReferenceExpression); refNode->name.value = variableName.ToString(); auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refNode; assign->second = createNode; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; return stat; } return nullptr; } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { if (prop == GlobalStringKey::Empty) { auto refNode = Ptr(new WfReferenceExpression); refNode->name.value = variableName.ToString(); auto refChildren = Ptr(new WfMemberExpression); refChildren->parent = refNode; refChildren->name.value = L"Children"; auto refAdd = Ptr(new WfMemberExpression); refAdd->parent = refChildren; refAdd->name.value = L"Add"; auto call = Ptr(new WfCallExpression); call->function = refAdd; call->arguments.Add(arguments.GetByIndex(index)[0].expression); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } else if (prop == _Tag) { { auto refNode = Ptr(new WfReferenceExpression); refNode->name.value = variableName.ToString(); auto refData = Ptr(new WfMemberExpression); refData->parent = refNode; refData->name.value = L"Data"; auto castExpr = Ptr(new WfTypeCastingExpression); castExpr->strategy = WfTypeCastingStrategy::Strong; castExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<tree::TreeViewItem>>::CreateTypeInfo().Obj()); castExpr->expression = refData; auto refProp = Ptr(new WfMemberExpression); refProp->parent = castExpr; refProp->name.value = L"tag"; auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refProp; assign->second = arguments.GetByIndex(index)[0].expression; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; block->statements.Add(stat); } if (prop != _Tag) { auto refNode = Ptr(new WfReferenceExpression); refNode->name.value = variableName.ToString(); auto refNotifyDataModified = Ptr(new WfMemberExpression); refNotifyDataModified->parent = refNode; refNotifyDataModified->name.value = L"NotifyDataModified"; auto call = Ptr(new WfCallExpression); call->function = refNotifyDataModified; auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } } } if (block->statements.Count() > 0) { return block; } return nullptr; } }; /*********************************************************************** Initialization ***********************************************************************/ void LoadListControls(IGuiInstanceLoaderManager* manager) { manager->CreateVirtualType( GlobalStringKey::Get(description::TypeInfo<GuiComboBoxListControl>::content.typeName), Ptr(new GuiComboBoxInstanceLoader) ); manager->SetLoader(Ptr(new GuiComboButtonInstanceLoader)); manager->SetLoader(Ptr(new GuiTreeViewInstanceLoader)); manager->SetLoader(Ptr(new GuiBindableTreeViewInstanceLoader)); manager->CreateVirtualType( GlobalStringKey::Get(description::TypeInfo<tree::MemoryNodeProvider>::content.typeName), Ptr(new GuiTreeNodeInstanceLoader) ); } } } } #endif /*********************************************************************** .\INSTANCELOADERS\GUIINSTANCELOADER_PLUGIN.CPP ***********************************************************************/ /* GuiInstanceLoader_Plugin.cpp GuiControl default: GuiControl*, GuiGraphicsComposition* GuiInstanceRootObject default: GuiComponent* GuiRawElement GuiInstanceLoader_TemplateControl.h GuiControl GuiInstanceLoader_Compositions.cpp GuiAxis ctor: AxisDirection GuiComposition default: GuiControl*, GuiGraphicsComposition*, Ptr<IGuiGraphicsElement> GuiTableComposition Rows, Columns: array(GuiCellOption) GuiCellComposition Site: SiteValue GuiInstanceLoader_Document.cpp GuiDocumentItem default: GuiControl*, GuiGraphicsComposition* GuiDocumentViewer, GuiDocumentLable default: Ptr<GuiDocumentItem> ctor: Behavior(GuiDocumentConfig) GuiInstanceLoader_List.cpp GuiComboBox ctor: ListControl(GuiListControl*) GuiTreeView Nodes: array(Ptr<tree::MemoryNodeProvider>) GuiBindableTreeView ctor: ReverseMappingProperty(WritableItemProperty<Value>) tree::TreeNode ctor: Text, Image Tag GuiInstanceLoader_Templates.cpp GuiCommonDatePickerLook ctor: BackgroundColor, PrimaryTextColor, SecondaryTextColor GuiCommonScrollViewLook ctor: DefaultScrollSize GuiInstanceLoader_Toolstrip.cpp GuiToolstripMenu, GuiToolstripMenuBar, GuiToolstripToolBar, GuiBindableRibbonGalleryMenu default: collection(GuiControl*) GuiToolstripButton SubMenu-set: GuiToolstripMenu* GuiRibbonButtons ctor: MaxSize, MinSize */ namespace vl { namespace presentation { namespace instance_loaders { #ifndef VCZH_DEBUG_NO_REFLECTION /*********************************************************************** GuiControlInstanceLoader ***********************************************************************/ class GuiControlInstanceLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; public: GuiControlInstanceLoader() { typeName = GlobalStringKey::Get(description::TypeInfo<GuiControl>::content.typeName); } GlobalStringKey GetTypeName()override { return typeName; } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(GlobalStringKey::Empty); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == GlobalStringKey::Empty) { auto info = GuiInstancePropertyInfo::Collection(nullptr); info->acceptableTypes.Add(TypeInfoRetriver<GuiControl*>::CreateTypeInfo()); info->acceptableTypes.Add(TypeInfoRetriver<GuiGraphicsComposition*>::CreateTypeInfo()); if (propertyInfo.typeInfo.typeInfo->GetTypeDescriptor()->CanConvertTo(description::GetTypeDescriptor<GuiInstanceRootObject>())) { info->acceptableTypes.Add(TypeInfoRetriver<GuiComponent*>::CreateTypeInfo()); } return info; } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { const auto& values = arguments.GetByIndex(index); if (prop == GlobalStringKey::Empty) { auto value = values[0].expression; auto td = values[0].typeInfo->GetTypeDescriptor(); Ptr<WfExpression> expr; if (td->CanConvertTo(description::GetTypeDescriptor<GuiComponent>())) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refAddComponent = Ptr(new WfMemberExpression); refAddComponent->parent = refControl; refAddComponent->name.value = L"AddComponent"; auto call = Ptr(new WfCallExpression); call->function = refAddComponent; call->arguments.Add(value); expr = call; } else if (td->CanConvertTo(description::GetTypeDescriptor<GuiControlHost>())) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refAddControlHostComponent = Ptr(new WfMemberExpression); refAddControlHostComponent->parent = refControl; refAddControlHostComponent->name.value = L"AddControlHostComponent"; auto call = Ptr(new WfCallExpression); call->function = refAddControlHostComponent; call->arguments.Add(value); expr = call; } else if (td->CanConvertTo(description::GetTypeDescriptor<GuiControl>())) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refAddChild = Ptr(new WfMemberExpression); refAddChild->parent = refControl; refAddChild->name.value = L"AddChild"; auto call = Ptr(new WfCallExpression); call->function = refAddChild; call->arguments.Add(value); expr = call; } else if (td->CanConvertTo(description::GetTypeDescriptor<GuiGraphicsComposition>())) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refContainerComposition = Ptr(new WfMemberExpression); refContainerComposition->parent = refControl; refContainerComposition->name.value = L"ContainerComposition"; auto refAddChild = Ptr(new WfMemberExpression); refAddChild->parent = refContainerComposition; refAddChild->name.value = L"AddChild"; auto call = Ptr(new WfCallExpression); call->function = refAddChild; call->arguments.Add(value); expr = call; } if (expr) { auto stat = Ptr(new WfExpressionStatement); stat->expression = expr; block->statements.Add(stat); } } } if (block->statements.Count() > 0) { return block; } return nullptr; } }; /*********************************************************************** GuiRawElementInstanceLoader ***********************************************************************/ class GuiRawElementInstanceLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; public: GuiRawElementInstanceLoader() { typeName = GlobalStringKey::Get(L"presentation::elements::GuiRawElement"); } GlobalStringKey GetTypeName()override { return typeName; } bool CanCreate(const TypeInfo& typeInfo) override { return typeName == typeInfo.typeName; } Ptr<workflow::WfStatement> CreateInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos tagPosition, GuiResourceError::List& errors)override { if (CanCreate(typeInfo)) { auto refCreateRawElement = Ptr(new WfChildExpression); refCreateRawElement->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<IGuiGraphicsElement>()); refCreateRawElement->name.value = L"CreateRawElement"; auto call = Ptr(new WfCallExpression); call->function = refCreateRawElement; auto refVariable = Ptr(new WfReferenceExpression); refVariable->name.value = variableName.ToString(); auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refVariable; assign->second = call; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; return stat; } return nullptr; } }; #endif /*********************************************************************** GuiPredefinedInstanceLoadersPlugin ***********************************************************************/ void InitializeTrackerProgressBar(const WString& variableName, Ptr<WfBlockStatement> block) { auto refVariable = Ptr(new WfReferenceExpression); refVariable->name.value = variableName; auto refSetPageSize = Ptr(new WfMemberExpression); refSetPageSize->parent = refVariable; refSetPageSize->name.value = L"SetPageSize"; auto refZero = Ptr(new WfIntegerExpression); refZero->value.value = L"0"; auto call = Ptr(new WfCallExpression); call->function = refSetPageSize; call->arguments.Add(refZero); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; block->statements.Add(stat); } extern void LoadToolstripControls(IGuiInstanceLoaderManager* manager); extern void LoadListControls(IGuiInstanceLoaderManager* manager); extern void LoadDocumentControls(IGuiInstanceLoaderManager* manager); extern void LoadCompositions(IGuiInstanceLoaderManager* manager); extern void LoadTemplates(IGuiInstanceLoaderManager* manager); class GuiPredefinedInstanceLoadersPlugin : public Object, public IGuiPlugin { public: GUI_PLUGIN_NAME(GacUI_Instance_TypeLoaders) { GUI_PLUGIN_DEPEND(GacUI_Res_ResourceResolver); GUI_PLUGIN_DEPEND(GacUI_Instance); GUI_PLUGIN_DEPEND(GacUI_Instance_Reflection); } void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { #ifndef VCZH_DEBUG_NO_REFLECTION if (controllerUnrelatedPlugins) { IGuiInstanceLoaderManager* manager=GetInstanceLoaderManager(); #define ADD_TEMPLATE_CONTROL(TYPENAME, THEME_NAME)\ manager->SetLoader(\ Ptr(new GuiTemplateControlInstanceLoader<TYPENAME>(\ L"presentation::controls::" L ## #TYPENAME,\ theme::ThemeName::THEME_NAME\ )\ )) #define ADD_VIRTUAL_CONTROL(VIRTUALTYPENAME, TYPENAME, THEME_NAME)\ manager->CreateVirtualType(GlobalStringKey::Get(description::TypeInfo<TYPENAME>::content.typeName),\ Ptr(new GuiTemplateControlInstanceLoader<TYPENAME>(\ L"presentation::controls::Gui" L ## #VIRTUALTYPENAME,\ theme::ThemeName::THEME_NAME\ )\ )) #define ADD_VIRTUAL_CONTROL_F(VIRTUALTYPENAME, TYPENAME, THEME_NAME, INIT_FUNCTION)\ manager->CreateVirtualType(GlobalStringKey::Get(description::TypeInfo<TYPENAME>::content.typeName),\ Ptr(new GuiTemplateControlInstanceLoader<TYPENAME>(\ L"presentation::controls::Gui" L ## #VIRTUALTYPENAME,\ theme::ThemeName::THEME_NAME,\ nullptr,\ INIT_FUNCTION\ )\ )) manager->CreateVirtualType( GlobalStringKey::Get(description::TypeInfo<IGuiGraphicsElement>::content.typeName), Ptr(new GuiRawElementInstanceLoader) ); manager->SetLoader(Ptr(new GuiControlInstanceLoader)); /* REAL-CONTROL-TYPE THEME-NAME */ ADD_TEMPLATE_CONTROL ( GuiCustomControl, CustomControl ); ADD_TEMPLATE_CONTROL ( GuiLabel, Label ); ADD_TEMPLATE_CONTROL ( GuiButton, Button ); ADD_TEMPLATE_CONTROL ( GuiTabPage, CustomControl ); ADD_TEMPLATE_CONTROL ( GuiTab, Tab ); ADD_TEMPLATE_CONTROL ( GuiScrollContainer, ScrollView ); ADD_TEMPLATE_CONTROL ( GuiWindow, Window ); ADD_TEMPLATE_CONTROL ( GuiTextList, TextList ); ADD_TEMPLATE_CONTROL ( GuiBindableTextList, TextList ); ADD_TEMPLATE_CONTROL ( GuiListView, ListView ); ADD_TEMPLATE_CONTROL ( GuiBindableListView, ListView ); ADD_TEMPLATE_CONTROL ( GuiBindableDataGrid, ListView ); ADD_TEMPLATE_CONTROL ( GuiMultilineTextBox, MultilineTextBox ); ADD_TEMPLATE_CONTROL ( GuiSinglelineTextBox, SinglelineTextBox ); ADD_TEMPLATE_CONTROL ( GuiDatePicker, DatePicker ); ADD_TEMPLATE_CONTROL ( GuiDateComboBox, DateComboBox ); ADD_TEMPLATE_CONTROL ( GuiRibbonTab, RibbonTab ); ADD_TEMPLATE_CONTROL ( GuiRibbonTabPage, CustomControl ); ADD_TEMPLATE_CONTROL ( GuiRibbonGroup, RibbonGroup ); ADD_TEMPLATE_CONTROL ( GuiRibbonIconLabel, RibbonIconLabel ); ADD_TEMPLATE_CONTROL ( GuiRibbonToolstrips, RibbonToolstrips ); ADD_TEMPLATE_CONTROL ( GuiRibbonGallery, RibbonGallery ); ADD_TEMPLATE_CONTROL ( GuiBindableRibbonGalleryList, RibbonGalleryList ); /* VIRTUAL-CONTROL-TYPE REAL-CONTROL-TYPE THEME-NAME */ ADD_VIRTUAL_CONTROL (GroupBox, GuiControl, GroupBox ); ADD_VIRTUAL_CONTROL (MenuSplitter, GuiControl, MenuSplitter ); ADD_VIRTUAL_CONTROL (MenuBarButton, GuiToolstripButton, MenuBarButton ); ADD_VIRTUAL_CONTROL (MenuItemButton, GuiToolstripButton, MenuItemButton ); ADD_VIRTUAL_CONTROL (ToolstripToolBarInMenu, GuiToolstripToolBar, ToolstripToolBarInMenu ); ADD_VIRTUAL_CONTROL (ToolstripDropdownButton, GuiToolstripButton, ToolstripDropdownButton ); ADD_VIRTUAL_CONTROL (ToolstripSplitButton, GuiToolstripButton, ToolstripSplitButton ); ADD_VIRTUAL_CONTROL (ToolstripSplitter, GuiControl, ToolstripSplitter ); ADD_VIRTUAL_CONTROL (ToolstripSplitterInMenu, GuiControl, ToolstripSplitterInMenu ); ADD_VIRTUAL_CONTROL (RibbonSmallButton, GuiToolstripButton, RibbonSmallButton ); ADD_VIRTUAL_CONTROL (RibbonSmallDropdownButton, GuiToolstripButton, RibbonSmallDropdownButton ); ADD_VIRTUAL_CONTROL (RibbonSmallSplitButton, GuiToolstripButton, RibbonSmallSplitButton ); ADD_VIRTUAL_CONTROL (RibbonLargeButton, GuiToolstripButton, RibbonLargeButton ); ADD_VIRTUAL_CONTROL (RibbonLargeDropdownButton, GuiToolstripButton, RibbonLargeDropdownButton ); ADD_VIRTUAL_CONTROL (RibbonLargeSplitButton, GuiToolstripButton, RibbonLargeSplitButton ); ADD_VIRTUAL_CONTROL (RibbonSmallIconLabel, GuiRibbonIconLabel, RibbonSmallIconLabel ); ADD_VIRTUAL_CONTROL (RibbonSplitter, GuiControl, RibbonSplitter ); ADD_VIRTUAL_CONTROL (RibbonToolstripHeader, GuiControl, RibbonToolstripHeader ); ADD_VIRTUAL_CONTROL (CheckBox, GuiSelectableButton, CheckBox ); ADD_VIRTUAL_CONTROL (RadioButton, GuiSelectableButton, RadioButton ); ADD_VIRTUAL_CONTROL (HScroll, GuiScroll, HScroll ); ADD_VIRTUAL_CONTROL (VScroll, GuiScroll, VScroll ); ADD_VIRTUAL_CONTROL_F (HTracker, GuiScroll, HTracker, InitializeTrackerProgressBar); ADD_VIRTUAL_CONTROL_F (VTracker, GuiScroll, VTracker, InitializeTrackerProgressBar); ADD_VIRTUAL_CONTROL_F (ProgressBar, GuiScroll, ProgressBar, InitializeTrackerProgressBar); LoadToolstripControls(manager); LoadListControls(manager); LoadDocumentControls(manager); LoadCompositions(manager); LoadTemplates(manager); } #undef ADD_TEMPLATE_CONTROL #undef ADD_VIRTUAL_CONTROL #undef ADD_VIRTUAL_CONTROL_F #endif } void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { } }; GUI_REGISTER_PLUGIN(GuiPredefinedInstanceLoadersPlugin) } } } /*********************************************************************** .\INSTANCELOADERS\GUIINSTANCELOADER_TEMPLATES.CPP ***********************************************************************/ #ifndef VCZH_DEBUG_NO_REFLECTION namespace vl { namespace presentation { namespace instance_loaders { /*********************************************************************** GuiCommonDatePickerLookLoader ***********************************************************************/ class GuiCommonDatePickerLookLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; GlobalStringKey _BackgroundColor; GlobalStringKey _PrimaryTextColor; GlobalStringKey _SecondaryTextColor; public: GuiCommonDatePickerLookLoader() { typeName = GlobalStringKey::Get(description::TypeInfo<GuiCommonDatePickerLook>::content.typeName); _BackgroundColor = GlobalStringKey::Get(L"BackgroundColor"); _PrimaryTextColor = GlobalStringKey::Get(L"PrimaryTextColor"); _SecondaryTextColor = GlobalStringKey::Get(L"SecondaryTextColor"); } GlobalStringKey GetTypeName()override { return typeName; } void GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { if (CanCreate(typeInfo)) { propertyNames.Add(_BackgroundColor); propertyNames.Add(_PrimaryTextColor); propertyNames.Add(_SecondaryTextColor); } } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _BackgroundColor || propertyInfo.propertyName == _PrimaryTextColor || propertyInfo.propertyName == _SecondaryTextColor) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<Color>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } bool CanCreate(const TypeInfo& typeInfo)override { return typeInfo.typeName == typeName; } Ptr<workflow::WfStatement> CreateInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos tagPosition, GuiResourceError::List& errors)override { if (CanCreate(typeInfo)) { vint indexBackgroundColor = arguments.Keys().IndexOf(_BackgroundColor); vint indexPrimaryTextColor = arguments.Keys().IndexOf(_PrimaryTextColor); vint indexSecondaryTextColor = arguments.Keys().IndexOf(_SecondaryTextColor); if (indexBackgroundColor != -1 && indexPrimaryTextColor != -1 && indexSecondaryTextColor != -1) { auto type = TypeInfoRetriver<GuiCommonDatePickerLook*>::CreateTypeInfo(); auto createExpr = Ptr(new WfNewClassExpression); createExpr->type = GetTypeFromTypeInfo(type.Obj()); createExpr->arguments.Add(arguments.GetByIndex(indexBackgroundColor)[0].expression); createExpr->arguments.Add(arguments.GetByIndex(indexPrimaryTextColor)[0].expression); createExpr->arguments.Add(arguments.GetByIndex(indexSecondaryTextColor)[0].expression); auto refVariable = Ptr(new WfReferenceExpression); refVariable->name.value = variableName.ToString(); auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->op = WfBinaryOperator::Assign; assignExpr->first = refVariable; assignExpr->second = createExpr; auto assignStat = Ptr(new WfExpressionStatement); assignStat->expression = assignExpr; return assignStat; } } return nullptr; } }; /*********************************************************************** GuiCommonScrollViewLookLoader ***********************************************************************/ class GuiCommonScrollViewLookLoader : public Object, public IGuiInstanceLoader { protected: GlobalStringKey typeName; GlobalStringKey _DefaultScrollSize; public: GuiCommonScrollViewLookLoader() { typeName = GlobalStringKey::Get(description::TypeInfo<GuiCommonScrollViewLook>::content.typeName); _DefaultScrollSize = GlobalStringKey::Get(L"DefaultScrollSize"); } GlobalStringKey GetTypeName()override { return typeName; } void GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { if (CanCreate(typeInfo)) { propertyNames.Add(_DefaultScrollSize); } } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _DefaultScrollSize) { Ptr<GuiInstancePropertyInfo> info; switch (precompileContext.targetCpuArchitecture) { case GuiResourceCpuArchitecture::x86: info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<vint32_t>::CreateTypeInfo()); break; case GuiResourceCpuArchitecture::x64: info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<vint64_t>::CreateTypeInfo()); break; default: CHECK_FAIL(L"The target CPU architecture is unspecified."); } info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } bool CanCreate(const TypeInfo& typeInfo)override { return typeInfo.typeName == typeName; } Ptr<workflow::WfStatement> CreateInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos tagPosition, GuiResourceError::List& errors)override { if (CanCreate(typeInfo)) { vint indexDefaultScrollSize = arguments.Keys().IndexOf(_DefaultScrollSize); if (indexDefaultScrollSize != -1) { auto type = TypeInfoRetriver<GuiCommonScrollViewLook*>::CreateTypeInfo(); auto createExpr = Ptr(new WfNewClassExpression); createExpr->type = GetTypeFromTypeInfo(type.Obj()); createExpr->arguments.Add(arguments.GetByIndex(indexDefaultScrollSize)[0].expression); auto refVariable = Ptr(new WfReferenceExpression); refVariable->name.value = variableName.ToString(); auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->op = WfBinaryOperator::Assign; assignExpr->first = refVariable; assignExpr->second = createExpr; auto assignStat = Ptr(new WfExpressionStatement); assignStat->expression = assignExpr; return assignStat; } } return nullptr; } }; /*********************************************************************** Initialization ***********************************************************************/ void LoadTemplates(IGuiInstanceLoaderManager* manager) { manager->SetLoader(Ptr(new GuiCommonDatePickerLookLoader)); manager->SetLoader(Ptr(new GuiCommonScrollViewLookLoader)); } } } } #endif /*********************************************************************** .\INSTANCELOADERS\GUIINSTANCELOADER_TOOLSTRIP.CPP ***********************************************************************/ #ifndef VCZH_DEBUG_NO_REFLECTION namespace vl { namespace presentation { namespace instance_loaders { Ptr<workflow::WfStatement> AddControlToToolstrip(GlobalStringKey variableName, IGuiInstanceLoader::ArgumentMap& arguments, GuiResourceError::List& errors) { auto block = Ptr(new WfBlockStatement); // TODO: (enumerable) foreach on group for (auto [prop, index] : indexed(arguments.Keys())) { const auto& values = arguments.GetByIndex(index); if (prop == GlobalStringKey::Empty) { auto value = values[0].expression; auto td = values[0].typeInfo->GetTypeDescriptor(); Ptr<WfExpression> expr; if (td->CanConvertTo(description::GetTypeDescriptor<GuiControl>())) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refToolstripItems = Ptr(new WfMemberExpression); refToolstripItems->parent = refControl; refToolstripItems->name.value = L"ToolstripItems"; auto refAdd = Ptr(new WfMemberExpression); refAdd->parent = refToolstripItems; refAdd->name.value = L"Add"; auto call = Ptr(new WfCallExpression); call->function = refAdd; call->arguments.Add(value); expr = call; } if (expr) { auto stat = Ptr(new WfExpressionStatement); stat->expression = expr; block->statements.Add(stat); } } } if (block->statements.Count() > 0) { return block; } return nullptr; } /*********************************************************************** GuiToolstripInstanceLoaderBase ***********************************************************************/ template<typename TBaseType> class GuiToolstripInstanceLoaderBase : public TBaseType { private: using TypeInfo = typename TBaseType::TypeInfo; public: using ArgumentMap = IGuiInstanceLoader::ArgumentMap; using PropertyInfo = IGuiInstanceLoader::PropertyInfo; GuiToolstripInstanceLoaderBase(const WString& _typeName, theme::ThemeName themeName, Ptr<WfExpression>(*_argumentFunction)(ArgumentMap&)) :TBaseType(_typeName, themeName, _argumentFunction) { } GuiToolstripInstanceLoaderBase(const WString& _typeName, theme::ThemeName themeName) :TBaseType(_typeName, themeName) { } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(GlobalStringKey::Empty); TBaseType::GetPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == GlobalStringKey::Empty) { return GuiInstancePropertyInfo::CollectionWithParent(TypeInfoRetriver<GuiControl*>::CreateTypeInfo()); } return TBaseType::GetPropertyType(precompileContext, propertyInfo); } Ptr<workflow::WfStatement> AssignParameters(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { if (auto statement = AddControlToToolstrip(variableName, arguments, errors)) { return statement; } else { return TBaseType::AssignParameters(precompileContext, resolvingResult, typeInfo, variableName, arguments, attPosition, errors); } } }; /*********************************************************************** GuiToolstripMenuInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiToolstripMenu> class GuiToolstripMenuInstanceLoader : public GuiToolstripInstanceLoaderBase<BASE_TYPE> { public: static Ptr<WfExpression> ArgumentFunction(ArgumentMap&) { auto expr = Ptr(new WfLiteralExpression); expr->value = WfLiteralValue::Null; return expr; } public: GuiToolstripMenuInstanceLoader() :GuiToolstripInstanceLoaderBase<BASE_TYPE>(description::TypeInfo<GuiToolstripMenu>::content.typeName, theme::ThemeName::Menu, ArgumentFunction) { } }; #undef BASE_TYPE /*********************************************************************** GuiToolstripMenuBarInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiToolstripMenuBar> class GuiToolstripMenuBarInstanceLoader : public GuiToolstripInstanceLoaderBase<BASE_TYPE> { public: GuiToolstripMenuBarInstanceLoader() :GuiToolstripInstanceLoaderBase<BASE_TYPE>(description::TypeInfo<GuiToolstripMenuBar>::content.typeName, theme::ThemeName::MenuBar) { } }; #undef BASE_TYPE /*********************************************************************** GuiToolstripToolBarInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiToolstripToolBar> class GuiToolstripToolBarInstanceLoader : public GuiToolstripInstanceLoaderBase<BASE_TYPE> { public: GuiToolstripToolBarInstanceLoader() :GuiToolstripInstanceLoaderBase<BASE_TYPE>(description::TypeInfo<GuiToolstripToolBar>::content.typeName, theme::ThemeName::ToolstripToolBar) { } }; #undef BASE_TYPE /*********************************************************************** GuiToolstripGroupContainerInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiToolstripGroupContainer> class GuiToolstripGroupContainerInstanceLoader : public GuiToolstripInstanceLoaderBase<BASE_TYPE> { public: GuiToolstripGroupContainerInstanceLoader() :GuiToolstripInstanceLoaderBase<BASE_TYPE>(description::TypeInfo<GuiToolstripGroupContainer>::content.typeName, theme::ThemeName::CustomControl) { } }; #undef BASE_TYPE /*********************************************************************** GuiToolstripGroupInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiToolstripGroup> class GuiToolstripGroupInstanceLoader : public GuiToolstripInstanceLoaderBase<BASE_TYPE> { public: GuiToolstripGroupInstanceLoader() :GuiToolstripInstanceLoaderBase<BASE_TYPE>(description::TypeInfo<GuiToolstripGroup>::content.typeName, theme::ThemeName::CustomControl) { } }; #undef BASE_TYPE /*********************************************************************** GuiToolstripButtonInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiToolstripButton> class GuiToolstripButtonInstanceLoader : public BASE_TYPE { protected: GlobalStringKey _SubMenu; public: GuiToolstripButtonInstanceLoader() :BASE_TYPE(description::TypeInfo<GuiToolstripButton>::content.typeName, theme::ThemeName::ToolstripButton) { _SubMenu = GlobalStringKey::Get(L"SubMenu"); } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { propertyNames.Add(_SubMenu); BASE_TYPE::GetPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _SubMenu) { return GuiInstancePropertyInfo::Set(TypeInfoRetriver<GuiToolstripMenu*>::CreateTypeInfo()); } return BASE_TYPE::GetPropertyType(precompileContext, propertyInfo); } Ptr<workflow::WfExpression> GetParameter(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const PropertyInfo& propertyInfo, GlobalStringKey variableName, GuiResourceTextPos attPosition, GuiResourceError::List& errors)override { if (propertyInfo.propertyName == _SubMenu) { auto refControl = Ptr(new WfReferenceExpression); refControl->name.value = variableName.ToString(); auto refEnsureToolstripSubMenu = Ptr(new WfMemberExpression); refEnsureToolstripSubMenu->parent = refControl; refEnsureToolstripSubMenu->name.value = L"EnsureToolstripSubMenu"; auto call = Ptr(new WfCallExpression); call->function = refEnsureToolstripSubMenu; return call; } return BASE_TYPE::GetParameter(precompileContext, resolvingResult, propertyInfo, variableName, attPosition, errors); } }; #undef BASE_TYPE /*********************************************************************** GuiRibbonToolstripMenuInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiRibbonToolstripMenu> class GuiRibbonToolstripMenuInstanceLoader : public GuiToolstripInstanceLoaderBase<BASE_TYPE> { public: static Ptr<WfExpression> ArgumentFunction(ArgumentMap&) { auto expr = Ptr(new WfLiteralExpression); expr->value = WfLiteralValue::Null; return expr; } public: GuiRibbonToolstripMenuInstanceLoader() :GuiToolstripInstanceLoaderBase<BASE_TYPE>(description::TypeInfo<GuiRibbonToolstripMenu>::content.typeName, theme::ThemeName::RibbonToolstripMenu, ArgumentFunction) { } }; #undef BASE_TYPE /*********************************************************************** GuiRibbonButtonsInstanceLoader ***********************************************************************/ #define BASE_TYPE GuiTemplateControlInstanceLoader<GuiRibbonButtons> class GuiRibbonButtonsInstanceLoader : public BASE_TYPE { protected: GlobalStringKey _MaxSize; GlobalStringKey _MinSize; void AddAdditionalArguments(types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceError::List& errors, Ptr<WfNewClassExpression> createControl)override { vint indexMaxSize = arguments.Keys().IndexOf(_MaxSize); vint indexMinSize = arguments.Keys().IndexOf(_MinSize); if (indexMaxSize != -1 && indexMinSize != -1) { createControl->arguments.Add(arguments.GetByIndex(indexMaxSize)[0].expression); createControl->arguments.Add(arguments.GetByIndex(indexMinSize)[0].expression); } } public: GuiRibbonButtonsInstanceLoader() :BASE_TYPE(description::TypeInfo<GuiRibbonButtons>::content.typeName, theme::ThemeName::RibbonButtons) { _MaxSize = GlobalStringKey::Get(L"MaxSize"); _MinSize = GlobalStringKey::Get(L"MinSize"); } void GetRequiredPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { if (CanCreate(typeInfo)) { propertyNames.Add(_MaxSize); propertyNames.Add(_MinSize); } } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)override { GetRequiredPropertyNames(precompileContext, typeInfo, propertyNames); } Ptr<GuiInstancePropertyInfo> GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)override { if (propertyInfo.propertyName == _MaxSize || propertyInfo.propertyName == _MinSize) { auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver<RibbonButtonSize>::CreateTypeInfo()); info->usage = GuiInstancePropertyInfo::ConstructorArgument; return info; } return IGuiInstanceLoader::GetPropertyType(precompileContext, propertyInfo); } }; #undef BASE_TYPE /*********************************************************************** Initialization ***********************************************************************/ void LoadToolstripControls(IGuiInstanceLoaderManager* manager) { manager->SetLoader(Ptr(new GuiToolstripMenuInstanceLoader)); manager->SetLoader(Ptr(new GuiToolstripMenuBarInstanceLoader)); manager->SetLoader(Ptr(new GuiToolstripToolBarInstanceLoader)); manager->SetLoader(Ptr(new GuiToolstripGroupContainerInstanceLoader)); manager->SetLoader(Ptr(new GuiToolstripGroupInstanceLoader)); manager->SetLoader(Ptr(new GuiToolstripButtonInstanceLoader)); manager->SetLoader(Ptr(new GuiRibbonButtonsInstanceLoader)); manager->SetLoader(Ptr(new GuiRibbonToolstripMenuInstanceLoader)); } } } } #endif /*********************************************************************** .\INSTANCEQUERY\GUIINSTANCEQUERY.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace instancequery; /*********************************************************************** ExecuteQueryVisitor ***********************************************************************/ class ExecuteQueryVisitor : public Object, public GuiIqQuery::IVisitor { public: Ptr<GuiInstanceContext> context; List<Ptr<GuiConstructorRepr>>& input; List<Ptr<GuiConstructorRepr>>& output; ExecuteQueryVisitor(Ptr<GuiInstanceContext> _context, List<Ptr<GuiConstructorRepr>>& _input, List<Ptr<GuiConstructorRepr>>& _output) :context(_context), input(_input), output(_output) { } static bool TestCtor(GuiIqPrimaryQuery* node, GlobalStringKey attribute, Ptr<GuiConstructorRepr> ctor) { if (node->attributeNameOption == GuiIqNameOption::Specified && node->attributeName.value != attribute.ToString()) { return false; } if (node->typeNameOption == GuiIqNameOption::Specified && node->typeName.value != ctor->typeName.ToString()) { return false; } if (node->referenceName.value != L"") { bool instanceName = ctor->instanceName != GlobalStringKey::Empty && node->referenceName.value == ctor->instanceName.ToString(); bool styleName = ctor->styleName && node->referenceName.value == ctor->styleName.Value(); return instanceName || styleName; } return true; } void Traverse(GuiIqPrimaryQuery* node, Ptr<GuiAttSetterRepr> setter) { if (setter) { // TODO: (enumerable) foreach on group for (auto [attribute, index] : indexed(setter->setters.Keys())) { auto setterValue = setter->setters.Values()[index]; for (auto value : setterValue->values) { if (auto ctor = value.Cast<GuiConstructorRepr>()) { if (TestCtor(node, attribute, ctor)) { output.Add(ctor); } } if (node->childOption == GuiIqChildOption::Indirect) { if (auto setter = value.Cast<GuiAttSetterRepr>()) { Traverse(node, setter); } } } } } else { if (TestCtor(node, GlobalStringKey::Empty, context->instance)) { output.Add(context->instance); } if (node->childOption == GuiIqChildOption::Indirect) { Traverse(node, context->instance); } } } void Visit(GuiIqPrimaryQuery* node)override { auto inputExists = &input; if (inputExists) { for (auto setter : input) { Traverse(node, setter); } } else { Traverse(node, 0); } } void Visit(GuiIqCascadeQuery* node)override { List<Ptr<GuiConstructorRepr>> temp; ExecuteQuery(node->parent, context, input, temp); ExecuteQuery(node->child, context, temp, output); } void Visit(GuiIqSetQuery* node)override { List<Ptr<GuiConstructorRepr>> first, second; ExecuteQuery(node->first, context, input, first); ExecuteQuery(node->second, context, input, second); switch (node->op) { case GuiIqBinaryOperator::ExclusiveOr: CopyFrom(output, From(first).Except(second).Union(From(second).Except(second))); break; case GuiIqBinaryOperator::Intersect: CopyFrom(output, From(first).Intersect(second)); break; case GuiIqBinaryOperator::Union: CopyFrom(output, From(first).Union(second)); break; case GuiIqBinaryOperator::Substract: CopyFrom(output, From(first).Except(second)); break; default:; } } }; /*********************************************************************** ExecuteQuery ***********************************************************************/ void ExecuteQuery(Ptr<GuiIqQuery> query, Ptr<GuiInstanceContext> context, collections::List<Ptr<GuiConstructorRepr>>& input, collections::List<Ptr<GuiConstructorRepr>>& output) { ExecuteQueryVisitor visitor(context, input, output); query->Accept(&visitor); } void ExecuteQuery(Ptr<GuiIqQuery> query, Ptr<GuiInstanceContext> context, collections::List<Ptr<GuiConstructorRepr>>& output) { #if defined(VCZH_GCC) && defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnull-dereference" #endif ExecuteQuery(query, context, *(List<Ptr<GuiConstructorRepr>>*)0, output); #if defined(VCZH_GCC) && defined(__clang__) #pragma clang diagnostic pop #endif } /*********************************************************************** ApplyStyle ***********************************************************************/ void ApplyStyleInternal(Ptr<GuiAttSetterRepr> src, Ptr<GuiAttSetterRepr> dst) { // TODO: (enumerable) foreach on dictionary for (auto [attribute, srcIndex] : indexed(src->setters.Keys())) { auto srcValue = src->setters.Values()[srcIndex]; vint dstIndex = dst->setters.Keys().IndexOf(attribute); if (dstIndex == -1) { dst->setters.Add(attribute, srcValue); } else { auto dstValue = dst->setters.Values()[dstIndex]; if (srcValue->binding == dstValue->binding) { if (srcValue->binding == GlobalStringKey::_Set) { ApplyStyleInternal(srcValue->values[0].Cast<GuiAttSetterRepr>(), dstValue->values[0].Cast<GuiAttSetterRepr>()); } else { CopyFrom(dstValue->values, srcValue->values, true); } } } } // TODO: (enumerable) foreach for (auto [eventName, srcIndex] : indexed(src->eventHandlers.Keys())) { if (!dst->eventHandlers.Keys().Contains(eventName)) { auto srcValue = src->eventHandlers.Values()[srcIndex]; dst->eventHandlers.Add(eventName, srcValue); } } // TODO: (enumerable) foreach for (auto [varName, srcIndex] : indexed(src->environmentVariables.Keys())) { if (!dst->environmentVariables.Keys().Contains(varName)) { auto srcValue = src->environmentVariables.Values()[srcIndex]; dst->environmentVariables.Add(varName, srcValue); } } } void ApplyStyle(Ptr<GuiInstanceStyle> style, Ptr<GuiConstructorRepr> ctor) { ApplyStyleInternal(style->setter->Clone().Cast<GuiAttSetterRepr>(), ctor); } /*********************************************************************** GuiIqPrint ***********************************************************************/ class GuiIqPrintVisitor : public Object, public GuiIqQuery::IVisitor { public: stream::StreamWriter& writer; GuiIqPrintVisitor(stream::StreamWriter& _writer) :writer(_writer) { } void Visit(GuiIqPrimaryQuery* node)override { switch (node->childOption) { case GuiIqChildOption::Direct: writer.WriteString(L"/"); break; case GuiIqChildOption::Indirect: writer.WriteString(L"//"); break; default:; } if (node->attributeNameOption == GuiIqNameOption::Specified) { writer.WriteChar(L'@'); writer.WriteString(node->attributeName.value); writer.WriteChar(L':'); } if (node->typeNameOption == GuiIqNameOption::Specified) { writer.WriteString(node->typeName.value); } else { writer.WriteChar(L'*'); } if (node->referenceName.value != L"") { writer.WriteChar(L'.'); writer.WriteString(node->referenceName.value); } } void Visit(GuiIqCascadeQuery* node)override { node->parent->Accept(this); node->child->Accept(this); } void Visit(GuiIqSetQuery* node)override { writer.WriteChar(L'('); node->first->Accept(this); switch (node->op) { case GuiIqBinaryOperator::ExclusiveOr: writer.WriteString(L" ^ "); break; case GuiIqBinaryOperator::Intersect: writer.WriteString(L" * "); break; case GuiIqBinaryOperator::Union: writer.WriteString(L" + "); break; case GuiIqBinaryOperator::Substract: writer.WriteString(L" - "); break; default:; } node->second->Accept(this); writer.WriteChar(L')'); } }; void GuiIqPrint(Ptr<GuiIqQuery> query, stream::StreamWriter& writer) { GuiIqPrintVisitor visitor(writer); query->Accept(&visitor); } } } /*********************************************************************** .\INSTANCEQUERY\GENERATED\GUIINSTANCEQUERYAST.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:Ast Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::instancequery { /*********************************************************************** Visitor Pattern Implementation ***********************************************************************/ void GuiIqPrimaryQuery::Accept(GuiIqQuery::IVisitor* visitor) { visitor->Visit(this); } void GuiIqCascadeQuery::Accept(GuiIqQuery::IVisitor* visitor) { visitor->Visit(this); } void GuiIqSetQuery::Accept(GuiIqQuery::IVisitor* visitor) { visitor->Visit(this); } } namespace vl::reflection::description { #ifndef VCZH_DEBUG_NO_REFLECTION IMPL_TYPE_INFO_RENAME(vl::presentation::instancequery::GuiIqQuery, presentation::instancequery::GuiIqQuery) IMPL_TYPE_INFO_RENAME(vl::presentation::instancequery::GuiIqQuery::IVisitor, presentation::instancequery::GuiIqQuery::IVisitor) IMPL_TYPE_INFO_RENAME(vl::presentation::instancequery::GuiIqNameOption, presentation::instancequery::GuiIqNameOption) IMPL_TYPE_INFO_RENAME(vl::presentation::instancequery::GuiIqChildOption, presentation::instancequery::GuiIqChildOption) IMPL_TYPE_INFO_RENAME(vl::presentation::instancequery::GuiIqPrimaryQuery, presentation::instancequery::GuiIqPrimaryQuery) IMPL_TYPE_INFO_RENAME(vl::presentation::instancequery::GuiIqCascadeQuery, presentation::instancequery::GuiIqCascadeQuery) IMPL_TYPE_INFO_RENAME(vl::presentation::instancequery::GuiIqBinaryOperator, presentation::instancequery::GuiIqBinaryOperator) IMPL_TYPE_INFO_RENAME(vl::presentation::instancequery::GuiIqSetQuery, presentation::instancequery::GuiIqSetQuery) #ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA BEGIN_CLASS_MEMBER(vl::presentation::instancequery::GuiIqQuery) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) END_CLASS_MEMBER(vl::presentation::instancequery::GuiIqQuery) BEGIN_ENUM_ITEM(vl::presentation::instancequery::GuiIqNameOption) ENUM_ITEM_NAMESPACE(vl::presentation::instancequery::GuiIqNameOption) ENUM_NAMESPACE_ITEM(Specified) ENUM_NAMESPACE_ITEM(Any) END_ENUM_ITEM(vl::presentation::instancequery::GuiIqNameOption) BEGIN_ENUM_ITEM(vl::presentation::instancequery::GuiIqChildOption) ENUM_ITEM_NAMESPACE(vl::presentation::instancequery::GuiIqChildOption) ENUM_NAMESPACE_ITEM(Direct) ENUM_NAMESPACE_ITEM(Indirect) END_ENUM_ITEM(vl::presentation::instancequery::GuiIqChildOption) BEGIN_CLASS_MEMBER(vl::presentation::instancequery::GuiIqPrimaryQuery) CLASS_MEMBER_BASE(vl::presentation::instancequery::GuiIqQuery) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::instancequery::GuiIqPrimaryQuery>(), NO_PARAMETER) CLASS_MEMBER_FIELD(childOption) CLASS_MEMBER_FIELD(attributeNameOption) CLASS_MEMBER_FIELD(attributeName) CLASS_MEMBER_FIELD(typeNameOption) CLASS_MEMBER_FIELD(typeName) CLASS_MEMBER_FIELD(referenceName) END_CLASS_MEMBER(vl::presentation::instancequery::GuiIqPrimaryQuery) BEGIN_CLASS_MEMBER(vl::presentation::instancequery::GuiIqCascadeQuery) CLASS_MEMBER_BASE(vl::presentation::instancequery::GuiIqQuery) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::instancequery::GuiIqCascadeQuery>(), NO_PARAMETER) CLASS_MEMBER_FIELD(parent) CLASS_MEMBER_FIELD(child) END_CLASS_MEMBER(vl::presentation::instancequery::GuiIqCascadeQuery) BEGIN_ENUM_ITEM(vl::presentation::instancequery::GuiIqBinaryOperator) ENUM_ITEM_NAMESPACE(vl::presentation::instancequery::GuiIqBinaryOperator) ENUM_NAMESPACE_ITEM(ExclusiveOr) ENUM_NAMESPACE_ITEM(Intersect) ENUM_NAMESPACE_ITEM(Union) ENUM_NAMESPACE_ITEM(Substract) END_ENUM_ITEM(vl::presentation::instancequery::GuiIqBinaryOperator) BEGIN_CLASS_MEMBER(vl::presentation::instancequery::GuiIqSetQuery) CLASS_MEMBER_BASE(vl::presentation::instancequery::GuiIqQuery) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::instancequery::GuiIqSetQuery>(), NO_PARAMETER) CLASS_MEMBER_FIELD(first) CLASS_MEMBER_FIELD(second) CLASS_MEMBER_FIELD(op) END_CLASS_MEMBER(vl::presentation::instancequery::GuiIqSetQuery) BEGIN_INTERFACE_MEMBER(vl::presentation::instancequery::GuiIqQuery::IVisitor) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::instancequery::GuiIqQuery::IVisitor::*)(vl::presentation::instancequery::GuiIqPrimaryQuery* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::instancequery::GuiIqQuery::IVisitor::*)(vl::presentation::instancequery::GuiIqCascadeQuery* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::instancequery::GuiIqQuery::IVisitor::*)(vl::presentation::instancequery::GuiIqSetQuery* node)) END_INTERFACE_MEMBER(vl::presentation::instancequery::GuiIqQuery) #endif #ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA class GuiInstanceQueryAstTypeLoader : public vl::Object, public ITypeLoader { public: void Load(ITypeManager* manager) { ADD_TYPE_INFO(vl::presentation::instancequery::GuiIqQuery) ADD_TYPE_INFO(vl::presentation::instancequery::GuiIqQuery::IVisitor) ADD_TYPE_INFO(vl::presentation::instancequery::GuiIqNameOption) ADD_TYPE_INFO(vl::presentation::instancequery::GuiIqChildOption) ADD_TYPE_INFO(vl::presentation::instancequery::GuiIqPrimaryQuery) ADD_TYPE_INFO(vl::presentation::instancequery::GuiIqCascadeQuery) ADD_TYPE_INFO(vl::presentation::instancequery::GuiIqBinaryOperator) ADD_TYPE_INFO(vl::presentation::instancequery::GuiIqSetQuery) } void Unload(ITypeManager* manager) { } }; #endif #endif bool GuiInstanceQueryAstLoadTypes() { #ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA if (auto manager = GetGlobalTypeManager()) { auto loader = Ptr(new GuiInstanceQueryAstTypeLoader); return manager->AddTypeLoader(loader); } #endif return false; } } /*********************************************************************** .\INSTANCEQUERY\GENERATED\GUIINSTANCEQUERYPARSER.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:GuiInstanceQuery Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::instancequery { void GuiInstanceQueryParserData(vl::stream::IStream& outputStream) { static const vl::vint dataLength = 2815; // 27722 bytes before compressing static const vl::vint dataBlock = 256; static const vl::vint dataRemain = 255; static const vl::vint dataSolidRows = 10; static const vl::vint dataRows = 11; static const char* compressed[] = { "\x4A\x6C\x00\x00\xF7\x0A\x00\x00\x0D\x00\x01\x82\x80\x07\x03\x82\x81\x82\x06\x89\x82\x88\x0A\x87\x06\x84\x0C\x0A\x9D\x0A\x86\x1A\x87\x16\x84\x77\x02\x09\xBF\x7B\x8C\x8B\x8E\x84\x00\x1D\x9D\x9F\x81\x9C\x8B\x90\x93\x7F\x1F\x9F\x81\x0A\x8B\x91\x85\x96\x83\x27\xA8\x8A\x91\x96\x94\x91\x9B\x90\x37\xA2\xB3\x87\x99\x9D\x93\x9C\x9B\x3F\xB8\x81\xBA\x9A\x8C\x9F\xA0\x9F\x45\xC0\x89\xA2\xAB\xA4\xA0\x98\xA3\x4D\xC8\x8F\xAA\xA3\xAC\xA5\xAA\xA7\x03\xB4\x87\xBE\x8B\xAA\x99\xA8\xAE\x09\x99\xAE\x9D\xAD\x98\xB3\xAA\xA9\x59\xD0\xA7\xA6\xB9\xB4\xA9\xB6\xAB\x6F\xD8\x82\x9A\xAF\xAE\xAF\xB4\xBB\x71\xE8\x82\x83\x0C\x94\xB2\xBF\xBA\x65\xF8\xB3\xAA\xB3\x84\x01\xBE\xC0\x7F\xF7\x81\xCB\xC9\xC1\xBC\xB7\xC1\x6E\x90\xF0\xB2\xC2\xB9\x81\x03\xC3\x8A\x8D\xD4\xDA\xB1\x84\xB9\xCC\xC4\xA0\x9F\xE2\xCE\xC2\xC5\xCC\xC3\xCD\x8F\xA6\xD1\xCA\xD3\xC9\x82\x02\xCC\xA4\x8C\xE1\xD1\xDA\xCC\xD5\xCA\x90\xA7\xB6\xDC\xD8\xDB\xD4\xDD\xD6\xDF\xB7\x9E\xC3\x88\x86\x87\x94\xDB\xD9\xA8\xA5\xC0\xFB\xD2\xE3\x84\xD9\xE4\xB2\xA3\xD0\xF5\xDB\xE1\xD5\xEA\xE5\xCD\xBA\xD6\xF9", "\xE0\x01\x07\xE6\xED\xD8\xB9\xD7\xF1\xE7\xE2\xE8\xF0\xF2\xD3\xC8\xE7\xF4\xEC\xED\xF6\xF0\xF7\xBD\xDC\xCA\x1F\xE0\x03\x04\xFA\xF8\xBF\xF8\xC1\xE2\xFC\x07\xFB\xF7\xFF\xF1\x40\x89\x7E\x80\xFB\x41\x86\x83\x80\x07\x85\x88\x83\x82\x0A\x8D\x8C\x72\x78\x00\x63\x5A\x7B\x78\xEC\x44\x8F\x81\x82\x17\x8C\x89\x86\x83\xDB\x56\x8D\x84\x86\x1F\x9A\x81\x8B\x6D\x0E\x3E\x70\x89\x78\x27\xA8\x7B\x7B\x84\x0E\x52\x86\x78\x85\x13\xBA\x7B\x87\x8C\x23\xB4\x88\x8A\x88\x37\x9C\x89\x8F\x6E\x10\x26\x88\x8F\x47\x11\x3E\x8A\x8E\x8A\x30\xAF\x82\x8D\x8D\x48\xBB\x89\x90\x91\x47\x8A\x9E\x90\x93\xE2\x52\x04\x7F\x04\x42\xB6\x80\x95\x8A\x15\x98\x91\x8E\x87\xCA\x54\x04\x7D\x05\x55\x8B\x9A\x42\x05\x61\x8F\x99\x97\x8F\x67\x83\x99\x9A\x95\x6B\xA2\x9B\x96\x96\x46\x9C\x97\x94\x9A\x09\x57\x05\x9B\x9C\x6A\xAF\x94\x9D\x9C\x70\xA5\x7E\x9D\x7A\x7C\xBB\x9F\x9F\x8A\x81\xB9\x96\x40\x44\x2E\x83\xA5\x92\xA2\x4D\xB8\x9C\x9B\x84\x19\x34\x7A\x07\x9D\xD4\x5B\x04\xA6\x9E\x86\x8C\xA2\x9C\x75\x1C\x17\xA5\xA3\xA3\x9F\xAE\x91\xAA\x99\x98\xA0\xAA\xA5\x9F\x80\x8A\xA2\x45\xA2", "\x02\x5E\x0E\xA7\xA9\x82\xA9\xA2\x43\x07\xAF\xB2\xA4\xA3\x40\x20\x35\xA7\xAE\xAD\x8B\xBC\xAD\xA1\x9B\xA4\xA3\xAE\xA2\xA8\xB0\x99\xA2\x41\x08\xF4\x62\x0A\xAD\xAF\xBB\x8D\xBC\xB0\x00\x23\x0B\xBF\xAD\xA9\xD6\x64\x04\x7D\x09\xD2\xA2\x74\x44\xAB\xCE\x93\xB2\xB0\xB0\xC3\x81\xB5\xB2\xA9\xBE\x9B\xA4\xB6\xB8\xE5\xA8\xAD\xB6\xB9\x06\x67\x04\x7C\x0A\xD9\xBD\x69\x09\xBC\xB1\xAB\xBA\xBB\xB3\xDC\x6A\x04\x7F\x0A\xF4\x86\xB6\xBD\xBD\xF8\xAC\xB3\xB8\xB1\xBC\xAC\x04\x7D\x0B\xFD\xA4\xBF\xBE\xBF\x01\xF7\xBE\xB7\xC0\xE8\x8E\xBE\x08\x7D\x16\x5C\xBD\xC3\x6F\x30\x09\xC4\xC3\xC2\x0A\xD7\xCC\xC3\xC3\xE9\x80\xC0\xC8\xC7\x1B\xDE\xCD\xC7\xC8\xCF\xB1\x04\x7E\x0C\x1A\xCA\x73\x0D\xCB\xE1\xB1\xC0\xBA\x42\x34\x34\x75\x0E\x42\x62\x5F\xB7\xBA\xCC\x3B\xF3\xCD\xCF\xCF\x2F\xB7\x04\x7C\x0E\x30\xCA\x49\x0D\xD1\x40\xD0\xCC\xCE\x41\x3A\x34\x7B\x0C\xCE\x3E\xFA\xC2\xD6\xD2\x51\xD4\xD9\xD1\xC8\x1F\xE2\x7D\x0C\xD2\x53\xD8\xD7\xCA\xC0\x5E\xE5\xC8\xCB\xD8\xE2\x7E\x0C\xD6\xD5\x5D\xC1\x4F\x0C\x7D\x40\x10\xD7\xD4\xC9\x11\xE6\xC2\xD8\xD8\x70\xCB\xDA\xA2\x10\xF4", "\x43\x17\xDA\x40\x44\x3B\xD5\xDD\xD5\x61\xF1\xD4\xDA\xC3\x74\xF2\xD2\xE1\xE1\x83\xE2\xC2\x79\x11\xF4\x46\x1E\xDC\x00\x47\x0F\xE9\xE1\xD6\xF7\x88\x14\x7D\x12\x6E\xE9\xD6\xE2\xDD\x81\xDC\xEF\xDF\xDB\xCF\x8B\x14\x7C\x13\x8F\xCD\x12\xE4\xE2\xA8\xF7\xBE\x10\x7D\x4F\x19\xE8\xDB\xEB\x9D\xC0\xEF\xE6\xE6\x93\xDF\xD4\xE3\xED\x00\xD1\x17\xE8\xEE\x94\xCA\xEC\xEE\xED\xBE\xFF\x62\x17\xEE\x00\xD3\x14\x7C\x15\xAE\xF1\xE0\xE9\xED\x73\xFF\xED\xF1\xF0\xB7\x56\x14\x7F\x15\x8F\xD8\x14\xF1\xEF\xD8\xC0\xF9\xF7\xF3\xDB\xC7\xEE\xF2\xF7\xD0\xFB\x69\x17\xF5\xDA\xE5\xFC\xF6\xF9\xE0\xCC\xCB\x02\x71\x01\x79\xC4\x68\xCA\xEE\xC9\x78\xC8\xFB\x01\x74\xF0\x00\x5F\x09\x46\x66\xC5\x4C\x97\x49\x4D\xFE\x41\xF1\x76\x32\x42\x44\x33\x20\xFC\x46\x24\x80\xF2\x7C\x4A\xFD\x01\x31\x80\x00\x36\x7E\x7E\x06\x85\x31\x99\x7F\x73\x20\x0A\x82\x25\x81\x16\x81\x20\x02\x81\x21\x83\x83\x1D\x29\x26\x0B\x8A\x21\x07\x81\x2A\x7F\xE2\x1D\x29\x83\x00\x0F\x35\x4A\x06\x28\x84\x14\x98\x83\x80\x22\x90\x85\x5D\x4D\x41\x85\xBA\x0D\x85\x86\x06\x23\x84\x00\x25\x83\x20\xFB\x7C\x7A", "\x21\x2A\x8B\x86\x40\x2D\x89\x78\x01\x89\x23\x83\xF7\x72\x87\x5D\x31\x2D\x81\x98\x30\x7F\x83\x85\x6D\x8A\x13\xF7\x5F\x80\xFA\x28\x82\x87\xF6\x68\x8B\x14\xA7\x48\x86\xD2\x0D\x84\x81\xF4\x3F\x20\x0F\xC3\x85\x88\x07\x8A\x27\x8A\x0A\x23\x8E\x06\xD0\x84\x24\x29\x9B\x8D\x63\x6E\x8F\x8D\xDC\x71\x8F\x8C\x22\x74\x8B\x8B\x76\x8C\x8C\xC0\x5A\x82\x8F\x24\x4D\x87\x8E\x53\x99\x8F\x0C\xD1\x8A\x8E\x86\x5D\x8F\x82\x67\x89\x8D\x19\xFC\x8D\x8E\x40\x8E\x8A\x90\x4B\x84\x93\x20\xD4\x84\x3F\x17\xB9\x7B\x91\x85\x9C\x22\x23\xCF\x83\x92\x80\x5B\x92\x92\x91\x97\x5F\x27\xA2\x99\x93\x92\x63\x96\x93\xA5\x93\x8D\x2A\xC4\x4A\x8D\x94\x3F\x86\x62\x1F\x28\x86\x4A\x4A\x8F\x7D\x93\x2D\x91\x30\x28\x87\x92\x11\xC2\x85\x7E\x5A\x89\x85\x8D\xA9\x9A\x84\x77\x0C\x92\x8E\x62\xAF\x8F\x94\x1D\x22\x9A\x78\x48\x90\x8F\x55\x94\x3C\x99\xA6\x8E\x9B\x84\x50\x9A\x95\x4E\x86\x94\x3E\x3A\x8D\x96\x32\xA4\x28\x84\x86\x3C\x93\x97\x03\x33\x3D\x58\x09\x99\x20\xEF\x09\x22\x87\xC6\x9B\x89\x15\xE7\x9A\x90\x76\xB5\x2D\x9B\xDF\x80\x9E\x40\x62\x90\x80\x72\x86\x26\x9C\x39\x9E", "\x94\x78\x4C\x81\x98\xEA\x2B\x99\x9F\x97\x8E\x9F\x5D\x70\x91\x9E\x14\xB4\x9B\x20\x96\x97\x9D\x0C\xC7\x89\x94\x6A\x9B\x9F\x37\xD4\x90\x91\x2D\xA4\x96\x9B\x8E\x7A\x91\x89\x01\xA0\xA3\x40\x8A\x2E\x9B\x6F\x86\xA5\x8C\x28\x98\x9D\x01\xFA\x97\x3A\x10\xB1\x98\xA3\x06\x3A\x9B\x09\x9C\xA7\xA5\x8F\xA3\x9E\x7F\x0A\x22\xA7\x5E\x24\xAD\x8F\x8D\x0E\xA6\x9F\x27\xB9\x9B\x42\x9B\xA9\x21\x8E\xBC\x96\xA5\xF5\x90\xA5\x39\xBB\xA3\x39\x86\xBD\x9B\x42\x81\x37\xA2\x49\x8C\xA5\xA3\x8D\x29\x9B\x8A\x37\xB3\x43\x53\xCE\x81\xAB\x17\x51\xA7\x99\xD2\x96\xA9\x56\x8A\x57\xAB\x69\x9B\xAC\x57\x5D\xAF\x46\xFD\x0D\x8A\xA6\x81\xA4\x34\xA0\x1E\xAA\x23\x41\x88\x92\xA8\x85\xA6\xAE\x83\x4D\xBF\x1F\x58\xC4\xA2\x20\x95\xAF\x9C\xA5\x05\xAA\xAC\x48\xB1\xA4\xAF\x35\xB1\xAD\xAA\x8A\x53\xAF\x5B\xA4\x8D\xAF\xEB\x28\xAF\xA7\x7A\xAF\xA4\x0B\xFC\xA3\xB0\x82\x06\xA9\xAE\x0F\xB7\x35\x58\xDC\xAF\xAA\x67\x53\xB4\x57\x10\x85\xB2\x5D\xBC\xA6\x20\x9F\x82\x88\xA8\x08\xB6\x9F\x40\x32\xAC\x82\x9A\xB5\xA1\xB3\x8D\xBB\xB3\x59\xF8\xA9\xAD\x84\x2B\xAD\x7D\xA2\xA2\x20\x69\xA8", "\xA5\xA9\xBF\x87\xAA\xAC\x85\xA5\xAE\x46\xAB\xBD\xA7\x96\x89\xB1\xA8\x8B\xA3\xA9\x63\xD3\xAC\x9E\xC8\x94\x39\xA9\x27\xAB\xAB\x01\xA9\x94\xB9\x93\x00\xB4\x57\xCD\xA0\x9A\x71\xDE\xA1\xAE\x89\xBF\x90\x95\xD5\xB4\x39\x74\xA1\x24\x9B\xEE\x8F\xB1\x94\xDC\xB7\xB4\x69\x28\xB7\x2E\xB2\x9D\x2E\xBC\x36\x85\xB1\x71\x86\x2C\x0B\x93\xB3\x96\x62\xE8\xA9\xA5\x6C\xAE\x35\x8C\xDD\x95\x80\x88\xF5\xAD\x9D\x70\x86\x21\x89\xDA\x9F\x98\x89\x1F\x28\x8A\x67\xAB\x83\xC1\x94\x05\xC5\xBF\x02\x28\xC0\x7D\xC2\xBE\xAD\x06\xF7\xB9\x21\x0A\xC0\x00\x0A\x91\xC3\xC3\xDF\x83\x21\xC2\xAF\xA9\x86\x85\x89\xCA\x20\xFB\x10\xC5\xC3\xF8\xA9\x22\x87\xFC\xBA\xBF\x07\xE4\xC1\xA3\x26\xD7\xC1\x89\xE4\x8F\xC3\x84\x3D\x3D\xAD\x2A\xCE\xC7\x7C\x9A\xC2\xC6\x18\xDC\xC1\x21\x11\x5B\xBD\x8C\x86\x29\xC7\x14\xF7\xC4\xC7\x33\xD1\xC2\x7D\xAC\xC7\xC5\xDD\xB5\xA9\xC8\x9A\xA8\xC9\x3C\xA5\x41\x9F\x0C\xDC\x38\x8B\xF4\x77\xA1\x8F\xBC\x51\xB3\xDD\x11\xC2\x4A\x13\x55\xCA\x75\x28\x8A\x65\x2C\xF8\x61\xCA\x2B\xC1\x23\xC4\x5E\xC7\x9C\x30\xCD\xB0\x5B\x64\xC9\xA6\x99\xC0\xB3\x21\x4E", "\x69\xCD\x82\x6B\xDD\x86\x42\x5E\x4F\xCC\xCC\xA3\x4C\x3A\x5A\xCA\x39\x03\x96\x58\xA8\x20\xB1\xCB\xA6\x09\x39\x55\x9F\xC7\x8F\xCF\xD2\x89\x22\x59\x83\xDD\xB1\xA1\xBB\x8A\x21\x79\x49\xD3\xB4\x8B\xCD\x94\xBF\x0F\xD3\x9F\x45\xDA\x0E\xB7\xA0\x7F\x22\x23\xEE\xBB\xD2\xAC\x8A\xB4\xB2\xFB\x65\x71\x2B\xA8\x8C\x3B\xF8\xB0\x71\x20\xB3\xBE\x86\x78\x43\xC3\x77\x70\x8B\x5D\x95\xAA\xD7\x5F\x88\xBE\xCE\x59\x5C\xB2\x70\x00\x3D\x4D\xC7\x8B\x15\xC0\x74\x32\x61\xD5\x37\x11\xD3\xA8\x91\x76\x4F\xD7\xDF\x08\x89\xD6\x00\x68\x51\x91\x8A\x55\xC0\x52\xC5\x76\x55\x9F\xC2\x8A\xFD\x05\xCD\xD3\x09\x42\xD4\xCD\x02\x3F\x9F\x40\x05\xC3\xD6\xE5\x46\x20\xD1\xD8\xCE\x59\x86\xB3\xB8\x64\x6B\x4D\xB4\x3B\xDD\xC1\x23\x8B\x9A\x7E\x5D\x62\xF7\x31\xDD\x00\x0C\xCA\xE6\x70\x5E\xDD\xDD\x2B\xDB\x20\xF2\xC7\xD4\x00\x0E\xD6\x85\x09\x53\xC8\xD5\xB7\xDA\x5C\x8A\xBC\x59\xDE\x22\xFA\xDB\xCC\xE1\xC0\x03\x0D\x8A\x25\xE0\xD8\xA0\x71\x63\xD1\xC6\xD1\xBF\x86\x2D\x44\x83\x04\xDA\x73\x2C\x71\xE3\xB3\x15\xE3\x20\x30\x60\x75\x66\x1A\xFC\x38\xC7\x82\x24\x4A\xD0\x76\x05\x8C", "\xDC\x21\x49\x42\x39\xDA\x72\xA2\x75\xDE\x3A\x58\xC6\x22\xCA\x9A\x77\x69\x97\xCA\x3D\xE4\x16\xF7\xD5\xD3\x1A\xE3\xD4\x85\x38\xE5\xE3\xB7\xDC\x05\x19\xB3\xB8\x85\x9F\xE4\xE7\xD6\x66\x7A\xE1\xC3\x92\xC3\xCE\x85\x2C\xE2\xDF\x6D\x67\xDE\x78\x1E\xEA\xC6\x6F\xC3\x22\x6F\x1A\xE6\xEA\xC3\x86\x24\xEB\xD0\xA0\x74\x71\x1A\xFD\xE8\x5B\xDC\xE0\xC4\xD0\x51\x72\xE3\x17\xF2\xCD\x42\x3E\xD6\x21\xA7\xD6\xEA\x20\x98\x72\xE9\x6F\x69\xE6\xE1\xB7\xC1\x24\x74\x1A\xEA\xDA\xD7\xB9\xE1\xE5\xC2\x6B\x72\xE3\x93\x48\xED\xD9\x9A\x70\x0B\x32\xAE\xCB\xE2\x03\x3A\xEE\x40\x74\xED\xD4\x81\x03\x7A\xE3\xAB\x48\xF2\x40\x0A\xF1\x20\xB1\xCD\xF1\x20\xC8\x7A\xE0\xB4\x92\xF1\x20\xCA\xC0\x02\xEB\x9B\x6A\x22\xF4\x1A\xE4\x56\x8B\x41\xF4\xEF\x9A\x76\x7A\xC6\xD7\xDA\xEC\x83\x27\xF0\xE8\xA0\x77\xD2\xC6\xC8\x56\xF4\x9F\xF7\xD5\xBD\x1A\xE0\xDD\xEB\x83\x2C\xCE\x83\x11\x50\x74\x5E\x01\xCF\xB3\x3D\xF3\x21\xD7\xF6\xE8\x00\x62\x01\xC7\x8B\x07\xF3\x21\xDF\xDA\x70\x0D\xCB\x4C\xFA\x40\x46\xF7\xF2\x00\x29\x0A\xBD\xE2\x31\xF3\x40\x0C\xF1\xF5\x84\x2C\x0D\x8C\xD1\x50\xF2", "\x42\x16\xFD\xFA\x83\x2E\x0D\x8C\x68\xC9\xE2\xF6\xC7\xE0\x74\x38\x25\x8D\xDD\x09\xE5\xF4\xEA\xFA\xD2\x0F\x32\xBC\xDB\xEF\x03\x32\xFC\xEC\x9A\x74\x0F\x32\x93\xD1\xFE\xB6\x70\x3A\x76\x05\x46\x08\x3B\x7A\x0A\x1B\x79\xFA\x68\x07\xCA\x7A\x28\xAC\x72\x10\xE1\x7A\x39\x7E\x0C\x5A\x0C\x8A\x10\xE6\x6A\x39\x86\x02\x81\xBC\x24\x7B\xF3\x77\x7C\x8E\x05\x46\x15\x39\x70\x1A\x8B\x7F\xFA\x60\x09\x65\x4D\x65\x20\x81\x80\x9A\x32\x09\x65\x4F\x32\xB9\x77\x80\xB7\x64\x09\x0B\x8C\x2B\xBA\x7E\x80\xB7\x6A\x09\x18\x8E\x2C\x33\x81\x10\x15\x8A\x6F\xA2\x07\x83\xCF\x2F\x80\xF9\x77\x6B\xAA\x0B\x2C\x3B\x87\x2C\xB7\x6B\x0A\xCB\x29\x7E\x03\x18\x80\xC7\x7C\x0A\x49\x8A\x10\x40\x87\x7C\xAD\x08\x7D\xBD\x1A\x84\x02\x15\x84\xD5\x70\x0B\x54\x8F\x1B\xDB\x2B\x81\xD5\x73\x0B\x65\x47\x33\x8D\x5D\x85\x22\x87\x7C\xB5\x05\x46\x2E\x76\x64\x01\x14\x86\xEC\x7A\x39\xB7\x05\x46\x4F\x3D\x58\xF4\x6E\x85\xE5\x73\x10\xB9\x05\x46\x49\x7A\x86\x00\x03\x87\x65\x85\x7D\xBB\x05\x46\x41\x05\x58\x7C\x8D\x86\xFA\x6D\x0B\x65\x4D\x37\x8D\x57\x7F\x02\x10\x7F\xFA\x6F\x0B\x31\x8E", "\x2C\x8A\x81\x10\x06\x30\x3A\xC5\x0E\x83\xDC\x11\x89\x00\x05\x80\x9A\x3D\x0C\x96\x82\x1E\x02\x74\x87\x28\x35\x0D\x65\x47\x76\x7A\x8F\x89\x7D\x85\x87\x02\x17\x0D\x65\x4A\x04\x85\x56\x8A\x84\x87\x7C\xD9\x05\x46\xA6\x3D\x58\xFF\x73\x10\x8C\x87\x7C\xDB\x0F\x88\xCF\x25\x8B\x02\x13\x89\x9A\x31\x0E\x9D\x8D\x1B\xBC\x81\x10\x9A\x8A\x6F\xE9\x01\x8C\xBF\x1E\x8B\x03\x13\x88\xD5\x71\x0F\xCB\x25\x8C\x02\x1E\x8A\xD5\x72\x0F\xCB\x28\x70\xB6\x87\x6B\xF3\x05\x8D\x0A\x1A\x8C\xC7\x74\x0F\x5B\x87\x1B\xD6\x82\x10\xD0\x85\x7D\xF7\x0F\x8D\xBB\x1F\x81\xDB\x77\x6B\xFA\x05\x46\x85\x73\x70\x01\x18\x8E\x02\x14\x7E\x28\x3C\x0F\x65\x49\x79\xF2\x59\x10\xF0\x81\x10\xA0\x78\x32\xFE\x05\x46\xAA\x77\x8F\x06\x16\x82\x03\x10\x71\x9A\x36\x46\x9C\x7F\x2C\x19\x7E\x5E\x1A\x1A\x90\x0C\x9D\x90\x0B\x4E\x43\x0F\x9F\x5E\xB0\x4B\x40\x5F\x4D\x44\x15\x9A\x69\x18\x95\x46\x0A\x79\x91\x8D\x54\x5B\x73\x1A\x43\x1E\x90\x68\xEE\x84\x58\x1A\x17\x4B\x26\x92\x46\x28\x92\x7C\x8C\x63\x63\x4C\x7A\x11\xB2\x4F\x92\xB1\x41\x93\x2C\x92\x4B\x11\x64\x63\x30\x15\x93\x1F\x10", }; vl::glr::DecompressSerializedData(compressed, true, dataSolidRows, dataRows, dataBlock, dataRemain, outputStream); } const wchar_t* ParserRuleName(vl::vint index) { static const wchar_t* results[] = { L"QPrimaryFragment", L"QPrimaryAttributed", L"QPrimary", L"Query0", L"Query1", L"Query2", L"QueryRoot", }; return results[index]; } const wchar_t* ParserStateLabel(vl::vint index) { static const wchar_t* results[] = { L"[0][QPrimaryFragment] BEGIN ", L"[1][QPrimaryFragment] END [ENDING]", L"[2][QPrimaryFragment]< \"*\" @ [ \".\" NAME ] >", L"[3][QPrimaryFragment]< \"*\" [ \".\" @ NAME ] >", L"[4][QPrimaryFragment]< \"*\" [ \".\" NAME @ ] >", L"[5][QPrimaryFragment]< NAME @ [ \".\" NAME ] >", L"[6][QPrimaryFragment]< NAME [ \".\" @ NAME ] >", L"[7][QPrimaryFragment]< NAME [ \".\" NAME @ ] >", L"[8][QPrimaryAttributed] BEGIN ", L"[9][QPrimaryAttributed] END [ENDING]", L"[10][QPrimaryAttributed]<! !QPrimaryFragment @ !>", L"[11][QPrimaryAttributed]<! \"@\" @ [ NAME ] \":\" !QPrimaryFragment !>", L"[12][QPrimaryAttributed]<! \"@\" [ NAME @ ] \":\" !QPrimaryFragment !>", L"[13][QPrimaryAttributed]<! \"@\" [ NAME ] \":\" !QPrimaryFragment @ !>", L"[14][QPrimaryAttributed]<! \"@\" [ NAME ] \":\" @ !QPrimaryFragment !>", L"[15][QPrimary] BEGIN ", L"[16][QPrimary] END [ENDING]", L"[17][QPrimary]<! \"(\" !QueryRoot \")\" @ !>", L"[18][QPrimary]<! \"(\" !QueryRoot @ \")\" !>", L"[19][QPrimary]<! \"(\" @ !QueryRoot \")\" !>", L"[20][QPrimary]<! \"/\" !QPrimaryAttributed @ !>", L"[21][QPrimary]<! \"/\" @ !QPrimaryAttributed !>", L"[22][QPrimary]<! \"//\" !QPrimaryAttributed @ !>", L"[23][QPrimary]<! \"//\" @ !QPrimaryAttributed !>", L"[24][Query0] BEGIN ", L"[25][Query0] END [ENDING]", L"[26][Query0]< Query0 @ QPrimary >", L"[27][Query0]< Query0 QPrimary @ >", L"[28][Query0]<! !QPrimary @ !>", L"[29][Query1] BEGIN ", L"[30][Query1] END [ENDING]", L"[31][Query1]< Query1 \"*\" @ Query0 >", L"[32][Query1]< Query1 \"*\" Query0 @ >", L"[33][Query1]< Query1 \"^\" @ Query0 >", L"[34][Query1]< Query1 \"^\" Query0 @ >", L"[35][Query1]< Query1 @ \"*\" Query0 >", L"[36][Query1]< Query1 @ \"^\" Query0 >", L"[37][Query1]<! !Query0 @ !>", L"[38][Query2] BEGIN ", L"[39][Query2] END [ENDING]", L"[40][Query2]< Query2 \"+\" @ Query1 >", L"[41][Query2]< Query2 \"+\" Query1 @ >", L"[42][Query2]< Query2 \"-\" @ Query1 >", L"[43][Query2]< Query2 \"-\" Query1 @ >", L"[44][Query2]< Query2 @ \"+\" Query1 >", L"[45][Query2]< Query2 @ \"-\" Query1 >", L"[46][Query2]<! !Query1 @ !>", L"[47][QueryRoot] BEGIN ", L"[48][QueryRoot] END [ENDING]", L"[49][QueryRoot]<! !Query2 @ !>", }; return results[index]; } Parser::Parser() : vl::glr::ParserBase<GuiInstanceQueryTokens, ParserStates, GuiInstanceQueryAstInsReceiver>(&GuiInstanceQueryTokenDeleter, &GuiInstanceQueryLexerData, &GuiInstanceQueryParserData) { } vl::WString Parser::GetClassName(vl::vint32_t classIndex) const { return vl::WString::Unmanaged(GuiInstanceQueryTypeName((GuiInstanceQueryClasses)classIndex)); } vl::vint32_t Parser::FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const { return -1; } vl::Ptr<vl::presentation::instancequery::GuiIqQuery> Parser::ParseQueryRoot(const vl::WString& input, vl::vint codeIndex) const { return ParseWithString<vl::presentation::instancequery::GuiIqQuery, ParserStates::QueryRoot>(input, this, codeIndex); } vl::Ptr<vl::presentation::instancequery::GuiIqQuery> Parser::ParseQueryRoot(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex) const { return ParseWithTokens<vl::presentation::instancequery::GuiIqQuery, ParserStates::QueryRoot>(tokens, this, codeIndex); } } /*********************************************************************** .\INSTANCEQUERY\GENERATED\GUIINSTANCEQUERY_ASSEMBLER.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:GuiInstanceQuery Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::instancequery { /*********************************************************************** GuiInstanceQueryAstInsReceiver : public vl::glr::AstInsReceiverBase ***********************************************************************/ vl::Ptr<vl::glr::ParsingAstBase> GuiInstanceQueryAstInsReceiver::CreateAstNode(vl::vint32_t type) { auto cppTypeName = GuiInstanceQueryCppTypeName((GuiInstanceQueryClasses)type); switch((GuiInstanceQueryClasses)type) { case GuiInstanceQueryClasses::CascadeQuery: return vl::Ptr(new vl::presentation::instancequery::GuiIqCascadeQuery); case GuiInstanceQueryClasses::PrimaryQuery: return vl::Ptr(new vl::presentation::instancequery::GuiIqPrimaryQuery); case GuiInstanceQueryClasses::SetQuery: return vl::Ptr(new vl::presentation::instancequery::GuiIqSetQuery); default: return vl::glr::AssemblyThrowCannotCreateAbstractType(type, cppTypeName); } } void GuiInstanceQueryAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::Ptr<vl::glr::ParsingAstBase> value) { auto cppFieldName = GuiInstanceQueryCppFieldName((GuiInstanceQueryFields)field); switch((GuiInstanceQueryFields)field) { case GuiInstanceQueryFields::CascadeQuery_child: return vl::glr::AssemblerSetObjectField(&vl::presentation::instancequery::GuiIqCascadeQuery::child, object, field, value, cppFieldName); case GuiInstanceQueryFields::CascadeQuery_parent: return vl::glr::AssemblerSetObjectField(&vl::presentation::instancequery::GuiIqCascadeQuery::parent, object, field, value, cppFieldName); case GuiInstanceQueryFields::SetQuery_first: return vl::glr::AssemblerSetObjectField(&vl::presentation::instancequery::GuiIqSetQuery::first, object, field, value, cppFieldName); case GuiInstanceQueryFields::SetQuery_second: return vl::glr::AssemblerSetObjectField(&vl::presentation::instancequery::GuiIqSetQuery::second, object, field, value, cppFieldName); default: return vl::glr::AssemblyThrowFieldNotObject(field, cppFieldName); } } void GuiInstanceQueryAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, const vl::regex::RegexToken& token, vl::vint32_t tokenIndex) { auto cppFieldName = GuiInstanceQueryCppFieldName((GuiInstanceQueryFields)field); switch((GuiInstanceQueryFields)field) { case GuiInstanceQueryFields::PrimaryQuery_attributeName: return vl::glr::AssemblerSetTokenField(&vl::presentation::instancequery::GuiIqPrimaryQuery::attributeName, object, field, token, tokenIndex, cppFieldName); case GuiInstanceQueryFields::PrimaryQuery_referenceName: return vl::glr::AssemblerSetTokenField(&vl::presentation::instancequery::GuiIqPrimaryQuery::referenceName, object, field, token, tokenIndex, cppFieldName); case GuiInstanceQueryFields::PrimaryQuery_typeName: return vl::glr::AssemblerSetTokenField(&vl::presentation::instancequery::GuiIqPrimaryQuery::typeName, object, field, token, tokenIndex, cppFieldName); default: return vl::glr::AssemblyThrowFieldNotToken(field, cppFieldName); } } void GuiInstanceQueryAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::vint32_t enumItem, bool weakAssignment) { auto cppFieldName = GuiInstanceQueryCppFieldName((GuiInstanceQueryFields)field); switch((GuiInstanceQueryFields)field) { case GuiInstanceQueryFields::PrimaryQuery_attributeNameOption: return vl::glr::AssemblerSetEnumField(&vl::presentation::instancequery::GuiIqPrimaryQuery::attributeNameOption, object, field, enumItem, weakAssignment, cppFieldName); case GuiInstanceQueryFields::PrimaryQuery_childOption: return vl::glr::AssemblerSetEnumField(&vl::presentation::instancequery::GuiIqPrimaryQuery::childOption, object, field, enumItem, weakAssignment, cppFieldName); case GuiInstanceQueryFields::PrimaryQuery_typeNameOption: return vl::glr::AssemblerSetEnumField(&vl::presentation::instancequery::GuiIqPrimaryQuery::typeNameOption, object, field, enumItem, weakAssignment, cppFieldName); case GuiInstanceQueryFields::SetQuery_op: return vl::glr::AssemblerSetEnumField(&vl::presentation::instancequery::GuiIqSetQuery::op, object, field, enumItem, weakAssignment, cppFieldName); default: return vl::glr::AssemblyThrowFieldNotEnum(field, cppFieldName); } } const wchar_t* GuiInstanceQueryTypeName(GuiInstanceQueryClasses type) { const wchar_t* results[] = { L"CascadeQuery", L"PrimaryQuery", L"Query", L"SetQuery", }; vl::vint index = (vl::vint)type; return 0 <= index && index < 4 ? results[index] : nullptr; } const wchar_t* GuiInstanceQueryCppTypeName(GuiInstanceQueryClasses type) { const wchar_t* results[] = { L"vl::presentation::instancequery::GuiIqCascadeQuery", L"vl::presentation::instancequery::GuiIqPrimaryQuery", L"vl::presentation::instancequery::GuiIqQuery", L"vl::presentation::instancequery::GuiIqSetQuery", }; vl::vint index = (vl::vint)type; return 0 <= index && index < 4 ? results[index] : nullptr; } const wchar_t* GuiInstanceQueryFieldName(GuiInstanceQueryFields field) { const wchar_t* results[] = { L"CascadeQuery::child", L"CascadeQuery::parent", L"PrimaryQuery::attributeName", L"PrimaryQuery::attributeNameOption", L"PrimaryQuery::childOption", L"PrimaryQuery::referenceName", L"PrimaryQuery::typeName", L"PrimaryQuery::typeNameOption", L"SetQuery::first", L"SetQuery::op", L"SetQuery::second", }; vl::vint index = (vl::vint)field; return 0 <= index && index < 11 ? results[index] : nullptr; } const wchar_t* GuiInstanceQueryCppFieldName(GuiInstanceQueryFields field) { const wchar_t* results[] = { L"vl::presentation::instancequery::GuiIqCascadeQuery::child", L"vl::presentation::instancequery::GuiIqCascadeQuery::parent", L"vl::presentation::instancequery::GuiIqPrimaryQuery::attributeName", L"vl::presentation::instancequery::GuiIqPrimaryQuery::attributeNameOption", L"vl::presentation::instancequery::GuiIqPrimaryQuery::childOption", L"vl::presentation::instancequery::GuiIqPrimaryQuery::referenceName", L"vl::presentation::instancequery::GuiIqPrimaryQuery::typeName", L"vl::presentation::instancequery::GuiIqPrimaryQuery::typeNameOption", L"vl::presentation::instancequery::GuiIqSetQuery::first", L"vl::presentation::instancequery::GuiIqSetQuery::op", L"vl::presentation::instancequery::GuiIqSetQuery::second", }; vl::vint index = (vl::vint)field; return 0 <= index && index < 11 ? results[index] : nullptr; } vl::Ptr<vl::glr::ParsingAstBase> GuiInstanceQueryAstInsReceiver::ResolveAmbiguity(vl::vint32_t type, vl::collections::Array<vl::Ptr<vl::glr::ParsingAstBase>>& candidates) { auto cppTypeName = GuiInstanceQueryCppTypeName((GuiInstanceQueryClasses)type); return vl::glr::AssemblyThrowTypeNotAllowAmbiguity(type, cppTypeName); } } /*********************************************************************** .\INSTANCEQUERY\GENERATED\GUIINSTANCEQUERY_LEXER.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:GuiInstanceQuery Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::instancequery { bool GuiInstanceQueryTokenDeleter(vl::vint token) { switch((GuiInstanceQueryTokens)token) { case GuiInstanceQueryTokens::SPACE: return true; default: return false; } } const wchar_t* GuiInstanceQueryTokenId(GuiInstanceQueryTokens token) { static const wchar_t* results[] = { L"INDIRECT", L"DIRECT", L"NAME", L"WILDCARD_INTERSECT", L"OPEN", L"CLOSE", L"XOR", L"UNION", L"SUBSTRACT", L"ATTRIBUTE", L"COLON", L"DOT", L"SPACE", }; vl::vint index = (vl::vint)token; return 0 <= index && index < GuiInstanceQueryTokenCount ? results[index] : nullptr; } const wchar_t* GuiInstanceQueryTokenDisplayText(GuiInstanceQueryTokens token) { static const wchar_t* results[] = { L"//", L"/", nullptr, L"*", L"(", L")", L"^", L"+", L"-", L"@", L":", L".", nullptr, }; vl::vint index = (vl::vint)token; return 0 <= index && index < GuiInstanceQueryTokenCount ? results[index] : nullptr; } const wchar_t* GuiInstanceQueryTokenRegex(GuiInstanceQueryTokens token) { static const wchar_t* results[] = { L"////", L"//", L"[a-zA-Z_][a-zA-Z0-9]*", L"/*", L"/(", L"/)", L"/^", L"/+", L"-", L"@", L":", L".", L"/s+", }; vl::vint index = (vl::vint)token; return 0 <= index && index < GuiInstanceQueryTokenCount ? results[index] : nullptr; } void GuiInstanceQueryLexerData(vl::stream::IStream& outputStream) { static const vl::vint dataLength = 232; // 1446 bytes before compressing static const vl::vint dataBlock = 256; static const vl::vint dataRemain = 232; static const vl::vint dataSolidRows = 0; static const vl::vint dataRows = 1; static const char* compressed[] = { "\xA6\x05\x00\x00\xE0\x00\x00\x00\x10\x00\x01\x93\x01\x84\x81\x82\x08\x82\x09\x08\x84\x8A\x0B\x84\x81\x06\x87\x04\xA0\x11\x84\x88\x14\x88\x83\x14\x17\x84\xAA\x1A\x84\x83\x15\x8E\x82\x2D\x20\x84\x8E\x13\x94\x83\x16\x93\x04\xB0\x04\x99\x14\x82\x1D\x96\x82\x40\x30\x84\x81\x24\x82\x2C\x82\x2F\x37\x84\x9F\x3A\x94\x81\x30\x82\x3D\x04\x8C\x01\xA3\xA1\x82\xA1\x80\x02\x04\x85\x04\x83\x04\x87\x00\x82\x04\x04\x8B\x04\x81\x04\x87\x7E\xAB\x7F\x0C\x81\x89\x81\x82\x04\x82\x02\x82\x5D\xDC\x95\xB7\xA4\xB5\xB2\xB3\xB3\x68\xE9\xBF\x6F\x81\x82\xB6\xB7\xB7\x70\xF1\xB2\xBF\x7E\x03\xB2\xB3\xBA\x6D\xE7\xB8\xA0\x03\xBD\xBE\xBF\xBF\x80\x81\xC2\xC3\xC4\xC5\xC2\xC3\xC3\x88\x89\xCA\xCB\xCC\xC5\xC6\xC7\xC7\x90\x91\xD2\xD3\xC8\xC7\x04\x82\xCB\x01\x98\xC0\x1A\xC4\xCD\xCE\xCF\xCF\x71\xFB\xA8\xA2\xDA\xBE\xBB\x7E\xCD\xA8\x97\xE6\xC0\xDF\xB6\x7F\x7E\x80\x05\x81\x94\xA2\xB1\x84\xA7\xA3\xA4\x5E\xCD\x8F\xAA\x81\x81\xAC\x00\xA9\x45\xB1\xF4\xC0\x06\xA0\x00", }; vl::glr::DecompressSerializedData(compressed, true, dataSolidRows, dataRows, dataBlock, dataRemain, outputStream); } } /*********************************************************************** .\REMOTEPROTOCOL\GUIREMOTEPROTOCOLCOMPILER.CPP ***********************************************************************/ namespace vl::presentation { using namespace collections; using namespace remoteprotocol; /*********************************************************************** CheckRemoteProtocolSchema ***********************************************************************/ class GuiRpCheckSchemaVisitor : public Object , public GuiRpType::IVisitor , public GuiRpDeclaration::IVisitor { protected: Ptr<GuiRpSymbols> symbols; List<GuiRpError>& errors; public: GuiRpCheckSchemaVisitor(Ptr<GuiRpSymbols> _symbols, List<GuiRpError>& _errors) : symbols(_symbols) , errors(_errors) { } // GuiRpType::IVisitor void Visit(GuiRpPrimitiveType* node) override { } void Visit(GuiRpReferenceType* node) override { if (symbols->enumDecls.Keys().Contains(node->name.value)) return; if (symbols->unionDecls.Keys().Contains(node->name.value)) return; if (symbols->structDecls.Keys().Contains(node->name.value)) return; errors.Add({ node->name.codeRange,L"Custom type \"" + node->name.value + L"\" not found." }); } void Visit(GuiRpOptionalType* node) override { node->element->Accept(this); } void Visit(GuiRpArrayType* node) override { node->element->Accept(this); } void Visit(GuiRpArrayMapType* node) override { vint index = symbols->structDecls.Keys().IndexOf(node->element.value); if (index == -1) { errors.Add({ node->element.codeRange,L"Struct \"" + node->element.value + L"\" not found in a map." }); return; } auto structDecl = symbols->structDecls.Values()[index]; auto fieldDecl = From(structDecl->members) .Where([&](auto&& member) { return member->name.value == node->keyField.value; }) .First({}); if (!fieldDecl) { errors.Add({ node->keyField.codeRange,L"Struct \"" + node->element.value + L"\" does not contain field " + node->keyField.value + L"\" required in a map." }); return; } } void Visit(GuiRpMapType* node) override { node->element->Accept(this); node->keyType->Accept(this); } // GuiRpDeclaration::IVisitor bool EnsureTypeUndefined(const glr::ParsingToken& name) { if (symbols->enumDecls.Keys().Contains(name.value)) { errors.Add({ name.codeRange,L"Enum \"" + name.value + L"\" already defined." }); return false; } if (symbols->unionDecls.Keys().Contains(name.value)) { errors.Add({ name.codeRange,L"Union \"" + name.value + L"\" already defined." }); return false; } if (symbols->structDecls.Keys().Contains(name.value)) { errors.Add({ name.codeRange,L"Struct \"" + name.value + L"\" already defined." }); return false; } return true; } void Visit(GuiRpEnumDecl* node) override { if (!EnsureTypeUndefined(node->name)) return; SortedList<WString> memberNames; for (auto member : node->members) { if (memberNames.Contains(member->name.value)) { errors.Add({ member->name.codeRange,L"Enum member \"" + node->name.value + L"::" + member->name.value + L"\" already exists." }); } else { memberNames.Add(member->name.value); } } for (auto att : node->attributes) { if (att->name.value == L"@Cpp") { if (!att->cppType) { errors.Add({ att->name.codeRange,L"Missing parameter for attribute: \"" + att->name.value + L"\"." }); } else if (symbols->cppMapping.Keys().Contains(node->name.value)) { errors.Add({ att->name.codeRange,L"Too many attributes: \"" + att->name.value + L"\"." }); } else { symbols->cppMapping.Add(node->name.value, att->cppType.value); } } else if (att->name.value == L"@CppNamespace") { if (!att->cppType) { errors.Add({ att->name.codeRange,L"Missing parameter for attribute: \"" + att->name.value + L"\"." }); } else if (symbols->cppNamespaces.Keys().Contains(node->name.value)) { errors.Add({ att->name.codeRange,L"Too many attributes: \"" + att->name.value + L"\"." }); } else { symbols->cppNamespaces.Add(node->name.value, att->cppType.value); } } else { errors.Add({ att->name.codeRange,L"Unsupported attribute: \"" + att->name.value + L"\" on enum \"" + node->name.value + L"\"." }); } } symbols->enumDecls.Add(node->name.value, node); } void Visit(GuiRpUnionDecl* node) override { if (!EnsureTypeUndefined(node->name)) return; SortedList<WString> memberNames; for (auto member : node->members) { if (memberNames.Contains(member->name.value)) { errors.Add({ member->name.codeRange,L"Union member \"" + node->name.value + L"::" + member->name.value + L"\" already exists." }); } else { memberNames.Add(member->name.value); vint index = symbols->structDecls.Keys().IndexOf(member->name.value); if (index == -1) { errors.Add({ member->name.codeRange,L"Struct \"" + member->name.value + L"\" not found in union " + node->name.value + L"\"." }); return; } auto structDecl = symbols->structDecls.Values()[index]; if (structDecl->type != GuiRpStructType::Struct) { errors.Add({ member->name.codeRange,L"Struct \"" + member->name.value + L"\" in union " + node->name.value + L"\" should not be a class." }); return; } } } for (auto att : node->attributes) { errors.Add({ att->name.codeRange,L"Unsupported attribute: \"" + att->name.value + L"\" on union \"" + node->name.value + L"\"." }); } symbols->unionDecls.Add(node->name.value, node); } void Visit(GuiRpStructDecl* node) override { if (!EnsureTypeUndefined(node->name)) return; if (node->type == GuiRpStructType::Class) { symbols->structDecls.Add(node->name.value, node); } SortedList<WString> memberNames; for (auto member : node->members) { if (memberNames.Contains(member->name.value)) { errors.Add({ member->name.codeRange,L"Struct member \"" + node->name.value + L"::" + member->name.value + L"\" already exists." }); } else { memberNames.Add(member->name.value); } member->type->Accept(this); } for (auto att : node->attributes) { if (att->name.value == L"@Cpp") { if (!att->cppType) { errors.Add({ att->name.codeRange,L"Missing parameter for attribute: \"" + att->name.value + L"\"." }); } else if (symbols->cppMapping.Keys().Contains(node->name.value)) { errors.Add({ att->name.codeRange,L"Too many attributes: \"" + att->name.value + L"\"." }); } else { symbols->cppMapping.Add(node->name.value, att->cppType.value); } } else { errors.Add({ att->name.codeRange,L"Unsupported attribute: \"" + att->name.value + L"\" on struct \"" + node->name.value + L"\"." }); } } if (node->type == GuiRpStructType::Struct) { symbols->structDecls.Add(node->name.value, node); } } void VisitDropAttribute(Ptr<remoteprotocol::GuiRpAttribute> att, const WString& name, SortedList<WString>& names) { if (names.Contains(name)) { errors.Add({ att->name.codeRange,L"Too many attributes: \"" + att->name.value + L"\"." }); } else { names.Add(name); } } void Visit(GuiRpMessageDecl* node) override { if (symbols->messageDecls.Keys().Contains(node->name.value)) { errors.Add({ node->name.codeRange,L"Message \"" + node->name.value + L"\" already exists." }); return; } if (node->request) { node->request->type->Accept(this); } if (node->response) { node->response->type->Accept(this); } for (auto att : node->attributes) { if (att->name.value == L"@DropRepeat") { if (node->response) { errors.Add({ node->name.codeRange,L"@DropRepeat cannot be used on message \"" + node->name.value + L"\" since it has response." }); } VisitDropAttribute(att, node->name.value, symbols->dropRepeatDeclNames); } else { errors.Add({ att->name.codeRange,L"Unsupported attribute: \"" + att->name.value + L"\" on message \"" + node->name.value + L"\"." }); } } symbols->messageDecls.Add(node->name.value, node); } void Visit(GuiRpEventDecl* node) override { if (symbols->eventDecls.Keys().Contains(node->name.value)) { errors.Add({ node->name.codeRange,L"Event \"" + node->name.value + L"\" already exists." }); return; } if (node->request) { node->request->type->Accept(this); } for (auto att : node->attributes) { if (att->name.value == L"@DropRepeat") { VisitDropAttribute(att, node->name.value, symbols->dropRepeatDeclNames); } else if (att->name.value == L"@DropConsecutive") { VisitDropAttribute(att, node->name.value, symbols->dropConsecutiveDeclNames); } else { errors.Add({ att->name.codeRange,L"Unsupported attribute: \"" + att->name.value + L"\" on event \"" + node->name.value + L"\"." }); } } if (symbols->dropRepeatDeclNames.Contains(node->name.value) && symbols->dropConsecutiveDeclNames.Contains(node->name.value)) { errors.Add({ node->name.codeRange,L"@DropRepeat and @DropConsecutive cannot be used together on event \"" + node->name.value + L"\"." }); } symbols->eventDecls.Add(node->name.value, node); } }; Ptr<GuiRpSymbols> CheckRemoteProtocolSchema(Ptr<GuiRpSchema> schema, collections::List<GuiRpError>& errors) { auto symbols = Ptr(new GuiRpSymbols); GuiRpCheckSchemaVisitor visitor(symbols, errors); for (auto decl : schema->declarations) { decl->Accept(&visitor); } return symbols; } /*********************************************************************** GenerateRemoteProtocolHeaderFile ***********************************************************************/ class GuiRpPrintTypeVisitor : public Object, public GuiRpType::IVisitor { protected: Ptr<GuiRpSymbols> symbols; GuiRpCppConfig& config; stream::TextWriter& writer; public: GuiRpPrintTypeVisitor(Ptr<GuiRpSymbols> _symbols, GuiRpCppConfig& _config, stream::TextWriter& _writer) : symbols(_symbols) , config(_config) , writer(_writer) { } // GuiRpType::IVisitor void Visit(GuiRpPrimitiveType* node) override { switch (node->type) { case GuiRpPrimitiveTypes::Boolean: writer.WriteString(L"bool"); break; case GuiRpPrimitiveTypes::Integer: writer.WriteString(L"::vl::vint"); break; case GuiRpPrimitiveTypes::Float: writer.WriteString(L"float"); break; case GuiRpPrimitiveTypes::Double: writer.WriteString(L"double"); break; case GuiRpPrimitiveTypes::String: writer.WriteString(L"::vl::WString"); break; case GuiRpPrimitiveTypes::Char: writer.WriteString(L"wchar_t"); break; case GuiRpPrimitiveTypes::Key: writer.WriteString(L"::vl::presentation::VKEY"); break; case GuiRpPrimitiveTypes::Color: writer.WriteString(L"::vl::presentation::Color"); break; case GuiRpPrimitiveTypes::Binary: writer.WriteString(L"::vl::Ptr<::vl::stream::MemoryStream>"); break; default: CHECK_FAIL(L"Unrecognized type"); } } static WString GetCppType(const WString& type, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config, bool forJson = false) { bool ptr = false; if (!forJson) { vint index = symbols->structDecls.Keys().IndexOf(type); if (index != -1) { auto structDecl = symbols->structDecls.Values()[index]; ptr = structDecl->type == GuiRpStructType::Class; } } WString result; { vint index = symbols->cppMapping.Keys().IndexOf(type); if (index == -1) { result = L"::" + config.cppNamespace + L"::" + type; } else { result = symbols->cppMapping.Values()[index]; } } if (ptr) { return L"::vl::Ptr<" + result + L">"; } else { return result; } } static WString GetCppTypeForJson(const WString& type, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config) { return GetCppType(type, symbols, config, true); } static WString GetCppNamespace(const WString& type, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config) { vint index = symbols->cppNamespaces.Keys().IndexOf(type); if (index == -1) { return GetCppType(type, symbols, config); } else { return symbols->cppNamespaces.Values()[index]; } } void Visit(GuiRpReferenceType* node) override { writer.WriteString(GetCppType(node->name.value, symbols, config)); } void Visit(GuiRpOptionalType* node) override { writer.WriteString(L"::vl::Nullable<"); node->element->Accept(this); writer.WriteString(L">"); } void Visit(GuiRpArrayType* node) override { writer.WriteString(L"::vl::Ptr<::vl::collections::List<"); node->element->Accept(this); writer.WriteString(L">>"); } void Visit(GuiRpArrayMapType* node) override { auto cppName = GetCppType(node->element.value, symbols, config); auto structDecl = symbols->structDecls[node->element.value]; auto fieldDecl = From(structDecl->members) .Where([&](auto&& member) { return member->name.value == node->keyField.value; }) .First(); writer.WriteString(L"::vl::Ptr<::vl::presentation::remoteprotocol::ArrayMap<"); fieldDecl->type->Accept(this); writer.WriteString(L", "); writer.WriteString(cppName); writer.WriteString(L", &"); writer.WriteString(cppName); writer.WriteString(L"::"); writer.WriteString(node->keyField.value); writer.WriteString(L">>"); } void Visit(GuiRpMapType* node) override { writer.WriteString(L"::vl::Ptr<::vl::collections::Dictionary<"); node->keyType->Accept(this); writer.WriteString(L", "); node->element->Accept(this); writer.WriteString(L">>"); } }; void GenerateSerializerFunctionHeader(const WString& type, bool semicolon, stream::TextWriter& writer) { writer.WriteString(L"\ttemplate<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<" + type + L">(const " + type + L" & value)"); writer.WriteLine(semicolon ? L";" : L""); } void GenerateDeserializerFunctionHeader(const WString& type, bool semicolon, stream::TextWriter& writer) { writer.WriteString(L"\ttemplate<> void ConvertJsonToCustomType<" + type + L">(vl::Ptr<vl::glr::json::JsonNode> node, " + type + L"& value)"); writer.WriteLine(semicolon ? L";" : L""); } void GenerateRemoteProtocolHeaderFile(Ptr<GuiRpSchema> schema, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config, stream::TextWriter& writer) { writer.WriteLine(L"/***********************************************************************"); writer.WriteLine(L"This file is generated by : Vczh GacUI Remote Protocol Generator"); writer.WriteLine(L"Licensed under https ://github.com/vczh-libraries/License"); writer.WriteLine(L"***********************************************************************/"); writer.WriteLine(L""); writer.WriteLine(L"#ifndef " + config.headerGuard); writer.WriteLine(L"#define " + config.headerGuard); writer.WriteLine(L""); writer.WriteLine(L"#include \"" + config.headerInclude + L"\""); writer.WriteLine(L""); auto structDecls = From(schema->declarations).FindType<GuiRpStructDecl>(); writer.WriteLine(L"namespace " + config.cppNamespace); writer.WriteLine(L"{"); for (auto structDecl : structDecls) { if (!symbols->cppMapping.Keys().Contains(structDecl->name.value)) { writer.WriteLine(L"\tstruct " + structDecl->name.value + L";"); } } writer.WriteLine(L"}"); writer.WriteLine(L"namespace vl::presentation::remoteprotocol"); writer.WriteLine(L"{"); for (auto structDecl : structDecls) { WString cppName = GuiRpPrintTypeVisitor::GetCppType(structDecl->name.value, symbols, config); writer.WriteLine(L"\ttemplate<> struct JsonNameHelper<" + cppName + L"> { static constexpr const wchar_t* Name = L\"" + structDecl->name.value + L"\"; };"); } writer.WriteLine(L"}"); writer.WriteLine(L"namespace " + config.cppNamespace); writer.WriteLine(L"{"); GuiRpPrintTypeVisitor printTypeVisitor(symbols, config, writer); for (auto enumDecl : From(schema->declarations).FindType<GuiRpEnumDecl>()) { if (!symbols->cppMapping.Keys().Contains(enumDecl->name.value)) { writer.WriteLine(L"\tenum class " + enumDecl->name.value); writer.WriteLine(L"\t{"); for (auto member : enumDecl->members) { writer.WriteLine(L"\t\t" + member->name.value + L","); } writer.WriteLine(L"\t};"); writer.WriteLine(L""); } } for (auto unionDecl : From(schema->declarations).FindType<GuiRpUnionDecl>()) { if (!symbols->cppMapping.Keys().Contains(unionDecl->name.value)) { writer.WriteLine(L"\tusing " + unionDecl->name.value + L" = ::vl::Variant<"); for (auto [member, index] : indexed(unionDecl->members)) { writer.WriteString(L"\t\t" + GuiRpPrintTypeVisitor::GetCppType(member->name.value, symbols, config)); if (index < unionDecl->members.Count() - 1) { writer.WriteLine(L","); } else { writer.WriteLine(L""); } } writer.WriteLine(L"\t>;"); writer.WriteLine(L""); } } for (auto structDecl : From(schema->declarations).FindType<GuiRpStructDecl>()) { if (!symbols->cppMapping.Keys().Contains(structDecl->name.value)) { writer.WriteLine(L"\tstruct " + structDecl->name.value); writer.WriteLine(L"\t{"); for (auto member : structDecl->members) { writer.WriteString(L"\t\t"); member->type->Accept(&printTypeVisitor); writer.WriteLine(L" " + member->name.value + L";"); } writer.WriteLine(L"\t};"); writer.WriteLine(L""); } } for (auto enumDecl : From(schema->declarations).FindType<GuiRpEnumDecl>()) { GenerateSerializerFunctionHeader(GuiRpPrintTypeVisitor::GetCppType(enumDecl->name.value, symbols, config), true, writer); } for (auto structDecl : From(schema->declarations).FindType<GuiRpStructDecl>()) { GenerateSerializerFunctionHeader(GuiRpPrintTypeVisitor::GetCppTypeForJson(structDecl->name.value, symbols, config), true, writer); } writer.WriteLine(L""); for (auto enumDecl : From(schema->declarations).FindType<GuiRpEnumDecl>()) { GenerateDeserializerFunctionHeader(GuiRpPrintTypeVisitor::GetCppType(enumDecl->name.value, symbols, config), true, writer); } for (auto structDecl : From(schema->declarations).FindType<GuiRpStructDecl>()) { GenerateDeserializerFunctionHeader(GuiRpPrintTypeVisitor::GetCppTypeForJson(structDecl->name.value, symbols, config), true, writer); } writer.WriteLine(L""); writer.WriteLine(L"#define " + config.builderMacroPrefix + L"_MESSAGES(HANDLER)\\"); for (auto messageDecl : From(schema->declarations).FindType<GuiRpMessageDecl>()) { writer.WriteString(L"\tHANDLER(" + messageDecl->name.value); writer.WriteString(L", "); if (messageDecl->request) { messageDecl->request->type->Accept(&printTypeVisitor); } else { writer.WriteString(L"void"); } writer.WriteString(L", "); if (messageDecl->response) { messageDecl->response->type->Accept(&printTypeVisitor); } else { writer.WriteString(L"void"); } writer.WriteString(messageDecl->request ? L", REQ" : L", NOREQ"); writer.WriteString(messageDecl->response ? L", RES" : L", NORES"); writer.WriteString(symbols->dropRepeatDeclNames.Contains(messageDecl->name.value) ? L", DROPREP" : L", NODROP"); writer.WriteLine(L")\\"); } writer.WriteLine(L""); writer.WriteLine(L"#define " + config.builderMacroPrefix + L"_EVENTS(HANDLER)\\"); for (auto eventDecl : From(schema->declarations).FindType<GuiRpEventDecl>()) { writer.WriteString(L"\tHANDLER(" + eventDecl->name.value); writer.WriteString(L", "); if (eventDecl->request) { eventDecl->request->type->Accept(&printTypeVisitor); } else { writer.WriteString(L"void"); } writer.WriteString(eventDecl->request ? L", REQ" : L", NOREQ"); writer.WriteString( symbols->dropRepeatDeclNames.Contains(eventDecl->name.value) ? L", DROPREP" : symbols->dropConsecutiveDeclNames.Contains(eventDecl->name.value) ? L", DROPCON" : L", NODROP"); writer.WriteLine(L")\\"); } writer.WriteLine(L""); SortedList<WString> requestTypes, responseTypes, eventTypes; { for (auto messageDecl : From(schema->declarations).FindType<GuiRpMessageDecl>()) { if (messageDecl->request) { auto type = stream::GenerateToStream([&](stream::TextWriter& writer) { GuiRpPrintTypeVisitor visitor(symbols, config, writer); messageDecl->request->type->Accept(&visitor); }); if (!requestTypes.Contains(type)) { requestTypes.Add(type); } } if (messageDecl->response) { auto type = stream::GenerateToStream([&](stream::TextWriter& writer) { GuiRpPrintTypeVisitor visitor(symbols, config, writer); messageDecl->response->type->Accept(&visitor); }); if (!responseTypes.Contains(type)) { responseTypes.Add(type); } } } for (auto eventDecl : From(schema->declarations).FindType<GuiRpEventDecl>()) { if (eventDecl->request) { auto type = stream::GenerateToStream([&](stream::TextWriter& writer) { GuiRpPrintTypeVisitor visitor(symbols, config, writer); eventDecl->request->type->Accept(&visitor); }); if (!eventTypes.Contains(type)) { eventTypes.Add(type); } } } } writer.WriteLine(L"#define GACUI_REMOTEPROTOCOL_MESSAGE_REQUEST_TYPES(HANDLER)\\"); for (auto type : requestTypes) writer.WriteLine(L"\tHANDLER(" + type + L")\\"); writer.WriteLine(L""); writer.WriteLine(L"#define GACUI_REMOTEPROTOCOL_MESSAGE_RESPONSE_TYPES(HANDLER)\\"); for (auto type : responseTypes) writer.WriteLine(L"\tHANDLER(" + type + L")\\"); writer.WriteLine(L""); writer.WriteLine(L"#define GACUI_REMOTEPROTOCOL_EVENT_REQUEST_TYPES(HANDLER)\\"); for (auto type : eventTypes) writer.WriteLine(L"\tHANDLER(" + type + L")\\"); writer.WriteLine(L""); writer.WriteLine(L"}"); writer.WriteLine(L""); writer.WriteLine(L"#endif"); } /*********************************************************************** GenerateRemoteProtocolCppFile ***********************************************************************/ void GenerateEnumSerializerFunctionImpl(Ptr<GuiRpEnumDecl> enumDecl, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config, stream::TextWriter& writer) { WString cppName = GuiRpPrintTypeVisitor::GetCppType(enumDecl->name.value, symbols, config); WString cppNss = GuiRpPrintTypeVisitor::GetCppNamespace(enumDecl->name.value, symbols, config); GenerateSerializerFunctionHeader(cppName, false, writer); writer.WriteLine(L"\t{"); writer.WriteLine(L"#define ERROR_MESSAGE_PREFIX L\"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<" + cppName + L">(const " + cppName + L"&)#\""); writer.WriteLine(L"\t\tauto node = Ptr(new glr::json::JsonString);"); writer.WriteLine(L"\t\tswitch (value)"); writer.WriteLine(L"\t\t{"); for (auto member : enumDecl->members) { writer.WriteLine(L"\t\tcase " + cppNss + L"::" + member->name.value + L": node->content.value = WString::Unmanaged(L\"" + member->name.value + L"\"); break;"); } writer.WriteLine(L"\t\tdefault: CHECK_FAIL(ERROR_MESSAGE_PREFIX L\"Unsupported enum value.\");"); writer.WriteLine(L"\t\t}"); writer.WriteLine(L"\t\treturn node;"); writer.WriteLine(L"#undef ERROR_MESSAGE_PREFIX"); writer.WriteLine(L"\t}"); writer.WriteLine(L""); } void GenerateStructSerializerFunctionImpl(Ptr<GuiRpStructDecl> structDecl, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config, stream::TextWriter& writer) { WString cppName = GuiRpPrintTypeVisitor::GetCppTypeForJson(structDecl->name.value, symbols, config); GenerateSerializerFunctionHeader(cppName, false, writer); writer.WriteLine(L"\t{"); writer.WriteLine(L"\t\tauto node = Ptr(new glr::json::JsonObject);"); for (auto member : structDecl->members) { writer.WriteLine(L"\t\tConvertCustomTypeToJsonField(node, L\"" + member->name.value + L"\", value." + member->name.value + L");"); } writer.WriteLine(L"\t\treturn node;"); writer.WriteLine(L"\t}"); writer.WriteLine(L""); } void GenerateEnumDeserializerFunctionImpl(Ptr<GuiRpEnumDecl> enumDecl, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config, stream::TextWriter& writer) { WString cppName = GuiRpPrintTypeVisitor::GetCppType(enumDecl->name.value, symbols, config); WString cppNss = GuiRpPrintTypeVisitor::GetCppNamespace(enumDecl->name.value, symbols, config); GenerateDeserializerFunctionHeader(cppName, false, writer); writer.WriteLine(L"\t{"); writer.WriteLine(L"#define ERROR_MESSAGE_PREFIX L\"vl::presentation::remoteprotocol::ConvertJsonToCustomType<" + cppName + L">(Ptr<JsonNode>, " + cppName + L"&)#\""); writer.WriteLine(L"\t\tauto jsonNode = node.Cast<glr::json::JsonString>();"); writer.WriteLine(L"\t\tCHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L\"Json node does not match the expected type.\");"); for (auto member : enumDecl->members) { writer.WriteLine(L"\t\tif (jsonNode->content.value == L\"" + member->name.value + L"\") value = " + cppNss + L"::" + member->name.value + L"; else"); } writer.WriteLine(L"\t\tCHECK_FAIL(ERROR_MESSAGE_PREFIX L\"Unsupported enum value.\");"); writer.WriteLine(L"#undef ERROR_MESSAGE_PREFIX"); writer.WriteLine(L"\t}"); writer.WriteLine(L""); } void GenerateStructDeserializerFunctionImpl(Ptr<GuiRpStructDecl> structDecl, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config, stream::TextWriter& writer) { WString cppName = GuiRpPrintTypeVisitor::GetCppTypeForJson(structDecl->name.value, symbols, config); GenerateDeserializerFunctionHeader(cppName, false, writer); writer.WriteLine(L"\t{"); writer.WriteLine(L"#define ERROR_MESSAGE_PREFIX L\"vl::presentation::remoteprotocol::ConvertJsonToCustomType<" + cppName + L">(Ptr<JsonNode>, " + cppName + L"&)#\""); writer.WriteLine(L"\t\tauto jsonNode = node.Cast<glr::json::JsonObject>();"); writer.WriteLine(L"\t\tCHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L\"Json node does not match the expected type.\");"); writer.WriteLine(L"\t\tfor (auto field : jsonNode->fields)"); writer.WriteLine(L"\t\t{"); for (auto member : structDecl->members) { writer.WriteLine(L"\t\t\tif (field->name.value == L\"" + member->name.value + L"\") ConvertJsonToCustomType(field->value, value." + member->name.value + L"); else"); } writer.WriteLine(L"\t\t\tCHECK_FAIL(ERROR_MESSAGE_PREFIX L\"Unsupported struct member.\");"); writer.WriteLine(L"\t\t}"); writer.WriteLine(L"#undef ERROR_MESSAGE_PREFIX"); writer.WriteLine(L"\t}"); writer.WriteLine(L""); } void GenerateRemoteProtocolCppFile(Ptr<GuiRpSchema> schema, Ptr<GuiRpSymbols> symbols, GuiRpCppConfig& config, stream::TextWriter& writer) { writer.WriteLine(L"/***********************************************************************"); writer.WriteLine(L"This file is generated by : Vczh GacUI Remote Protocol Generator"); writer.WriteLine(L"Licensed under https ://github.com/vczh-libraries/License"); writer.WriteLine(L"***********************************************************************/"); writer.WriteLine(L""); writer.WriteLine(L"#include \"" + config.headerFileName + L"\""); writer.WriteLine(L""); writer.WriteLine(L"namespace " + config.cppNamespace); writer.WriteLine(L"{"); for (auto enumDecl : From(schema->declarations).FindType<GuiRpEnumDecl>()) { GenerateEnumSerializerFunctionImpl(enumDecl, symbols, config, writer); } for (auto structDecl : From(schema->declarations).FindType<GuiRpStructDecl>()) { GenerateStructSerializerFunctionImpl(structDecl, symbols, config, writer); } for (auto enumDecl : From(schema->declarations).FindType<GuiRpEnumDecl>()) { GenerateEnumDeserializerFunctionImpl(enumDecl, symbols, config, writer); } for (auto structDecl : From(schema->declarations).FindType<GuiRpStructDecl>()) { GenerateStructDeserializerFunctionImpl(structDecl, symbols, config, writer); } writer.WriteLine(L"}"); } } /*********************************************************************** .\REMOTEPROTOCOL\GENERATED\GUIREMOTEPROTOCOLAST.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:Ast Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::remoteprotocol { /*********************************************************************** Visitor Pattern Implementation ***********************************************************************/ void GuiRpPrimitiveType::Accept(GuiRpType::IVisitor* visitor) { visitor->Visit(this); } void GuiRpReferenceType::Accept(GuiRpType::IVisitor* visitor) { visitor->Visit(this); } void GuiRpOptionalType::Accept(GuiRpType::IVisitor* visitor) { visitor->Visit(this); } void GuiRpArrayType::Accept(GuiRpType::IVisitor* visitor) { visitor->Visit(this); } void GuiRpArrayMapType::Accept(GuiRpType::IVisitor* visitor) { visitor->Visit(this); } void GuiRpMapType::Accept(GuiRpType::IVisitor* visitor) { visitor->Visit(this); } void GuiRpEnumDecl::Accept(GuiRpDeclaration::IVisitor* visitor) { visitor->Visit(this); } void GuiRpUnionDecl::Accept(GuiRpDeclaration::IVisitor* visitor) { visitor->Visit(this); } void GuiRpStructDecl::Accept(GuiRpDeclaration::IVisitor* visitor) { visitor->Visit(this); } void GuiRpMessageDecl::Accept(GuiRpDeclaration::IVisitor* visitor) { visitor->Visit(this); } void GuiRpEventDecl::Accept(GuiRpDeclaration::IVisitor* visitor) { visitor->Visit(this); } } namespace vl::reflection::description { #ifndef VCZH_DEBUG_NO_REFLECTION IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpType, presentation::remoteprotocol::GuiRpType) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpType::IVisitor, presentation::remoteprotocol::GuiRpType::IVisitor) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpPrimitiveTypes, presentation::remoteprotocol::GuiRpPrimitiveTypes) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpPrimitiveType, presentation::remoteprotocol::GuiRpPrimitiveType) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpReferenceType, presentation::remoteprotocol::GuiRpReferenceType) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpOptionalType, presentation::remoteprotocol::GuiRpOptionalType) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpArrayType, presentation::remoteprotocol::GuiRpArrayType) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpArrayMapType, presentation::remoteprotocol::GuiRpArrayMapType) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpMapType, presentation::remoteprotocol::GuiRpMapType) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpAttribute, presentation::remoteprotocol::GuiRpAttribute) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpDeclaration, presentation::remoteprotocol::GuiRpDeclaration) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpDeclaration::IVisitor, presentation::remoteprotocol::GuiRpDeclaration::IVisitor) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpEnumMember, presentation::remoteprotocol::GuiRpEnumMember) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpEnumDecl, presentation::remoteprotocol::GuiRpEnumDecl) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpUnionMember, presentation::remoteprotocol::GuiRpUnionMember) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpUnionDecl, presentation::remoteprotocol::GuiRpUnionDecl) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpStructMember, presentation::remoteprotocol::GuiRpStructMember) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpStructType, presentation::remoteprotocol::GuiRpStructType) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpStructDecl, presentation::remoteprotocol::GuiRpStructDecl) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpMessageRequest, presentation::remoteprotocol::GuiRpMessageRequest) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpMessageResponse, presentation::remoteprotocol::GuiRpMessageResponse) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpMessageDecl, presentation::remoteprotocol::GuiRpMessageDecl) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpEventRequest, presentation::remoteprotocol::GuiRpEventRequest) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpEventDecl, presentation::remoteprotocol::GuiRpEventDecl) IMPL_TYPE_INFO_RENAME(vl::presentation::remoteprotocol::GuiRpSchema, presentation::remoteprotocol::GuiRpSchema) #ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpType) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpType) BEGIN_ENUM_ITEM(vl::presentation::remoteprotocol::GuiRpPrimitiveTypes) ENUM_ITEM_NAMESPACE(vl::presentation::remoteprotocol::GuiRpPrimitiveTypes) ENUM_NAMESPACE_ITEM(Boolean) ENUM_NAMESPACE_ITEM(Integer) ENUM_NAMESPACE_ITEM(Float) ENUM_NAMESPACE_ITEM(Double) ENUM_NAMESPACE_ITEM(String) ENUM_NAMESPACE_ITEM(Char) ENUM_NAMESPACE_ITEM(Key) ENUM_NAMESPACE_ITEM(Color) ENUM_NAMESPACE_ITEM(Binary) END_ENUM_ITEM(vl::presentation::remoteprotocol::GuiRpPrimitiveTypes) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpPrimitiveType) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpType) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpPrimitiveType>(), NO_PARAMETER) CLASS_MEMBER_FIELD(type) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpPrimitiveType) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpReferenceType) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpType) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpReferenceType>(), NO_PARAMETER) CLASS_MEMBER_FIELD(name) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpReferenceType) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpOptionalType) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpType) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpOptionalType>(), NO_PARAMETER) CLASS_MEMBER_FIELD(element) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpOptionalType) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpArrayType) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpType) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpArrayType>(), NO_PARAMETER) CLASS_MEMBER_FIELD(element) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpArrayType) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpArrayMapType) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpType) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpArrayMapType>(), NO_PARAMETER) CLASS_MEMBER_FIELD(element) CLASS_MEMBER_FIELD(keyField) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpArrayMapType) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpMapType) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpType) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpMapType>(), NO_PARAMETER) CLASS_MEMBER_FIELD(element) CLASS_MEMBER_FIELD(keyType) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpMapType) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpAttribute) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpAttribute>(), NO_PARAMETER) CLASS_MEMBER_FIELD(name) CLASS_MEMBER_FIELD(cppType) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpAttribute) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpDeclaration) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_FIELD(attributes) CLASS_MEMBER_FIELD(name) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpDeclaration) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpEnumMember) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpEnumMember>(), NO_PARAMETER) CLASS_MEMBER_FIELD(name) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpEnumMember) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpEnumDecl) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpDeclaration) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpEnumDecl>(), NO_PARAMETER) CLASS_MEMBER_FIELD(members) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpEnumDecl) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpUnionMember) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpUnionMember>(), NO_PARAMETER) CLASS_MEMBER_FIELD(name) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpUnionMember) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpUnionDecl) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpDeclaration) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpUnionDecl>(), NO_PARAMETER) CLASS_MEMBER_FIELD(members) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpUnionDecl) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpStructMember) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpStructMember>(), NO_PARAMETER) CLASS_MEMBER_FIELD(name) CLASS_MEMBER_FIELD(type) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpStructMember) BEGIN_ENUM_ITEM(vl::presentation::remoteprotocol::GuiRpStructType) ENUM_ITEM_NAMESPACE(vl::presentation::remoteprotocol::GuiRpStructType) ENUM_NAMESPACE_ITEM(Struct) ENUM_NAMESPACE_ITEM(Class) END_ENUM_ITEM(vl::presentation::remoteprotocol::GuiRpStructType) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpStructDecl) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpDeclaration) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpStructDecl>(), NO_PARAMETER) CLASS_MEMBER_FIELD(type) CLASS_MEMBER_FIELD(members) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpStructDecl) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpMessageRequest) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpMessageRequest>(), NO_PARAMETER) CLASS_MEMBER_FIELD(type) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpMessageRequest) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpMessageResponse) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpMessageResponse>(), NO_PARAMETER) CLASS_MEMBER_FIELD(type) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpMessageResponse) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpMessageDecl) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpDeclaration) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpMessageDecl>(), NO_PARAMETER) CLASS_MEMBER_FIELD(request) CLASS_MEMBER_FIELD(response) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpMessageDecl) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpEventRequest) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpEventRequest>(), NO_PARAMETER) CLASS_MEMBER_FIELD(type) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpEventRequest) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpEventDecl) CLASS_MEMBER_BASE(vl::presentation::remoteprotocol::GuiRpDeclaration) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpEventDecl>(), NO_PARAMETER) CLASS_MEMBER_FIELD(request) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpEventDecl) BEGIN_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpSchema) CLASS_MEMBER_BASE(vl::glr::ParsingAstBase) CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::presentation::remoteprotocol::GuiRpSchema>(), NO_PARAMETER) CLASS_MEMBER_FIELD(declarations) END_CLASS_MEMBER(vl::presentation::remoteprotocol::GuiRpSchema) BEGIN_INTERFACE_MEMBER(vl::presentation::remoteprotocol::GuiRpType::IVisitor) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpType::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpPrimitiveType* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpType::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpReferenceType* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpType::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpOptionalType* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpType::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpArrayType* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpType::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpArrayMapType* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpType::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpMapType* node)) END_INTERFACE_MEMBER(vl::presentation::remoteprotocol::GuiRpType) BEGIN_INTERFACE_MEMBER(vl::presentation::remoteprotocol::GuiRpDeclaration::IVisitor) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpDeclaration::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpEnumDecl* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpDeclaration::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpUnionDecl* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpDeclaration::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpStructDecl* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpDeclaration::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpMessageDecl* node)) CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::presentation::remoteprotocol::GuiRpDeclaration::IVisitor::*)(vl::presentation::remoteprotocol::GuiRpEventDecl* node)) END_INTERFACE_MEMBER(vl::presentation::remoteprotocol::GuiRpDeclaration) #endif #ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA class GuiRemoteProtocolAstTypeLoader : public vl::Object, public ITypeLoader { public: void Load(ITypeManager* manager) { ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpType) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpType::IVisitor) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpPrimitiveTypes) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpPrimitiveType) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpReferenceType) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpOptionalType) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpArrayType) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpArrayMapType) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpMapType) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpAttribute) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpDeclaration) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpDeclaration::IVisitor) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpEnumMember) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpEnumDecl) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpUnionMember) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpUnionDecl) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpStructMember) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpStructType) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpStructDecl) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpMessageRequest) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpMessageResponse) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpMessageDecl) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpEventRequest) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpEventDecl) ADD_TYPE_INFO(vl::presentation::remoteprotocol::GuiRpSchema) } void Unload(ITypeManager* manager) { } }; #endif #endif bool GuiRemoteProtocolAstLoadTypes() { #ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA if (auto manager = GetGlobalTypeManager()) { auto loader = Ptr(new GuiRemoteProtocolAstTypeLoader); return manager->AddTypeLoader(loader); } #endif return false; } } /*********************************************************************** .\REMOTEPROTOCOL\GENERATED\GUIREMOTEPROTOCOLAST_JSON.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:Ast Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::remoteprotocol::json_visitor { void AstVisitor::PrintFields(GuiRpArrayMapType* node) { BeginField(vl::WString::Unmanaged(L"element")); WriteToken(node->element); EndField(); BeginField(vl::WString::Unmanaged(L"keyField")); WriteToken(node->keyField); EndField(); } void AstVisitor::PrintFields(GuiRpArrayType* node) { BeginField(vl::WString::Unmanaged(L"element")); Print(node->element.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpAttribute* node) { BeginField(vl::WString::Unmanaged(L"cppType")); WriteToken(node->cppType); EndField(); BeginField(vl::WString::Unmanaged(L"name")); WriteToken(node->name); EndField(); } void AstVisitor::PrintFields(GuiRpDeclaration* node) { BeginField(vl::WString::Unmanaged(L"attributes")); BeginArray(); for (auto&& listItem : node->attributes) { BeginArrayItem(); Print(listItem.Obj()); EndArrayItem(); } EndArray(); EndField(); BeginField(vl::WString::Unmanaged(L"name")); WriteToken(node->name); EndField(); } void AstVisitor::PrintFields(GuiRpEnumDecl* node) { BeginField(vl::WString::Unmanaged(L"members")); BeginArray(); for (auto&& listItem : node->members) { BeginArrayItem(); Print(listItem.Obj()); EndArrayItem(); } EndArray(); EndField(); } void AstVisitor::PrintFields(GuiRpEnumMember* node) { BeginField(vl::WString::Unmanaged(L"name")); WriteToken(node->name); EndField(); } void AstVisitor::PrintFields(GuiRpEventDecl* node) { BeginField(vl::WString::Unmanaged(L"request")); Print(node->request.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpEventRequest* node) { BeginField(vl::WString::Unmanaged(L"type")); Print(node->type.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpMapType* node) { BeginField(vl::WString::Unmanaged(L"element")); Print(node->element.Obj()); EndField(); BeginField(vl::WString::Unmanaged(L"keyType")); Print(node->keyType.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpMessageDecl* node) { BeginField(vl::WString::Unmanaged(L"request")); Print(node->request.Obj()); EndField(); BeginField(vl::WString::Unmanaged(L"response")); Print(node->response.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpMessageRequest* node) { BeginField(vl::WString::Unmanaged(L"type")); Print(node->type.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpMessageResponse* node) { BeginField(vl::WString::Unmanaged(L"type")); Print(node->type.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpOptionalType* node) { BeginField(vl::WString::Unmanaged(L"element")); Print(node->element.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpPrimitiveType* node) { BeginField(vl::WString::Unmanaged(L"type")); switch (node->type) { case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Binary: WriteString(vl::WString::Unmanaged(L"Binary")); break; case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Boolean: WriteString(vl::WString::Unmanaged(L"Boolean")); break; case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Char: WriteString(vl::WString::Unmanaged(L"Char")); break; case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Color: WriteString(vl::WString::Unmanaged(L"Color")); break; case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Double: WriteString(vl::WString::Unmanaged(L"Double")); break; case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Float: WriteString(vl::WString::Unmanaged(L"Float")); break; case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Integer: WriteString(vl::WString::Unmanaged(L"Integer")); break; case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Key: WriteString(vl::WString::Unmanaged(L"Key")); break; case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::String: WriteString(vl::WString::Unmanaged(L"String")); break; default: WriteNull(); } EndField(); } void AstVisitor::PrintFields(GuiRpReferenceType* node) { BeginField(vl::WString::Unmanaged(L"name")); WriteToken(node->name); EndField(); } void AstVisitor::PrintFields(GuiRpSchema* node) { BeginField(vl::WString::Unmanaged(L"declarations")); BeginArray(); for (auto&& listItem : node->declarations) { BeginArrayItem(); Print(listItem.Obj()); EndArrayItem(); } EndArray(); EndField(); } void AstVisitor::PrintFields(GuiRpStructDecl* node) { BeginField(vl::WString::Unmanaged(L"members")); BeginArray(); for (auto&& listItem : node->members) { BeginArrayItem(); Print(listItem.Obj()); EndArrayItem(); } EndArray(); EndField(); BeginField(vl::WString::Unmanaged(L"type")); switch (node->type) { case vl::presentation::remoteprotocol::GuiRpStructType::Class: WriteString(vl::WString::Unmanaged(L"Class")); break; case vl::presentation::remoteprotocol::GuiRpStructType::Struct: WriteString(vl::WString::Unmanaged(L"Struct")); break; default: WriteNull(); } EndField(); } void AstVisitor::PrintFields(GuiRpStructMember* node) { BeginField(vl::WString::Unmanaged(L"name")); WriteToken(node->name); EndField(); BeginField(vl::WString::Unmanaged(L"type")); Print(node->type.Obj()); EndField(); } void AstVisitor::PrintFields(GuiRpType* node) { } void AstVisitor::PrintFields(GuiRpUnionDecl* node) { BeginField(vl::WString::Unmanaged(L"members")); BeginArray(); for (auto&& listItem : node->members) { BeginArrayItem(); Print(listItem.Obj()); EndArrayItem(); } EndArray(); EndField(); } void AstVisitor::PrintFields(GuiRpUnionMember* node) { BeginField(vl::WString::Unmanaged(L"name")); WriteToken(node->name); EndField(); } void AstVisitor::Visit(GuiRpPrimitiveType* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"PrimitiveType"), node); PrintFields(static_cast<GuiRpType*>(node)); PrintFields(static_cast<GuiRpPrimitiveType*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpReferenceType* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"ReferenceType"), node); PrintFields(static_cast<GuiRpType*>(node)); PrintFields(static_cast<GuiRpReferenceType*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpOptionalType* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"OptionalType"), node); PrintFields(static_cast<GuiRpType*>(node)); PrintFields(static_cast<GuiRpOptionalType*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpArrayType* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"ArrayType"), node); PrintFields(static_cast<GuiRpType*>(node)); PrintFields(static_cast<GuiRpArrayType*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpArrayMapType* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"ArrayMapType"), node); PrintFields(static_cast<GuiRpType*>(node)); PrintFields(static_cast<GuiRpArrayMapType*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpMapType* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"MapType"), node); PrintFields(static_cast<GuiRpType*>(node)); PrintFields(static_cast<GuiRpMapType*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpEnumDecl* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"EnumDecl"), node); PrintFields(static_cast<GuiRpDeclaration*>(node)); PrintFields(static_cast<GuiRpEnumDecl*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpUnionDecl* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"UnionDecl"), node); PrintFields(static_cast<GuiRpDeclaration*>(node)); PrintFields(static_cast<GuiRpUnionDecl*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpStructDecl* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"StructDecl"), node); PrintFields(static_cast<GuiRpDeclaration*>(node)); PrintFields(static_cast<GuiRpStructDecl*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpMessageDecl* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"MessageDecl"), node); PrintFields(static_cast<GuiRpDeclaration*>(node)); PrintFields(static_cast<GuiRpMessageDecl*>(node)); EndObject(); } void AstVisitor::Visit(GuiRpEventDecl* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"EventDecl"), node); PrintFields(static_cast<GuiRpDeclaration*>(node)); PrintFields(static_cast<GuiRpEventDecl*>(node)); EndObject(); } AstVisitor::AstVisitor(vl::stream::StreamWriter& _writer) : vl::glr::JsonVisitorBase(_writer) { } void AstVisitor::Print(GuiRpType* node) { if (!node) { WriteNull(); return; } node->Accept(static_cast<GuiRpType::IVisitor*>(this)); } void AstVisitor::Print(GuiRpDeclaration* node) { if (!node) { WriteNull(); return; } node->Accept(static_cast<GuiRpDeclaration::IVisitor*>(this)); } void AstVisitor::Print(GuiRpAttribute* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"Attribute"), node); PrintFields(static_cast<GuiRpAttribute*>(node)); EndObject(); } void AstVisitor::Print(GuiRpEnumMember* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"EnumMember"), node); PrintFields(static_cast<GuiRpEnumMember*>(node)); EndObject(); } void AstVisitor::Print(GuiRpUnionMember* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"UnionMember"), node); PrintFields(static_cast<GuiRpUnionMember*>(node)); EndObject(); } void AstVisitor::Print(GuiRpStructMember* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"StructMember"), node); PrintFields(static_cast<GuiRpStructMember*>(node)); EndObject(); } void AstVisitor::Print(GuiRpMessageRequest* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"MessageRequest"), node); PrintFields(static_cast<GuiRpMessageRequest*>(node)); EndObject(); } void AstVisitor::Print(GuiRpMessageResponse* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"MessageResponse"), node); PrintFields(static_cast<GuiRpMessageResponse*>(node)); EndObject(); } void AstVisitor::Print(GuiRpEventRequest* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"EventRequest"), node); PrintFields(static_cast<GuiRpEventRequest*>(node)); EndObject(); } void AstVisitor::Print(GuiRpSchema* node) { if (!node) { WriteNull(); return; } BeginObject(); WriteType(vl::WString::Unmanaged(L"Schema"), node); PrintFields(static_cast<GuiRpSchema*>(node)); EndObject(); } } /*********************************************************************** .\REMOTEPROTOCOL\GENERATED\GUIREMOTEPROTOCOLPARSER.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:GuiRemoteProtocol Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::remoteprotocol { void GuiRemoteProtocolParserData(vl::stream::IStream& outputStream) { static const vl::vint dataLength = 7660; // 109122 bytes before compressing static const vl::vint dataBlock = 256; static const vl::vint dataRemain = 236; static const vl::vint dataSolidRows = 29; static const vl::vint dataRows = 30; static const char* compressed[] = { "\x42\xAA\x01\x00\xE4\x1D\x00\x00\x21\x00\x01\x82\x80\x02\x0B\x82\x81\x82\x06\x89\x82\x9F\x7C\x85\x84\x87\x0C\x0A\x80\x89\x85\x1A\x84\x16\x84\x18\x0A\xB7\x0A\x9E\x1A\x84\x22\x84\x25\x0A\xD0\x0A\x96\x2A\x86\x2E\x84\x32\x0A\xEB\x0A\x92\x3A\x86\x3A\x84\x57\x10\x09\x8E\x8E\x8A\x80\x03\x99\x86\x35\xB7\x8C\x99\x9A\x9C\x9F\x9A\x9F\x33\xC0\xB4\x8A\x8A\x9F\x7E\xA0\x9C\x44\xBD\x89\xBF\x95\x9A\x85\x00\xA7\x50\x89\x82\x11\xA6\x83\x00\xAB\x81\x04\x57\x82\x85\x0A\xA9\x82\x03\xAE\x00\x07\x20\xA8\x00\xB5\xA3\xA3\x9D\x0A\x89\x25\xAA\xA2\x9C\xB6\x82\xB3\x4B\xC1\xB1\xA3\xAD\xB4\xA5\xBA\xB9\x77\xF4\xAF\xAE\xB3\x80\xB9\xBC\xA4\x7F\xE8\x81\xC6\xA3\xB8\xC3\xBC\xBB\x87\xF8\x89\xDA\xBD\xBC\xBF\x84\xC7\x01\xFE\x8B\xC6\xCD\xC0\xC5\xCA\xC5\x97\x8C\xCF\xD6\xCB\xC8\xCD\xCE\xCD\x91\x90\xF6\x82\xD2\xC9\xCC\xCB\xCF\xA7\xA1\xDC\xCA\xDE\xCC\xD4\xD1\xD1\xAB\xB0\xED\xD2\xDF\xD5\xD0\xD4\xC1\x93\xB8\xE6\xDA\xD7\xDC\xC3\xC1\xB3\xBE\xB9\xC1\xFB\xD3\xE2\x82\x04\xB0\x0B\x0A\x96\xBF\xD5\xC4\xDE\xD7\xD4\xB4\xD0\xF6\xCF\xEE\xE1\xE9\xEB\xE9\xD6\xC5\xD4\xFA", "\xE9\xE8\xE2\xEF\xE6\xDC\xD8\xE2\xE4\xD4\xF1\xDB\xF0\xF3\xE5\xB3\xE7\xEA\xF9\xF5\xD9\xF6\xE9\xEF\xD7\xF1\xFC\xEE\x00\xB3\x06\xE5\xE0\xDF\xCC\xFB\xF2\xE2\xFD\xFF\xFC\x00\xBC\x74\x72\x7F\x03\x81\x8F\x7E\x80\xBD\x44\x89\x82\x81\x05\x88\x8B\x76\x82\x0F\x8C\x8B\x82\x83\xDD\x52\x81\x84\x85\xD8\x48\x46\x43\x53\x09\x53\x08\x7C\x86\xF3\x50\x85\x84\x88\xE8\x65\x8C\x7A\x89\xEE\x68\x80\x7E\x8A\xF2\x6C\x81\x79\x88\x16\xA3\x87\x83\x8C\x0D\xB4\x83\x86\x8D\x17\xB8\x82\x8D\x8D\x3C\xB7\x83\x42\x05\x60\x57\x0F\x86\x8E\xEB\x69\x87\x8B\x91\x46\x89\x9B\x88\x92\x4B\x8A\x9D\x88\x93\x4F\x8E\x9F\x8A\x8B\x22\x85\x9D\x93\x95\x51\x98\x93\x94\x94\x5B\x92\x95\x94\x8C\x14\x9A\x00\x5B\x06\x43\xBD\x89\x8E\x99\x3B\xBE\x8A\x9B\x99\x6B\xA9\x9C\x9B\x9B\x6E\xB1\x96\x95\x96\x74\x9D\x9A\x97\x97\x54\xB1\x83\x9E\x9D\x75\xB8\x9C\x96\x9F\x5E\x8A\x4E\x04\x58\x1F\x25\x9D\x9B\x9E\x80\xB7\x9A\x9C\x98\x44\x8C\xA8\x98\xA2\x8B\xB9\x94\x8B\x9F\x91\x94\xA3\xA5\xA0\x97\x8A\xA9\xA5\x9F\x0A\x62\x00\x5B\x08\x86\xB0\x90\xA7\xA6\x7C\xA5\xA9\xA0\xA7\xA4\xA7\xA6\xA9\xA5", "\x98\x8D\xA2\xA6\xAB\x96\xB0\xAD\xAB\xA3\x8E\x87\xA5\xAD\x40\x26\x20\x57\x09\xA8\x72\xB7\xAD\xAF\xAB\xB4\x80\xB6\xAE\xB0\xA2\xBE\xA3\xAA\xAC\x9A\x88\xB8\xAA\xB2\xAB\xA9\xAC\xA9\xB2\xC1\xB3\x6A\x08\x58\x2B\x3C\xA7\xB1\xB4\xB3\x83\xB1\xAC\xB6\xD0\x9A\xB9\xB5\xB1\xC4\xBF\xAB\xB6\xB7\xDD\xA0\xB3\xBA\xB9\xDF\xA2\xB9\xBB\xB5\xE4\x8B\xBC\xB6\xBB\xED\x8D\xBC\xB2\xAA\xF4\x8F\xB0\xBC\xBA\xE5\x80\x0E\x0B\x5A\xE1\xAC\xB8\xBF\xBD\xEA\xB9\xBE\xBC\x00\x2F\x20\x58\x45\x42\xCB\x73\xB6\xBE\xBC\xEF\x8C\xC1\xBD\xBD\xCE\x91\xCA\xC2\xC4\x0D\xD0\xC3\xC7\xC5\x15\xCB\xC6\xC5\xC6\x14\xCF\xCA\xC7\xC7\x1D\xFF\xBE\xC2\xC8\x1B\xDE\xC1\xC9\xC0\xD5\x73\x0C\xBF\xB9\x28\xE3\xCD\xC9\xC9\x24\xE0\xC8\xC6\xC9\x33\xF1\xC7\xCB\xC0\x38\xC6\xBA\xCD\xBF\x3B\xEC\xC9\xCD\x6C\x34\x2B\xC9\xB9\x0D\x60\x76\x06\xB5\xCF\xEB\x88\xD2\xC2\xD2\x00\xFF\xCE\xCC\xD3\x2E\xCE\xD9\xD0\xCF\x54\xCF\xD5\xD7\x6B\x39\x20\x5A\x0F\xD1\x57\xCB\xDD\xD5\xD3\x50\xF0\xCF\xCA\xCC\x1C\xF5\xC3\xDB\xCD\x61\xE4\xD4\xCD\xD9\x6C\xEB\xDE\xDA\xCD\x66\xD2\xDE\xD6\xD5\x74\xD3\xD5\xDF\xDC\xAF", "\x7D\x02\xD0\xDE\x7C\xE0\xDF\xD5\xD4\x69\xE8\xDF\xDE\x88\x1C\x49\x4C\x86\x41\x3F\x20\x50\x10\x58\x41\x20\x52\x10\x58\x43\x20\x5E\x46\xE1\x0A\x45\x10\x5A\x11\x7B\xC0\xC7\x11\xE6\x80\xC3\xEA\xD8\xDC\x6D\xF0\x98\x10\x58\x49\x1C\xD7\xDE\xDF\xA7\xDD\xE9\xEA\xD8\x72\xE8\xE6\xDF\xEB\x7D\xEA\xE0\xEE\xEB\xB1\xEC\xE1\xE1\xDC\xB7\xE1\xE7\xD8\xEE\x9E\xC2\xEB\xEB\xE7\x71\x8C\x1C\xE6\xED\xBD\xFC\xEF\xEE\xEF\xB3\xF2\xE5\xEC\xF0\xAD\xCA\xF4\xEF\xF3\xCE\xD1\xF4\xF3\xF1\x3A\x8D\x13\xF0\xF3\xB9\xEF\xDB\xEE\xEE\xCD\xD3\xF9\xF2\xF7\xCB\xD4\x8E\x13\xF5\xC8\xE1\xF6\xF3\xF7\xD8\xC5\xFC\xF5\xF6\xA0\xDA\xFD\xF5\xFA\xD4\xE8\x9F\x10\xF9\xE7\xE6\xFB\xF9\x6C\x22\x54\xE9\x41\x14\xA6\xE8\xF5\xF8\xF4\xE0\x60\x80\xFC\x7E\x75\x7E\x01\x89\x24\x0A\xF4\x77\x7D\xFC\x6E\x7C\x7D\xED\x4C\x82\x7D\x0F\x8B\x81\xFB\x13\x8E\x80\x0A\xAF\x79\x21\x55\x09\x81\x04\x84\x8A\x80\x0E\x9B\x86\x7E\x1F\x86\x81\x01\xD2\x73\x80\x10\x96\x85\x81\x17\x83\x85\x00\xA4\x8F\x7E\x16\xAA\x85\x84\x22\x9D\x82\x09\x80\x04\x24\xFD\x6F\x85\x85\x2B\x99\x84\x0C\xAE\x82\x87\x18\xA1\x84", "\x87\x3F\x9A\x84\x0E\xBB\x85\x27\x2B\x20\x28\x0B\x1A\x87\x84\x04\xCA\x82\x83\x0A\x8E\x89\x85\x3D\x80\x88\x13\x9E\x83\x8B\x19\x99\x09\x89\x4F\x88\x86\xAF\x5A\x08\x8A\x28\x81\x8C\x88\x60\x83\x8A\x18\xB7\x84\x8D\x28\x82\x8D\x8C\x5F\x83\x8E\x19\xE1\x88\x8D\x2A\xBE\x86\x8D\x52\x99\x89\x6C\x5B\x0D\x8A\x2D\x8B\x8A\x8E\x4D\x9E\x88\x1C\xE7\x8B\x8D\x93\x5C\x0D\x8E\x77\x9A\x8C\x1E\xD4\x83\x91\x19\x82\x97\x90\x76\x99\x8D\x22\x84\x98\x3B\x2E\x00\x92\x91\x81\x8B\x92\x21\x92\x9F\x8D\x42\x95\x90\x91\x91\x99\x90\x24\x9B\x9C\x90\x4A\xAE\x66\x24\x36\x9D\x8D\x1B\x96\x91\x8E\x4C\x9C\x93\x92\x9A\x9D\x91\x2A\xA8\x97\x95\x4B\x9E\x94\x8F\x69\x83\x96\x29\xAA\x9D\x95\x52\xBE\x57\x0B\x8F\x94\x95\xBA\x60\x09\x96\x56\xBA\x96\x97\xC0\x8E\x97\x2A\xC2\x95\x96\x58\xBB\x8C\x8D\xA2\x89\x99\x2C\xCA\x97\x98\x35\x8B\x9F\x99\xCD\x92\x97\x2B\xC8\x90\x9A\x52\x86\x9E\x9A\xD4\x90\x4D\x18\x3D\x94\x99\x5F\x9D\x99\x98\xB6\x83\x99\x38\xC5\x99\x9A\x6C\xA7\x62\x0C\x58\x83\x0C\x37\xE3\x9E\x9A\x76\xA0\x9F\x9A\xB3\x8F\x9D\x39\xF1\x90\x60\x94\x21\x95\x4D\x65\x0B", "\x9C\x3C\xD3\x94\x42\x33\x3A\x9B\x9E\xFC\x92\x9A\x38\xFB\x93\xA0\x80\x85\xA6\x99\xD1\x8C\x9A\x39\x82\xA4\x9C\x84\x8B\xA2\x77\x67\x1F\x9E\x43\xF4\x9E\x9D\x6F\x96\xA5\xA2\x18\xA4\xA1\x43\xE6\x68\x0C\x89\x8C\xA5\x9D\x1A\xA0\xA6\x41\x9B\xAA\xA0\x8A\xA1\xA2\x9E\x13\xA1\xA2\x42\xE9\x0E\xA3\x92\xAA\xA5\x9A\x26\xA3\xA6\x48\xA9\xA7\xA1\x8F\xA8\xA6\xA6\x17\xA7\xA5\x4E\xB2\xA7\xA6\x97\xB5\xA3\x20\x6A\x0D\xA4\x4C\xBE\x5A\x25\x7B\x89\xA3\xA8\x3F\xA8\xA8\x49\xCA\xA3\xA6\x9C\x99\xA4\xA7\x3B\xB4\xA7\x52\xC7\xA4\xAB\x87\x8C\xAD\xA7\x57\xB1\xAA\x53\xBA\xAF\xA8\xA9\x8D\xA8\x4D\x6C\x02\xA9\x55\xB1\xAE\xAA\xAC\xA3\xAF\xA5\x67\xA9\xA9\x5A\xB3\x3D\x0C\x2C\xAE\x0A\xAC\x56\xAB\xAF\x57\xD9\xAD\xAB\xAD\x90\xAD\xAE\xBA\x6F\x0C\x16\xF0\x00\xAE\xB2\xB6\xA9\x21\x71\x1D\xAC\x5A\xF1\xA4\xB0\xBF\xBE\xA3\xAA\x85\xA3\xB2\x61\xF4\xAC\xAB\xC6\xB7\xAE\xB1\x0E\xAC\x26\x51\x89\xBA\xAC\xCA\x8D\x8B\x0E\x82\xB5\xB3\x62\xF2\xA6\xAC\xCB\xB3\xAC\xB3\x5A\xA7\xB3\x67\x9E\xBD\xB3\xCD\xA4\xB1\xB4\x8C\xAF\xB2\x6A\xE5\xA8\xB4\xD0\xB8\xA9\xB5\x0E\xB4\x0D\x66\x88", "\xB6\xB5\xDA\x8A\xB7\xB6\xB1\x35\x0C\x58\x2E\x23\xB3\x3B\x20\x28\x0F\x60\x39\x0C\x58\x7A\x00\x2D\x3D\x20\x2C\x0F\x60\x3D\x0C\x5C\xFE\x03\xB7\xD1\xB6\xB1\x5C\x7F\x0D\xB9\x69\xB8\xB4\xB6\xEA\x8E\xBE\xBA\xD3\xBA\xB0\x76\xAD\xB7\xB5\xD7\xAE\xB0\xB2\x7F\xA3\x94\x20\x52\xBC\xBB\xE7\x95\xBA\xBB\xE8\xA7\xBE\x7A\x84\x91\x10\xF2\x9E\xBD\xBB\xE0\xA2\xB5\x76\xEB\xB9\x5E\x41\x2E\xB9\xBE\xB0\xA1\xBE\x7C\xE5\xBB\xBB\xF7\xA6\xBF\xBA\xE9\xA0\xC1\x13\x83\x17\xBF\xD5\xBA\xB9\xBF\xFB\xB1\x8C\x21\x05\xCC\xB4\xFF\xBE\x55\x10\x0C\xC7\xC3\x77\x86\xC9\xC0\xB1\x46\x11\xC2\x15\xC5\x9F\x21\x18\xC8\xC1\x0E\xD3\xC5\xC1\xF8\xBF\xC2\x84\xF0\xB4\xC2\x0F\xE4\xC0\xC4\x25\xD4\x80\x22\x1C\xC2\xC5\x0C\xE8\xC4\x42\x89\x00\x2E\x22\x2C\xC7\xC5\x11\xFF\xBB\xBE\x02\xD9\xC4\x8E\xBB\xCC\xBF\x00\xFC\xC6\xC1\x3E\xDD\xC4\x62\x8B\x14\xC7\x1B\xC2\xCA\xC7\x47\xDF\xC5\x88\xB5\xCE\xC4\x1B\xFD\xBB\xC9\x46\xD1\x8C\x23\x45\xCF\xC9\x14\xC0\x05\x11\x54\xC1\xC8\x90\xF4\xB9\xC9\x2E\xDB\xC8\xC9\x5F\xCA\xCA\x95\xD1\xC0\xCB\x06\x8E\x11\xCB\x5C\xC1\xCE\x97\xCB\xCF\x10\x34", "\xE0\xCD\xCC\x5A\xD0\xCD\x9A\xF2\xCF\xCD\x31\xD5\xCF\xC5\x4E\xD1\xCE\x9D\xFA\xC8\xCE\xDD\x50\x10\x2C\x91\x00\x2E\x24\x60\x23\x12\xB0\x14\x10\x2C\x95\x00\x2E\x25\x60\x27\x12\xB0\x18\x10\xAE\x99\x0E\xCE\x98\xFD\xC2\x20\x4D\x12\xD3\xCD\x7B\xD3\xCD\xA6\xF5\xC4\xD3\x16\xE6\xC4\xCC\x9B\xD3\xD1\x9E\x9A\xDE\xA1\x4D\x17\xD2\xCD\xA8\xD4\xCE\xA8\xCD\xCC\xD4\x13\xDC\x17\xD4\xAA\xD8\xD0\x85\x1D\x10\xD7\x50\xF2\xD3\xD4\x9C\xD8\xD7\xAA\x9F\xD7\xCE\x5D\xF7\xD5\xD5\x9E\xC1\xD8\x93\xBC\xD1\x5C\x4F\x20\x2F\x13\x60\x20\x14\x58\x21\x10\x2C\x51\x20\x2B\x14\x60\x24\x14\x58\x25\x10\x2C\x53\x30\xAF\x14\xB5\xDD\xD3\xB0\x81\x28\x15\x6C\xFE\xD1\xD5\xB6\xC0\xDE\xB6\xA0\xD3\xDD\x5E\xC0\xDB\xDB\xE8\xC4\xDF\xB7\xE2\x69\x14\x6F\xE7\xDA\xDD\xEF\xC6\xDC\xB1\xA4\xD6\x6C\x55\x2E\xDB\xDE\xA3\xAB\x17\xBD\xC2\xD0\xDE\x7C\xFB\xD4\xDF\xF2\xC0\xE0\x9F\xEB\xD1\xDD\x58\xE2\xDC\xE0\xE5\xC3\xE1\xBC\x8A\xEA\x7A\x56\x3B\xD9\xDD\x01\xF0\xE3\x1D\xAD\x10\x2C\x57\x0F\xE5\xDF\x02\xF3\x37\x2B\x17\xE1\xE2\x8C\xD2\xE3\x36\xB0\x1C\xE0\xC3\x99\xEF\x35\x58\x22\xE4\xDE", "\x0B\xE8\xE6\xBF\xBF\xDB\xE5\x38\xB2\x17\xE4\xB9\xC8\x4F\x2C\x30\xEF\xDF\x8F\xF1\xE5\xE5\x06\xF9\xE5\xC1\xBB\xE9\xE0\x95\xE4\xE0\x3A\xB4\x14\xE4\xCB\xBF\xE3\xE9\x38\x75\x12\xE8\x07\xE9\xE7\xCD\xC4\xE9\xE8\x9C\xFC\xE0\xE1\x50\xEA\xE9\xCD\x9E\xE4\xEB\x8E\xE2\x36\x16\x60\x37\x14\x58\x38\x10\x2D\x5C\x20\x2A\x17\x60\x3B\x14\x58\x3C\x10\x2D\x5E\x20\x2E\x17\x70\xBF\x14\xD2\xBA\xE7\x64\x60\x2B\xEF\xE9\x52\xE5\xE9\xD5\xA3\xE6\xE7\xA9\xD6\xEC\xEE\x73\xFE\xE5\xDD\x80\x61\x19\xB7\xFD\xE3\xE9\x7B\xED\xE8\xD3\xEC\xE6\x20\x61\x3E\xE9\xEA\x4E\xE9\x23\x30\x07\xF1\xEE\xC1\xC1\xF4\xF0\x8D\xF0\xF1\xE2\x88\xF3\xF0\xB8\xD3\xF1\xF2\x96\xF5\xF3\xDF\xB3\x84\x18\xC6\xD7\xF7\xF3\x9A\xE6\x21\x31\x1E\xF1\xF4\xCC\xC9\x26\x18\xA4\xEF\xF1\xE6\xAA\xFB\xF2\xB9\xD1\xE7\x18\xA9\xFE\xE0\x32\x31\xF7\xEE\xBD\xF9\xE8\xF0\xB7\xF6\xEC\xDE\xB5\xF8\xF6\xDE\xF9\x59\x19\xB4\xFB\xF5\x65\xCA\x10\x2D\x65\x20\x2C\x19\x60\x2D\x18\x58\x4E\x10\xAF\x67\x01\xFE\xF6\xBE\xEE\xF6\xF0\xD0\xF3\xFB\xDE\xD5\xFA\xF7\xD4\xE8\xB0\x34\x4F\xF6\xFB\xEC\xDD\xFF\xFB\xD8\xE3\xB5", "\x34\x5C\xF1\xFD\xF2\xD2\xFE\xFB\xE6\xEF\xBE\x34\x64\xF7\xFC\xF0\xED\xF9\xFD\x92\xF5\xAB\x34\x6C\xFE\xF1\xDC\xEF\xFF\xFE\xF5\xE3\xB0\x35\x74\xF1\xFE\xD6\xD4\xF6\xFF\xA6\x7F\x7F\xD8\x15\x0D\x60\x16\x0D\x60\x17\x0D\x60\x18\x0D\x60\x19\x0D\x70\x5A\x0D\xFC\x7B\x7A\x82\x4B\x0D\x0F\x8D\x7A\xF9\x77\x7D\xF8\x7D\x7F\xF6\x75\x81\xE8\x75\x1D\xDC\x00\x16\xDD\x00\x16\xDE\x00\x16\xDF\x00\x16\xE0\x00\x57\xE1\x03\x81\x02\x8D\x40\xE2\x08\x82\x0A\x53\x0E\x2C\x80\x7A\x00\x80\x83\x19\x88\x81\x11\x74\x0E\x60\x15\x0E\x60\x16\x0E\x60\x17\x0E\x60\x18\x0E\x70\x59\x0E\x2F\x85\x7A\xD5\x4A\x0E\x41\x81\x83\x42\x87\x84\x46\x89\x84\x33\x80\x81\xBE\x2B\x0E\x70\x5C\x0E\x60\x1D\x0E\x60\x1E\x0E\x60\x1F\x0E\x60\x10\x0F\x70\x51\x0F\x45\x8B\x84\x27\x32\x0F\x5B\x8D\x40\xF3\x00\x57\xF4\x00\x16\xF5\x00\x16\xF6\x00\x16\xF7\x00\x16\xF8\x00\x57\xF9\x0F\x85\x16\x81\x47\xFA\x0E\x86\x4D\x41\x0B\x53\x16\x10\x75\x82\x1C\x03\x37\x87\xC4\x19\x87\xE0\x1C\x87\x83\x1E\x87\x78\x8E\x2B\x7A\x8D\x1B\x80\x8B\x87\x82\x8D\x87\x87\x8F\x87\x89\x81\x88\xE1\x27\x38\x03\x14", "\x16\x93\x59\x15\x09\x1D\x00\xE0\x1C\x15\x09\x1A\x21\x03\x1E\x88\x02\x12\x16\x8A\x87\x13\x9A\x81\x10\x90\x8B\x21\x0A\x12\x89\x06\x14\x89\x83\x16\x89\x06\x18\x89\x02\x1F\x89\x61\x18\x88\x37\x13\x88\xDB\x15\x14\x09\x38\x26\xAC\x81\x8A\x99\x83\x8A\x0A\x16\x8A\xC2\x18\x8A\x03\x1A\x8A\x01\x1C\x8A\x9C\x8C\x88\x33\x10\x8B\xD9\x12\x8B\x31\x25\x8B\x60\x14\x8A\x03\x1A\x8B\xC4\x1C\x8B\x07\x10\x16\xC1\x86\x88\xAF\x8E\x8A\x33\x13\x8B\x6D\x2C\x8A\x35\x1C\x8A\xCA\x82\x10\xCC\x8D\x1B\xCE\x81\x10\xBE\x80\x00\xC0\x84\x8D\x0E\x18\x8D\xC9\x89\x8B\x95\x8A\x10\xE1\x83\x8E\x9D\x83\x8C\xE4\x8D\x10\xD6\x80\x27\xE6\x81\x89\xE8\x87\x8A\xEA\x80\x8D\xEF\x8C\x10\xC4\x85\x14\xC6\x84\x21\xF3\x82\x8A\x09\x1B\x8D\x01\x1D\x8D\xDB\x1F\x8D\x04\x18\x8F\xED\x8E\x10\xFB\x8C\x8F\x37\x11\x8F\x71\x2C\x8A\x06\x9A\x8D\xF5\x8B\x8B\xF7\x83\x59\xD1\x84\x88\x3A\x10\x91\xE7\x83\x89\xE9\x87\x89\x08\x92\x8C\x0A\x99\x8F\xFF\x0E\x90\xD8\x1A\x91\xF4\x8C\x91\xF6\x8E\x91\x16\x92\x92\x0B\x9C\x90\x0E\x14\x92\xA2\x16\x92\x00\x96\x10\x02\x90\x00\x04\x99\x1D\x06\x9B\x8E", "\x0A\x17\x91\xB1\x8A\x13\x2D\x9E\x92\x0C\x10\x93\xB1\x1C\x8E\x33\x98\x15\x13\x9D\x8C\x15\x95\x94\x9B\x82\x92\x44\x97\x8B\x01\x97\x94\xDE\x89\x94\x4E\x96\x10\x3C\x95\x8C\x3E\x92\x92\x42\x93\x1B\x4D\x9B\x8A\xB8\x88\x92\x14\x9A\x92\x4A\x91\x10\x55\x90\x94\x21\x99\x90\xF0\x87\x8C\x3B\x9B\x91\xA5\x8D\x91\xA9\x8F\x91\xD2\x8E\x8E\x66\x91\x94\x68\x98\x30\x6A\x9B\x8C\x6C\x9D\x8B\x6E\x98\x91\x9E\x8C\x2B\x12\x9E\x95\x48\x90\x96\x53\x93\x10\x63\x94\x96\xFA\x88\x95\x73\x95\x15\x75\x9C\x8D\x77\x9F\x8C\x2B\x91\x97\xFF\x0F\x93\x40\x99\x95\xAF\x1C\x8A\x0E\x9D\x97\x6B\x99\x92\x6D\x9D\x98\x20\x9D\x10\x90\x9E\x92\x92\x90\x1D\xAC\x84\x8C\x96\x96\x97\x98\x98\x97\x9A\x9F\x96\xE5\x8A\x10\xA2\x9D\x95\x97\x9F\x95\x99\x91\x96\xAD\x8E\x98\x9D\x9C\x90\x9F\x95\x1D\xA1\x99\x98\x03\x9B\x98\xE0\x89\x97\x3D\x93\x8D\x8E\x95\x9B\xDC\x17\x9B\x27\x9D\x9A\x7F\x9F\x9A\x81\x9B\x94\xB2\x96\x98\xFE\x80\x16\xA3\x9A\x98\xA5\x9C\x98\xB0\x93\x98\x84\x9C\x8A\xD4\x9C\x9A\xA4\x9E\x9A\xA6\x91\x9D\x2C\x9A\x9C\x3A\x25\x9D\xC3\x97\x9D\xC5\x99\x9D\xC7\x92\x96\xDB", "\x9F\x9B\x87\x93\x9E\xE2\x86\x9D\xCE\x98\x9D\xD0\x98\x9E\xD2\x94\x96\xB3\x9C\x8F\xC0\x99\x8D\x0A\x1F\x15\xDF\x9B\x9E\xE1\x9D\x9E\x5C\x99\x10\xEF\x90\x94\xAC\x86\x9F\xB0\x95\x93\x37\x95\x14\x39\x9C\x9B\x56\x9E\x9B\x9B\x92\x97\xCB\x99\x10\x00\xA8\x9E\x02\xAA\x9B\x07\x97\x9A\x7A\x90\x97\x09\xA3\x92\xE7\x92\x10\x0D\xAB\x9F\x34\x90\x95\x05\x92\x95\x1A\xA2\x98\xE5\x95\xA1\xF3\x98\x9B\xE9\x9F\x94\x7E\x91\x95\x80\x9F\xA1\xC8\x95\xA1\xCD\x9F\x8B\xEA\x99\x9B\xCF\x9B\x9B\x12\xAD\x9B\x14\xA8\x9A\x67\x9B\xA0\x1B\xA7\x9F\x30\xAC\x9E\x32\xAA\x9D\xC9\x96\x9E\x38\xA6\x94\x3A\xA6\x93\x10\xAA\x93\xFC\x91\xA2\x36\xAA\xA0\x3A\x20\x1C\x0E\x95\x93\xC0\x16\x90\x4D\x1A\x10\x11\x9C\x2B\xFD\x9E\x92\x4E\xA0\xA1\x51\xA9\x10\x53\xA4\x97\x47\xAF\xA3\x22\xA1\x23\x57\xA1\xA3\x59\xAA\xA5\x60\x1E\x90\x55\xAC\x90\xF1\x9D\x8F\x3A\x21\xA6\x3C\xA3\xA6\x06\x1B\xA5\x88\x9D\xA5\x15\xA9\xA6\x3A\x13\xA2\x6E\xA9\x1D\x6C\xA4\x1C\xC4\x85\x93\x0C\x00\xA1\x11\x07\xA7\xB1\x95\xA1\x7C\xAE\xA7\x80\xA7\xA6\xFC\x84\xA7\x0D\x90\xA6\x0A\x1D\xA7\x62\xAF\xA7\x77\xA6", "\xA8\x45\x18\xA8\xD5\x8A\xA8\x09\x1C\xA8\x6D\xAE\xA8\x6E\xA0\xA9\x57\x90\xA4\x6B\xAC\x39\x06\x94\x8C\x35\x1A\xA9\x37\x15\x93\xAC\x84\xA0\xAA\x95\xA8\x48\xA3\xA1\x2F\x94\xA9\xB0\x96\xAA\x52\x18\xAA\x5E\xA9\xA4\x16\xA4\x21\xA4\xA0\xA1\xA0\xA9\x96\xB1\xAA\xAA\x37\xAB\xA4\xE0\x14\x8C\x92\xA9\x2E\xBF\xA9\x2F\xC1\xA0\x30\xC3\xAE\x32\xC5\xA2\x22\xC7\xA1\x23\xC9\xA4\x21\xCB\xAA\x23\xCD\xA8\x26\xCF\xAD\x26\x35\x96\x8B\x28\xA6\x10\xC9\x17\xA7\x06\x96\xA9\x03\x14\x8C\xA2\xA3\x13\xD3\xA0\xA1\xD7\xAE\xA6\xD9\xA7\xAA\x72\xA2\xAB\xC5\xA6\xA7\x39\xA6\x10\xD4\xAD\xA1\x09\x11\xAE\x63\xA3\xAE\xAF\xA5\xAE\xBA\xA5\x98\x9C\xA8\x26\xDF\xA2\xA6\xEE\xA9\xA5\xF0\xA6\x87\xB8\xA3\xA7\xDC\x98\x26\x4C\xA0\xA8\x45\x1F\x8F\xC4\x14\xB0\xBD\x1D\xA2\x00\x05\x1F\x62\xAE\x21\x8F\xA2\x92\x35\x9A\xB0\x6D\xAC\xB0\x99\xA9\xAA\x34\xAB\xAA\xB4\xAA\x10\x10\xB9\x9F\x01\x12\xB1\x63\xAD\xAD\x65\x9F\xA5\x17\xB9\x10\x19\xB5\xAD\x03\x1C\xB1\x59\xAE\xB1\x9C\x9F\xAF\x6D\x20\x1C\xC2\x95\xA1\x22\x2C\xB2\x02\xBA\x13\x50\xAD\xAB\x31\xB7\x13\x06\x95\x93\xF1\x97\xB3", "\x60\x16\x90\x0E\x96\xA6\x22\x90\x1C\x79\xAD\x1B\x0E\x91\xAD\x70\x25\x93\x06\x9E\xAA\xEA\xA0\xAB\x2E\xB0\x1E\x2D\xB2\xAB\x2F\xBC\xB4\xE4\xAB\xB4\x14\x20\xB4\x51\xBE\xB4\x31\x24\xB5\x26\xA9\xAE\x1A\xB0\x00\x19\xAE\xA2\x64\xA2\xAF\x01\x1E\xB3\x8E\x90\x1C\xBE\xAF\xB3\xAC\xA3\x10\x14\x00\xA1\x62\x2D\xB0\x63\xB0\xB5\xF1\xA2\xB5\xBC\xA3\x18\x4D\xB3\xAF\x2E\x38\xB5\xFC\xAD\xB6\x53\xB0\x1E\x35\x95\x93\x26\xBC\xAE\x06\x1D\xB5\x25\xAF\xA6\x0A\x10\x11\x5C\xA4\x95\x66\xB3\x18\x65\xB8\xB7\x71\xB2\x1C\x73\xB5\xB1\xC2\xA7\xB8\xCE\xA0\xB9\xD0\xA2\xB9\x6D\x24\xB4\x71\x26\xB9\xD8\x18\xB9\xA2\x1A\xB9\xB1\x1C\xB9\xB3\x1E\xB9\xAF\x15\x93\x98\xAB\xB5\x42\x23\x59\x06\x98\x01\x54\xA4\xB9\xDB\x11\xB4\xDB\x19\xB8\x70\xB3\xB9\x8A\xB0\xB0\xE0\x13\xB4\xAA\xB1\x27\x01\xB9\xB5\x03\x11\x13\x62\xA0\xB8\x35\x16\x90\x15\x05\xB5\x2B\xA6\xB5\x72\xB0\xBC\x8E\xB4\xAC\xB5\xB5\x92\x60\x14\x8C\x06\x90\x24\x6F\xB0\xA2\xB9\xA5\xBC\x2E\x36\xB0\x01\x1A\xBC\x0A\x1C\xBC\x77\xB6\xB8\xCF\xB7\xA0\x2C\x30\xBA\xD0\x1C\xBD\xD5\x1E\xBD\xDC\x10\xBE\x35\x12\xBE\xC4", "\xBA\xBD\xC0\xA7\xBC\x9B\xB8\xBE\x9D\xBA\xBE\x9F\xBC\xBE\xAF\x14\xBE\xB8\xB6\x1C\x10\xA7\x1F\xCD\xB1\xBC\x74\xB7\xBB\x6E\xA3\xB0\xE5\xB4\x98\xC6\xB1\xBB\x95\xBE\xBE\xDD\xB0\xC0\xDF\xB2\xC0\xE1\xB4\xC0\xE3\xB6\xC0\xFB\xBC\xBF\xC8\xA8\xC0\xF5\xB0\xBD\x0B\xCE\xBF\x45\xBA\x10\xF9\xAE\xB7\xB9\xB5\xBE\x28\xB5\x27\x0E\x90\xB3\x0D\xC6\xBE\xF9\x2A\xC1\xD7\xB2\xBC\x91\xB0\xC1\xB6\xB6\xAB\x0C\xC9\xBF\x32\xB5\xB3\x33\x1A\xB3\x09\x1A\x16\xBB\xBB\xB3\x1C\xA0\x00\x0E\x96\x90\x23\xB1\x10\x35\x97\xC1\xA5\x2E\xBA\x20\xC0\xBB\xAF\xBF\xBF\x22\xC9\xB9\x25\xCB\xAD\x3F\xC2\x10\xF0\xBF\xC1\xF7\xBA\xAC\x41\xC3\xBD\x47\xC0\x00\x43\xC0\xC4\x3D\xC2\x1A\x35\xC0\xA1\xC7\x1B\xC1\x36\xC8\xBF\x63\xAA\xBF\x1B\xCC\xBF\x75\xBE\xB6\x44\xCE\xC0\x57\xBA\xB7\x28\xCE\x10\x7B\xB5\x9F\x10\xA0\xB8\x32\x93\x10\x2C\xC1\xA7\xD8\xBB\xC3\xAD\xB9\xC0\x84\x9F\xC0\x6A\xC7\xB9\x49\xCB\xC4\x42\xC1\xC7\x49\xC6\xC3\x76\xC2\x92\x77\xC9\xBD\x58\xCE\xC6\x39\xCC\xC3\x6F\xCE\xC3\x4D\xCB\xBE\x81\xCD\xBE\x83\xCF\xBE\x74\xC5\xC8\x01\xC8\xC8\x03\xCA\xC8\x05\xCC\xC8\x07\xCE", "\xC8\x6C\xC4\x96\x7C\xC5\xC4\x14\x26\x90\x33\xB0\xB6\x1C\xC4\xAF\x7F\xC9\xBE\x90\xC7\xC5\x0A\xC6\xC4\x9D\xCB\xC5\x99\xC6\xAC\x87\xCB\xC9\xB1\x15\x93\xF4\xBD\xA6\x69\xB8\xAD\x0A\x1B\xCA\x3E\xAE\xAF\xA1\xCC\xC4\xA6\xC4\xC8\xB3\xC6\xC8\xB1\xC3\xC7\xB7\xC8\xC4\xB9\xCA\xC4\x49\xC8\xCA\x10\xAE\xCA\xEF\xAD\xCA\x06\xA8\xC5\x72\xCA\xCB\xB5\xC9\xC8\xC7\xCB\xC8\xC9\xCD\xC8\xCB\xCF\xC8\xCD\xC1\xC9\x40\x92\x22\xC0\x94\x8C\xC0\x9D\xB3\xB3\xBD\x3F\xBB\xA3\x10\xD5\xC8\xCD\x4A\xAA\xCD\x34\xB5\xB8\x7A\xAC\xCD\x8F\x92\xCE\xD4\xC7\xCD\xE0\xCD\x1B\x35\x90\x9C\xE9\xCF\xCD\x68\xC4\x1C\xB4\xBA\xC7\xFC\xB5\xAC\xF2\xC4\xB1\xA3\xC7\xAE\x31\x28\xAE\xB2\xC2\xAB\xF8\xC2\x10\xC0\x94\x99\x5A\xC3\x10\x96\x60\xA8\x02\xD3\xD0\x04\xD5\xD0\x81\xB9\xCF\xFC\xCF\xA2\x00\x06\xC9\x52\xAD\xD0\x5F\xB2\xB8\x0F\xD3\x10\x0C\xD1\xD1\x18\xAD\xAF\x8F\x89\x16\x0A\x11\xC5\x06\x1A\xD1\x03\x1C\xD1\xF2\xB9\x10\x1E\xD1\x10\x21\xD0\x00\x23\xD5\xD2\x19\xD2\xC1\x28\xDD\xAE\x29\xD6\xAD\x2B\xD3\x10\x13\xC0\x00\x2F\xD1\xD3\x8B\xAF\xC2\x33\xC0\x00\xA9\xC3\x10\x37\xD2\x10", "\x39\xD1\x10\x3B\xD6\xD3\x0A\x1D\xD3\x40\xDF\xD3\x42\xD9\x10\xBA\xB6\x10\xA3\xBA\x9F\x1B\xBA\x10\x7D\xB0\x00\xC0\xC2\x10\xBF\xB9\x10\xD6\xB3\x10\x47\xD1\x10\x51\xD8\xD4\x00\x05\xD5\x49\xD0\xD5\x4A\xD5\xBD\xC2\xCA\xD5\x09\x1F\xD4\x06\x15\xBA\x06\x18\xBA\x09\x13\xD5\x00\x04\xD6\xC6\x92\x10\x68\xD5\xB2\x0A\x1B\xD6\x02\x1B\xD4\x6E\xD1\x10\x4D\xD1\x10\x71\xD0\x00\x60\xD3\x10\x84\xB6\x10\x6B\xB6\x10\x58\xD0\x00\x66\xDB\xD7\x3F\x2E\xA1\x01\x10\xD8\x02\x1D\xD7\x4B\xD4\xD8\x54\xDB\xD5\x09\x18\xD8\x57\xDD\xD5\x7A\xDC\xD5\x5F\xDA\x10\x8C\xD2\xD6\x03\x14\x26\x5E\xD6\xD4\x0A\x16\xD9\x7C\xD2\xD8\x00\x0A\xD9\x81\xDD\x21\x99\xD0\xD9\x06\x1B\xD4\x9E\xD5\xD8\x8E\xD5\xD9\xA2\xD3\x10\x77\xD2\x10\xA5\xD1\x10\x94\xD2\x10\x1C\x09\xDA\x02\x16\xD6\xB1\xD7\xD9\xE2\x90\xDB\xB2\xD9\xD5\x06\x15\xDB\x9B\xD0\xDA\x09\x1C\xDB\x9F\xD6\x10\x73\xD0\x00\xC0\xD6\xDA\x91\xDF\xDB\x0A\x1F\xDA\x51\xAD\x01\x80\xA3\xDC\xD8\x15\x13\x95\x00\x8B\xFE\xC9\x10\x29\x0D\xC5\x09\x16\x09\xD2\xDC\x2B\xD5\xD9\xB7\x09\x17\x09\xD9\xD4\xD1\x01\x11\x34\xDC\xD6\x10\x98", "\x0F\xDD\x10\xD6\x10\xE2\xDB\xB8\x03\x19\x09\xE6\xD3\xA6\x3C\x06\xDD\x06\x1A\x09\xED\xD6\xBF\x01\x1D\x38\xE3\xD3\x10\x9B\x03\xDF\xE4\x99\x10\xF6\xDA\xDE\x02\x1C\x09\xFA\xD0\x00\xEB\xA0\x00\x98\x34\x21\xFB\xC0\x8A\x0A\x13\x3A\x06\xE0\xDF\x03\x13\x3E\xF7\xD2\x10\x9D\x01\xE0\x35\x18\x40\x0F\xE1\x10\x9E\x01\xE0\x23\xDC\x45\x15\xE0\x00\x9F\x01\xE0\x2F\xD4\x47\x1B\xE0\x0A\x1E\xEA\x10\x20\xEE\xDF\x01\x11\x0A\x12\xEA\x10\xE8\x4B\xE1\xA2\x01\xE0\x37\x9D\x51\x1B\xE3\x0A\x01\xE5\x93\x6D\x5B\xE0\x09\x14\x0A\x01\xE0\xB8\x81\x56\xE3\x06\x15\x0A\x01\xE7\xC6\x03\x1C\x57\x3C\xE3\x10\xA6\x01\xE0\xDA\xA2\x10\x7A\x53\xE4\x02\x17\x0A\x01\xE5\xD3\x6F\x5A\xE4\xDC\x61\xE0\x3D\xDA\x5B\x50\xE0\x00\xA9\x01\xE0\xC4\x82\x5B\x1B\xEA\x0A\xB0\x84\x8C\x53\xE7\xCF\xA0\xC6\x10\x5A\xE6\xE2\x00\x0C\x0A\x01\xE5\xD4\x03\x10\x5C\x1B\xED\x0A\x5D\xEA\x10\x68\xE2\x10\xC2\x5B\xE1\xAF\x07\xE6\x0A\x11\xE7\x64\xE0\x0B\x01\xEB\x0F\x80\xA7\xE0\x23\xCE\xC9\xB1\x15\x13\x03\xE5\x88\xB8\xC4\xE6\x86\xA2\x22\x38\xBC\xE0\x15\xD7\x32\x80\xB1\x9F\x02\xD3\xD2\x03\x33", "\xE0\x8C\xE0\xA8\x35\x93\x30\x23\xD1\xE9\x77\xA0\xE4\xDA\x37\xE4\xC6\xC2\xBB\xE0\xDE\x44\x35\xD6\xE9\x6E\xA0\xEA\x68\x2F\xE6\x9B\xEB\xB2\x6D\xD0\x3C\xE1\x82\xEA\x83\xE8\x9E\x03\x33\xDC\x93\xEC\xC9\x06\x1B\xDA\x14\x45\xD7\x80\xB0\xC8\xBD\xD6\x36\x83\x2C\xA0\x61\xE3\x10\xCA\xDE\x44\x24\x02\xC6\x55\xE5\xAA\xBE\x23\x2D\xF1\xB0\x27\x0E\x92\xEB\x4E\x4B\x2F\xBA\xE5\xE5\x7D\xD3\x30\xE9\xD3\x10\xB5\xE2\x1A\x0E\x9D\xEB\x03\x3B\x35\xCB\xED\xA9\x93\x53\x30\x8B\x35\xEC\x71\x25\x93\xC8\xE3\x30\x93\x3F\xB7\x67\xB6\xDC\x66\x30\x12\xD7\xE6\xAF\xC9\xD0\x3C\xF9\x32\xEE\x95\xC0\x57\x35\x4A\xB5\x6D\x2E\xBB\xC0\x3A\xE1\xEC\xEA\x23\xCB\xB0\x3C\xBC\x47\xEE\xF1\xE9\xEE\x27\x3E\x4F\xFA\xE0\x27\x64\xC0\x3C\x61\x5C\xED\xD8\x10\xB8\xDF\xEE\x2B\x42\xE5\xEF\x68\x20\xB8\xCD\xEE\x2B\xBC\x5A\xF0\x6D\x20\xB8\xD4\xEE\x2B\xC8\x5F\xEF\x71\x25\x95\xC2\xE1\x2E\xF6\x54\xF0\xA2\x15\x95\x07\xF1\x2E\x17\x66\xF1\xD8\x15\x95\x0D\xF1\x2E\x53\x62\xF2\x1D\xFC\xEF\x66\x33\x68\x28\xF1\x1B\x03\xE9\xF1\x2C\x3F\x68\x1C\xFE\xF2\x0A\x1F\xF1\x2C\x3F\x6A\x2D\xF3\x1B", "\x03\xE5\xF2\x2C\x3E\x6C\x39\xFF\x1A\x03\xE3\xF1\xE1\x2D\x6D\x3F\xF0\x1D\x98\xEE\xB5\x66\x36\x71\x33\xF3\x1B\x47\xF6\xD7\xC0\x3F\x72\x45\xF5\x1D\x4D\xFC\xF3\xE9\x2C\x75\x51\xFC\x1D\x4D\xF2\xF4\x2C\x38\x76\x57\xF5\x13\x23\xD0\xF3\xE9\x2D\x79\x4B\xFF\x1A\x23\xD6\xF3\xE9\x23\x7B\x5D\xF7\xD2\xB6\xDA\x3D\xCC\x79\xF6\x20\xDA\xF2\xBA\x3B\x7F\x6E\xFC\xD2\x27\xA4\x41\x0E\x89\xED\xA2\x1A\xE9\x07\xDA\x3D\x12\x83\xF6\xD0\x1A\xF7\x66\xF9\x2F\x23\x83\xF7\x03\x1A\xF7\x54\xF9\x2F\x38\x84\xF8\x02\x1A\xF7\x5A\xF9\x2E\x4E\x8A\xF8\x3B\xA5\xF8\xC0\x3A\x85\x78\xF1\x1B\x35\xDF\xD2\x03\x3E\x85\x95\xF3\x1B\x3D\xD0\xF6\xF9\x21\x86\xE7\xC0\x27\x3D\xD1\xF8\x00\x37\x86\x9D\xE8\x1D\x3D\xD7\xF8\x00\x3A\xE7\xA7\xF2\x1A\x3D\xDD\xF8\x1D\xCF\x89\x47\xB2\x1A\xA4\xEB\xF7\x14\x45\x00\x9F\x8C\xE7\xB5\xF4\xFA\x2E\x38\x00\xB2\xF1\x23\xB5\xFA\xFA\x2E\x3D\x00\xBF\xF4\x21\xB5\xF0\xFB\x00\x32\x01\xC5\xFA\x23\x66\xD5\xFB\x03\x37\x01\x9F\x8E\xF9\xD5\x11\x8E\x7C\xE8\x1D\x18\x0F\x89\xB7\xA3\x59\xE1\x81\xE8\xBE\x2A\x01\xD8\xFC\x9C\x9C\xD5\xE8\x31\x2C\x01\xDF", "\xFB\xC1\xAC\x81\x8E\xD1\xE1\x2E\x1E\x05\xFE\xED\xCA\xA2\x3D\xAD\xD1\xC0\x30\x02\xEC\xF2\xA4\xB0\x91\x8E\xAF\xE1\x2E\x22\x03\xFF\x5B\x10\x16\xE1\x8D\xF4\x03\x34\x02\xFA\x7E\x2B\x3C\x7E\x87\x66\x36\x26\x01\x00\x81\x54\xE8\x49\xD5\x40\x1E\x14\x07\x00\xAF\x78\x67\x75\x6B\x03\x1A\x05\x07\x81\xA6\x7C\x8A\x4B\x6A\xF4\x6E\x19\x2C\x07\x13\x77\x7F\xD9\x0B\xD4\x3C\x7E\x88\x10\x01\x9F\x41\xFD\x5C\x81\xDC\x6E\x44\x36\x01\x08\x91\x11\x4B\x68\xF9\x6E\x18\x1E\x07\x02\x94\x13\x70\x6B\x6A\x03\x1A\x08\x11\x7F\x18\x18\xEC\x3D\x6B\xC0\x03\x02\x33\x84\x42\x3D\x6A\xB3\x60\xEE\x39\x82\x8E\x1D\x75\xE1\x43\x60\x05\x02\x1F\x88\x26\x75\x6B\x05\x82\x11\x46\x01\xF7\x71\x11\xBA\x6E\x01\xB1\x11\x12\x0B\x7E\x45\x84\x04\x83\x18\x27\x00\x05\xED\x11\x5D\x6A\x81\x22\x13\x0A\x15\x82\x38\x15\xD7\x35\x6B\xC0\x18\x02\x44\x85\x4D\x39\x6A\xD4\x67\x32\x59\x03\x01\x98\x0E\xAD\x6C\xB8\x40\x1F\x2D\x01\x06\xF0\x11\x71\x61\x08\xB9\x76\x6C\x1C\x03\x36\x81\x27\x6F\x80\x00\x00\x01\xC0\x1D\x0B\x34\x82\xEC\x0C\xDC\x09\x09\x1C\x9A\x1D\x5E\x03\x0F\xA2\x0D\x3F\x82", "\x10\x0C\x6F\xC0\x1F\x02\x1A\x81\x46\x05\x15\x84\x0D\x07\xE6\x1B\x18\x02\x84\xB1\x08\x0F\x89\x09\x45\x86\x36\x64\x00\x24\x93\x0D\x12\x0E\x20\x3F\x75\x93\x15\x06\x67\x82\x68\x00\x15\x09\x0E\x53\x27\x19\x33\x0A\x04\x94\x13\x26\x86\x08\xA0\x86\x6C\x2A\x03\x4B\x8F\x1A\x14\x09\x42\x1B\x15\x27\x1B\x0D\x1E\x85\xD8\x00\x0B\x86\x09\xB5\x07\x19\x6D\x04\x15\x90\x0E\x14\x0A\x10\x27\x86\xEE\x0E\x03\x07\x87\xEB\x4A\x08\x5E\x89\x10\x44\x76\xD9\x10\x03\xBA\x85\x3A\x1B\x6E\x4D\x80\x3C\x71\x03\x01\x8F\x69\xAC\x43\x19\x83\x08\x63\x8A\x3B\x73\x01\x32\x9C\x0E\xD4\x82\x20\x39\x15\x93\x14\x07\x09\x84\x85\x17\x85\x06\x0C\x18\xA6\x1A\x3C\x07\x0D\xB5\x0A\x45\x09\x08\x05\x1F\x64\x39\x03\x59\x83\x1B\x4A\x76\x41\x0D\x01\xC0\x1B\x0F\x25\x84\x1D\x19\x0E\x86\x0A\x3B\x9A\x1D\x7E\x05\x1C\x97\x08\x85\x02\x03\x40\x1F\x1F\x0C\x87\xAF\x0D\x1F\x89\x08\xA3\x17\x32\x01\x06\x3E\x89\x08\x2A\x18\x1D\x80\x1E\x41\x07\x00\xFA\x78\x2B\x49\x88\x06\x0C\x68\x27\x18\x42\x07\x10\xE8\x6E\x42\x15\x87\xBA\x1D\x10\x07\x81\x9B\x4C\x8A\x4F\x76\x40\x12\x88\x66\x1F\x10", "\x15\x89\x81\x00\x12\x83\x09\x0C\x00\x1E\x88\x06\x1B\xBA\x10\x82\x86\x10\x10\x8A\xEE\x0C\x04\x23\x8A\x20\x1A\x09\x84\x09\x35\x27\x19\x23\x00\x88\xD0\x0D\x26\x86\x08\xBD\x17\x32\x0F\x05\x4C\x81\x08\xD6\x75\xFD\x54\x20\x48\x07\x00\xB5\x68\x2B\x41\x8A\x17\x6F\x64\x12\x05\x03\x8D\xF9\x0A\x08\x52\x94\x6F\x4E\x24\x12\x07\x81\xDA\x77\x14\xC0\x76\xD9\x16\x04\x07\x86\xAC\x55\x8B\xB7\x77\x32\x18\x07\x01\x86\x52\x06\x0F\x29\xB4\x60\xE0\x1A\x09\x07\x82\x05\x8E\x8A\x18\x6F\x64\x1C\x05\x03\x83\xDC\x5B\x8B\x79\x7A\x1D\x9E\x07\x00\x88\x76\xB7\x88\xD0\x14\x20\x28\x07\x80\x7D\x6C\x2E\xAA\x6A\xE0\x12\x0A\x07\x81\xAF\x6C\x45\x3B\x02\x21\x38\x00\xE0\x14\x0A\x2A\x88\x9A\x0F\x6F\x09\x09\x30\xA7\x18\x54\x0F\x13\x80\x00\x4F\x81\x8B\xC0\x19\x15\x0D\x8D\xC2\x16\x10\x11\x1F\xC9\x0A\x05\x38\x8D\x3A\x1B\x76\x83\x0A\x13\xBA\x1C\x2B\x07\x80\x46\x82\x21\x1B\x8D\x81\x0F\x38\x27\x1A\x2B\x0D\x8C\xFD\x6B\x20\x1D\x8C\xED\x1F\x0A\x07\x83\x18\x8E\x7F\x00\x01\x35\x82\x09\xD2\x86\x36\x31\x05\x63\x94\x8D\x03\x09\x71\x27\x18\x59\x06\x18\xED\x12\x65\x86", "\x08\xA3\x8A\x7B\x36\x05\xC6\x81\xEE\x03\x09\xE9\x07\x19\xB7\x01\x33\x9C\x0F\xE2\x82\x10\x1B\x1F\xC9\x19\x05\xCA\x8D\x26\x05\x70\x83\x06\x39\x27\x1B\x2E\x13\x87\x68\x16\x39\x95\x8C\xE0\x1E\x0B\x07\x80\x63\x6C\x45\x0A\x74\x3A\x80\x1E\x60\x08\x1D\xED\x13\x71\x9B\x8E\x27\x1B\x18\x07\x81\x34\x8C\x8A\x66\x76\x41\x13\x1F\x27\x1D\x18\x11\x8E\x85\x02\x3C\x21\x7E\x13\x27\x06\x07\x86\x0E\xAC\x45\xFA\x89\xB4\x27\x19\x32\x07\x80\x8D\x80\x3D\x7C\x8E\xE7\x56\x36\x4B\x07\x01\x84\x84\x48\x7B\x20\x03\x91\x44\x76\x36\x4D\x07\x01\x94\x84\x02\x92\xED\x66\x1B\x67\x07\x00\x92\x84\x6C\x4B\x90\x63\x8F\x64\x11\x07\x03\x89\x09\x91\x93\x0A\x60\x1E\xD3\x07\x00\xA2\x85\x0B\x94\x00\xBA\x1D\x35\x07\x80\xA9\x86\x43\xA2\x65\x81\x17\x0D\x07\x82\x2F\x90\x8D\x18\x97\xAC\x40\x1F\x6C\x07\x00\xAE\x84\x6C\x56\x1E\x09\x0B\x09\x00\x1F\x6D\x05\x1E\xF0\x12\x83\x66\x08\x38\x96\x6C\x1E\x07\xC6\x80\x1F\x86\x09\x8C\x83\x18\xDF\x05\x31\xAB\x77\x81\x09\x41\x27\x18\x38\x13\x8F\x09\x0A\x0A\x22\x66\x11\x12\x0E\x07\x83\x36\x90\x4D\x52\x91\x21\x1C\x7F\x70\x14\x0E", "\x07\x81\x2D\x88\x4F\x59\x91\x8D\x7A\x1C\x73\x07\x00\xE2\x84\x98\x96\x8A\xBA\x18\x1D\x07\x80\x69\x80\x1B\xE1\x90\xFC\x67\x19\xEA\x07\x00\x99\x87\x04\x92\x10\x6E\x92\x40\x1B\x80\xE9\x14\x1D\x07\x80\x70\x87\x26\x9F\x93\xC9\x0E\x07\x07\x87\x1C\x98\x93\x12\x9A\x3D\x70\x07\x01\x90\x87\x93\x2E\x4E\xA5\x74\x0A\x22\x0F\x07\x83\x3D\x8D\x93\xA7\x77\x64\x34\x07\x03\x88\x11\xB0\x8F\x14\x0A\x08\xFC\x1F\x64\x36\x07\x1E\x91\x27\x14\x72\x41\x17\x94\x27\x19\x1F\x0D\x8D\x26\x96\x10\x0A\x96\x13\x3A\x07\x8D\x8F\xDD\x43\x08\x24\x27\x32\x7B\x04\x94\x86\x08\xAC\x96\x20\x0E\x25\x93\x1D\x0F\x0D\x8F\x15\x29\x08\x45\x92\x77\x3E\x07\x03\x87\x30\x30\x4F\xAD\x86\x08\xA4\x92\x77\x3C\x64\x51\x67\x12\x93\x2F\xAF\x83\x08\x7F\x27\x64\x02\x01\x00\x78\x1D\x74\x74\x93\x80\x1E\x03\x05\xCD\x49\x08\x81\x80\x9B\x4E\x96\x40\x09\x96\x66\x1D\x00\x0C\x96\xD1\x05\xE2\x48\x94\xF0\x06\x00\xDB\x91\x36\x18\x97\x81\x06\x44\x27\x1B\x01\x10\x45\xB3\x79\x36\x33\x94\x83\x07\x2C\x99\x75\xB8\x93\x0D\xA0\x26\x20\x2A\x27\x93\x1D\x00\x52\x96\x8E\x19\x77\x42\x8E\x89\x0F", "\x00\x7B\x93\x10\x2E\x88\x6C\x98\x97\x49\x8E\x6C\x11\x00\x7E\x92\x10\x1E\x88\x9D\x81\x08\x00\x98\x2A\x83\x19\x09\x04\x30\x81\x09\x49\x9F\x97\x68\x92\x7B\x15\x01\x86\x90\x00\x2C\x88\x7A\x49\x98\x22\x68\x78\x17\x00\x8A\x93\x13\xB0\x4C\xC6\x80\x00\x78\x91\x5F\x19\x00\x8A\x93\x18\x93\x2F\xC7\x9E\x7F\xBE\x13\x03\x14\x99\xD5\x87\x30\x80\x03\xC7\x89\x97\x2C\x1D\x03\x14\x98\xB1\x86\xFB\x2E\x98\x34\x79\x17\x1F\x04\x62\x8A\x8C\x8F\x91\x29\xE6\x19\x08\x14\x98\x88\x88\x36\x5B\x27\x84\x08\x4B\x27\x1B\x08\x10\x45\x7C\x73\xC5\x46\x09\xA1\x95\x00\xEF\x97\x6B\x13\x97\x06\x0F\x63\x83\x19\x13\x0E\x34\xD0\x0E\x3D\x26\x08\xFE\x76\x6C\x28\x00\x8A\x98\x1D\x59\x98\x50\x20\x1E\x2A\x05\x6A\x95\x0F\x88\x29\x10\x50\x9A\xEE\x0B\x01\x14\x9F\x31\xA8\x4E\xB2\x96\x10\x2C\x2B\xC9\x0D\x01\x62\x9C\x3B\x30\x71\xB6\x90\x3C\x2E\x01\xDC\x95\x09\x6E\x9E\x20\x39\x27\x93\x1F\x02\x30\x45\xC8\x95\x0E\x41\x29\x21\x2C\x9A\xDD\x13\x03\x77\x99\x4A\x0A\x08\x5F\x92\x7B\x34\x00\x8A\x94\x19\xE8\x4D\x51\x26\x08\xD4\x92\x77\x36\x00\x8A\x9A\x1B\xB0\x4F\xE3\x86\x8E", "\xC0\x18\x07\x14\x99\xE0\x8D\x32\x97\x9D\x73\x80\x1E\x3A\x04\x62\xB2\x8D\xCE\x9A\x10\x31\x96\xEE\x1C\x01\x14\x98\x37\xB0\x8C\xCF\x91\x10\x5E\x9A\xF6\x1E\x01\x14\x9F\x37\xA8\x4F\x1A\x76\x10\x03\x7A\xD9\x00\x02\x86\x99\x21\x0F\x73\xDA\x90\x3C\x41\x01\xEE\x86\x08\x49\x74\x77\xA7\x18\x21\x0F\x3B\xC1\x72\x42\x16\x9D\xBA\x1B\x08\x05\x9E\x81\x0B\xE3\x42\x9E\xD9\x04\x02\xCB\x99\x20\x12\x2C\x83\x09\x38\x94\x21\x11\x14\x98\xCC\x8B\x51\x80\x01\xE9\x93\x10\x11\x9E\xF6\x07\x02\x14\x9B\x3A\xB5\x8B\xED\x9A\x10\x67\x8E\xEE\x09\x02\x14\x99\x3C\xA3\x9E\xEE\x9F\x39\xA7\x1B\x12\x14\x98\xEE\x8B\x7D\xA5\x9C\xE0\x1D\x04\x14\x99\x8C\x84\x46\xEC\x9D\x75\x80\x1F\x27\x04\x31\xBF\x92\xFC\x89\x08\x69\x83\x60\x11\x02\x8A\x9B\x24\xB0\x8F\x98\x63\x08\xD5\x9E\x89\x13\x02\x8A\x99\x29\xA2\x67\x01\xA2\x08\xDE\x9C\x82\x15\x02\x8A\x90\x2A\x8E\xA1\xF9\x80\x1E\x57\x04\x62\x81\x97\x55\x72\x10\x0F\xA1\x40\x1A\x8E\xBA\x19\x0B\x14\x99\x72\x96\x41\x89\x0A\xE9\x9A\x1E\x5B\x04\x62\xAD\x96\xED\x9E\x41\x80\x02\xEB\x94\x20\x5D\x04\x62\x9D\x96\x0E\xA1\x10\x2D", "\xA1\x00\xB7\x25\x14\x9B\x5D\xA8\x4E\x2A\x76\x10\x18\x2F\xC9\x01\x03\x5C\x9A\x34\x0F\x78\x04\xA0\x3C\x63\x00\xC5\x91\x97\xDE\x61\x21\x03\xA2\x08\xA0\x3C\x65\x00\xC5\x8C\x9A\x49\xA6\x20\x0B\xA3\x80\x06\x3E\xDA\x1F\x19\x14\x98\x57\x99\x8A\x83\x09\x29\xA0\x00\x20\xA2\xF6\x09\x03\x14\x9B\x70\x89\x68\x25\xA3\x3F\xB1\x84\xC5\x81\x9C\xF9\x94\x8B\xAF\xA0\x27\x2D\x06\x14\x98\xED\x9A\xA2\x02\x0C\x8B\xB7\xA1\x70\x1F\x06\x14\x99\xC2\x63\x9F\x6A\x76\x20\x3E\x2D\x93\x11\x07\x7E\x99\x8C\x19\xA3\x44\xA7\x64\x35\x02\x8A\x99\x3F\xB0\x62\x42\x00\xA4\x4C\xA7\x64\x37\x02\x8A\x9C\x43\xF0\xA1\x40\x08\xA4\x54\xA0\x78\x39\x02\x8A\x90\x49\x86\xA5\x42\x15\xA4\x5E\xA4\x82\x3B\x02\x8A\x96\x5C\x76\x8D\x25\xA7\xA1\x14\x25\x0F\x14\x98\xE6\x2E\x49\x8A\x0B\x1A\xA3\x18\x7F\x04\x62\xAD\x2F\x52\xA0\x40\xC0\x1D\x20\x14\x98\x0B\x33\x83\x76\x73\x81\x0B\x47\xE6\x1B\x20\x1E\xA3\x14\x13\x96\x82\x09\x04\xA3\x30\x07\x04\xC5\x81\x79\xF9\x92\x97\x81\x09\x08\xAE\x44\x09\x04\xC5\x91\x31\xF6\x8A\x98\x80\x01\x2A\xA4\x41\x0B\x04\xC5\x87\x79\xC1\xA2\x21\x19\xA4", "\x27\x2D\x08\x14\x99\x9B\x29\xA6\x65\xA6\x6C\x0F\x04\x8A\x9C\xF2\x51\xA5\x42\x07\xA5\xBE\x11\x12\x14\x99\x44\x38\x4D\xAD\xA7\xC9\x13\x04\x14\x9A\xE6\x62\x64\xE2\x26\xD0\x0B\x09\x3B\xAF\xA7\xF0\xA1\x9E\xB2\xA7\x79\xA4\x4F\xF5\xA5\x96\x40\x55\xFB\x40\x9F\x8E\x66\x51\x63\x2C\x9B\x62\x25\xB6\x8F\xB3\x56\x3E\xA0\x99\x9A\x03\xE9\x4E\x52\x41\xA4\xA8\x08\xAC\x50\xBB\x7E\x99\x00\xA5\x50\x50\xEF\x55\x75\x0F\xAD\x26\x11\xA9\x88\x90\x15\x88\x83\x42\x15\x4A\x16\xAD\xA2\x98\xA8\x8C\xA3\xE0\x02\x70\x51\x1D\xA8\x20\xA8\xD0\x75\x09\xA6\x70\x00\x7E\x7C\x49\xA7\xA9\x23\xAE\xEB\x6A\xA8\x99\x03\xD2\x24\x6B\x4A\xBC\x8A\x2A\x6D\xA5\x4B\x09\x97\x60\xD3\x35\x08\x4D\xB4\xA9\x7A\x78\x00\x3A\x7B\x7F\x09\x53\xBD\xA9\x4D\x1E\xA9\x33\x6F\x85\x44\x52\x99\x07\x93\x43\xA9\xDD\x71\x7C\x03\x0D\xA6\x49\x58\xA2\x0A\x54\xCD\xA9\x4D\x0E\xAA\x43\x69\x21\x36\x81\x9E\x6E\xD3\x51\xAA\x41\x14\xAA\x54\xAD\xF6\x40\x00\xE7\x7A\x55\xDA\xAA\x59\x7E\x6B\x44\x0F\xAB\x9F\xAB\x9A\x00", }; vl::glr::DecompressSerializedData(compressed, true, dataSolidRows, dataRows, dataBlock, dataRemain, outputStream); } const wchar_t* ParserRuleName(vl::vint index) { static const wchar_t* results[] = { L"RType", L"RAttributeParameter", L"RAttribute", L"REnumMember", L"REnum", L"RUnionMember", L"RUnion", L"RStructMember", L"RStructBody", L"RStruct", L"RMessageRequest", L"RMessageResponse", L"RMessage", L"REventRequest", L"REvent", L"RDeclDetail", L"RDecl", L"Schema", }; return results[index]; } const wchar_t* ParserStateLabel(vl::vint index) { static const wchar_t* results[] = { L"[0][RType] BEGIN ", L"[1][RType] END [ENDING]", L"[2][RType]< \"binary\" @ >", L"[3][RType]< \"bool\" @ >", L"[4][RType]< \"char\" @ >", L"[5][RType]< \"color\" @ >", L"[6][RType]< \"double\" @ >", L"[7][RType]< \"float\" @ >", L"[8][RType]< \"int\" @ >", L"[9][RType]< \"key\" @ >", L"[10][RType]< \"string\" @ >", L"[11][RType]< NAME \"[\" \".\" @ NAME \"]\" >", L"[12][RType]< NAME \"[\" \".\" NAME \"]\" @ >", L"[13][RType]< NAME \"[\" \".\" NAME @ \"]\" >", L"[14][RType]< NAME \"[\" @ \".\" NAME \"]\" >", L"[15][RType]< RType \"?\" @ >", L"[16][RType]< RType \"[\" \"]\" @ >", L"[17][RType]< RType \"[\" @ \"]\" >", L"[18][RType]< RType \"[\" @ RType \"]\" >", L"[19][RType]< RType \"[\" RType \"]\" @ >", L"[20][RType]< RType \"[\" RType @ \"]\" >", L"[21][RType]< RType @ \"?\" >", L"[22][RType]< RType @ \"[\" \"]\" >", L"[23][RType]< RType @ \"[\" RType \"]\" >", L"[24][RType]{{< NAME @ \"[\" \".\" NAME \"]\" > ; < NAME @ >}}", L"[25][RAttribute] BEGIN ", L"[26][RAttribute] END [ENDING]", L"[27][RAttribute]< \"[\" @ ATT_NAME [ \"(\" ( CPP_NAME ) \")\" ] \"]\" >", L"[28][RAttribute]< \"[\" ATT_NAME @ [ \"(\" ( CPP_NAME ) \")\" ] \"]\" >", L"[29][RAttribute]< \"[\" ATT_NAME [ \"(\" ( CPP_NAME ) \")\" @ ] \"]\" >", L"[30][RAttribute]< \"[\" ATT_NAME [ \"(\" ( CPP_NAME ) \")\" ] \"]\" @ >", L"[31][RAttribute]< \"[\" ATT_NAME [ \"(\" ( CPP_NAME @ ) \")\" ] \"]\" >", L"[32][RAttribute]< \"[\" ATT_NAME [ \"(\" @ ( CPP_NAME ) \")\" ] \"]\" >", L"[33][REnumMember] BEGIN ", L"[34][REnumMember] END [ENDING]", L"[35][REnumMember]< NAME \",\" @ >", L"[36][REnumMember]< NAME @ \",\" >", L"[37][REnum] BEGIN ", L"[38][REnum] END [ENDING]", L"[39][REnum]< \"enum\" @ NAME \"{\" { REnumMember } \"}\" >", L"[40][REnum]< \"enum\" NAME \"{\" @ { REnumMember } \"}\" >", L"[41][REnum]< \"enum\" NAME \"{\" { REnumMember @ } \"}\" >", L"[42][REnum]< \"enum\" NAME \"{\" { REnumMember } \"}\" @ >", L"[43][REnum]< \"enum\" NAME @ \"{\" { REnumMember } \"}\" >", L"[44][RUnionMember] BEGIN ", L"[45][RUnionMember] END [ENDING]", L"[46][RUnionMember]< NAME \",\" @ >", L"[47][RUnionMember]< NAME @ \",\" >", L"[48][RUnion] BEGIN ", L"[49][RUnion] END [ENDING]", L"[50][RUnion]< \"union\" @ NAME \"{\" { RUnionMember } \"}\" >", L"[51][RUnion]< \"union\" NAME \"{\" @ { RUnionMember } \"}\" >", L"[52][RUnion]< \"union\" NAME \"{\" { RUnionMember @ } \"}\" >", L"[53][RUnion]< \"union\" NAME \"{\" { RUnionMember } \"}\" @ >", L"[54][RUnion]< \"union\" NAME @ \"{\" { RUnionMember } \"}\" >", L"[55][RStructMember] BEGIN ", L"[56][RStructMember] END [ENDING]", L"[57][RStructMember]< \"var\" @ NAME \":\" RType \";\" >", L"[58][RStructMember]< \"var\" NAME \":\" @ RType \";\" >", L"[59][RStructMember]< \"var\" NAME \":\" RType \";\" @ >", L"[60][RStructMember]< \"var\" NAME \":\" RType @ \";\" >", L"[61][RStructMember]< \"var\" NAME @ \":\" RType \";\" >", L"[62][RStructBody] BEGIN ", L"[63][RStructBody] END [ENDING]", L"[64][RStructBody]< NAME \"{\" @ { RStructMember } \"}\" >", L"[65][RStructBody]< NAME \"{\" { RStructMember @ } \"}\" >", L"[66][RStructBody]< NAME \"{\" { RStructMember } \"}\" @ >", L"[67][RStructBody]< NAME @ \"{\" { RStructMember } \"}\" >", L"[68][RStruct] BEGIN ", L"[69][RStruct] END [ENDING]", L"[70][RStruct]<! \"class\" !RStructBody @ !>", L"[71][RStruct]<! \"class\" @ !RStructBody !>", L"[72][RStruct]<! \"struct\" !RStructBody @ !>", L"[73][RStruct]<! \"struct\" @ !RStructBody !>", L"[74][RMessageRequest] BEGIN ", L"[75][RMessageRequest] END [ENDING]", L"[76][RMessageRequest]< \"request\" \":\" @ RType \";\" >", L"[77][RMessageRequest]< \"request\" \":\" RType \";\" @ >", L"[78][RMessageRequest]< \"request\" \":\" RType @ \";\" >", L"[79][RMessageRequest]< \"request\" @ \":\" RType \";\" >", L"[80][RMessageResponse] BEGIN ", L"[81][RMessageResponse] END [ENDING]", L"[82][RMessageResponse]< \"response\" \":\" @ RType \";\" >", L"[83][RMessageResponse]< \"response\" \":\" RType \";\" @ >", L"[84][RMessageResponse]< \"response\" \":\" RType @ \";\" >", L"[85][RMessageResponse]< \"response\" @ \":\" RType \";\" >", L"[86][RMessage] BEGIN ", L"[87][RMessage] END [ENDING]", L"[88][RMessage]< \"message\" @ NAME \"{\" [ RMessageRequest ] [ RMessageResponse ] \"}\" >", L"[89][RMessage]< \"message\" NAME \"{\" @ [ RMessageRequest ] [ RMessageResponse ] \"}\" >", L"[90][RMessage]< \"message\" NAME \"{\" [ RMessageRequest @ ] [ RMessageResponse ] \"}\" >", L"[91][RMessage]< \"message\" NAME \"{\" [ RMessageRequest ] [ RMessageResponse @ ] \"}\" >", L"[92][RMessage]< \"message\" NAME \"{\" [ RMessageRequest ] [ RMessageResponse ] \"}\" @ >", L"[93][RMessage]< \"message\" NAME @ \"{\" [ RMessageRequest ] [ RMessageResponse ] \"}\" >", L"[94][REventRequest] BEGIN ", L"[95][REventRequest] END [ENDING]", L"[96][REventRequest]< \"request\" \":\" @ RType \";\" >", L"[97][REventRequest]< \"request\" \":\" RType \";\" @ >", L"[98][REventRequest]< \"request\" \":\" RType @ \";\" >", L"[99][REventRequest]< \"request\" @ \":\" RType \";\" >", L"[100][REvent] BEGIN ", L"[101][REvent] END [ENDING]", L"[102][REvent]< \"event\" @ NAME \"{\" [ REventRequest ] \"}\" >", L"[103][REvent]< \"event\" NAME \"{\" @ [ REventRequest ] \"}\" >", L"[104][REvent]< \"event\" NAME \"{\" [ REventRequest @ ] \"}\" >", L"[105][REvent]< \"event\" NAME \"{\" [ REventRequest ] \"}\" @ >", L"[106][REvent]< \"event\" NAME @ \"{\" [ REventRequest ] \"}\" >", L"[107][RDeclDetail] BEGIN ", L"[108][RDeclDetail] END [ENDING]", L"[109][RDeclDetail]<! !REnum @ !>", L"[110][RDeclDetail]<! !REvent @ !>", L"[111][RDeclDetail]<! !RMessage @ !>", L"[112][RDeclDetail]<! !RStruct @ !>", L"[113][RDeclDetail]<! !RUnion @ !>", L"[114][RDecl] BEGIN ", L"[115][RDecl] END [ENDING]", L"[116][RDecl]<! { RAttribute @ } !RDeclDetail !>", L"[117][RDecl]<! { RAttribute } !RDeclDetail @ !>", L"[118][Schema] BEGIN ", L"[119][Schema] END [ENDING]", L"[120][Schema]< RDecl @ { RDecl } >", L"[121][Schema]< RDecl { RDecl @ } >", }; return results[index]; } Parser::Parser() : vl::glr::ParserBase<GuiRemoteProtocolTokens, ParserStates, GuiRemoteProtocolAstInsReceiver>(&GuiRemoteProtocolTokenDeleter, &GuiRemoteProtocolLexerData, &GuiRemoteProtocolParserData) { } vl::WString Parser::GetClassName(vl::vint32_t classIndex) const { return vl::WString::Unmanaged(GuiRemoteProtocolTypeName((GuiRemoteProtocolClasses)classIndex)); } vl::vint32_t Parser::FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const { return -1; } vl::Ptr<vl::presentation::remoteprotocol::GuiRpSchema> Parser::ParseSchema(const vl::WString& input, vl::vint codeIndex) const { return ParseWithString<vl::presentation::remoteprotocol::GuiRpSchema, ParserStates::Schema>(input, this, codeIndex); } vl::Ptr<vl::presentation::remoteprotocol::GuiRpSchema> Parser::ParseSchema(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex) const { return ParseWithTokens<vl::presentation::remoteprotocol::GuiRpSchema, ParserStates::Schema>(tokens, this, codeIndex); } } /*********************************************************************** .\REMOTEPROTOCOL\GENERATED\GUIREMOTEPROTOCOL_ASSEMBLER.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:GuiRemoteProtocol Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::remoteprotocol { /*********************************************************************** GuiRemoteProtocolAstInsReceiver : public vl::glr::AstInsReceiverBase ***********************************************************************/ vl::Ptr<vl::glr::ParsingAstBase> GuiRemoteProtocolAstInsReceiver::CreateAstNode(vl::vint32_t type) { auto cppTypeName = GuiRemoteProtocolCppTypeName((GuiRemoteProtocolClasses)type); switch((GuiRemoteProtocolClasses)type) { case GuiRemoteProtocolClasses::ArrayMapType: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpArrayMapType); case GuiRemoteProtocolClasses::ArrayType: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpArrayType); case GuiRemoteProtocolClasses::Attribute: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpAttribute); case GuiRemoteProtocolClasses::EnumDecl: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpEnumDecl); case GuiRemoteProtocolClasses::EnumMember: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpEnumMember); case GuiRemoteProtocolClasses::EventDecl: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpEventDecl); case GuiRemoteProtocolClasses::EventRequest: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpEventRequest); case GuiRemoteProtocolClasses::MapType: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpMapType); case GuiRemoteProtocolClasses::MessageDecl: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpMessageDecl); case GuiRemoteProtocolClasses::MessageRequest: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpMessageRequest); case GuiRemoteProtocolClasses::MessageResponse: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpMessageResponse); case GuiRemoteProtocolClasses::OptionalType: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpOptionalType); case GuiRemoteProtocolClasses::PrimitiveType: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpPrimitiveType); case GuiRemoteProtocolClasses::ReferenceType: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpReferenceType); case GuiRemoteProtocolClasses::Schema: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpSchema); case GuiRemoteProtocolClasses::StructDecl: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpStructDecl); case GuiRemoteProtocolClasses::StructMember: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpStructMember); case GuiRemoteProtocolClasses::UnionDecl: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpUnionDecl); case GuiRemoteProtocolClasses::UnionMember: return vl::Ptr(new vl::presentation::remoteprotocol::GuiRpUnionMember); default: return vl::glr::AssemblyThrowCannotCreateAbstractType(type, cppTypeName); } } void GuiRemoteProtocolAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::Ptr<vl::glr::ParsingAstBase> value) { auto cppFieldName = GuiRemoteProtocolCppFieldName((GuiRemoteProtocolFields)field); switch((GuiRemoteProtocolFields)field) { case GuiRemoteProtocolFields::ArrayType_element: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpArrayType::element, object, field, value, cppFieldName); case GuiRemoteProtocolFields::Declaration_attributes: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpDeclaration::attributes, object, field, value, cppFieldName); case GuiRemoteProtocolFields::EnumDecl_members: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpEnumDecl::members, object, field, value, cppFieldName); case GuiRemoteProtocolFields::EventDecl_request: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpEventDecl::request, object, field, value, cppFieldName); case GuiRemoteProtocolFields::EventRequest_type: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpEventRequest::type, object, field, value, cppFieldName); case GuiRemoteProtocolFields::MapType_element: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpMapType::element, object, field, value, cppFieldName); case GuiRemoteProtocolFields::MapType_keyType: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpMapType::keyType, object, field, value, cppFieldName); case GuiRemoteProtocolFields::MessageDecl_request: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpMessageDecl::request, object, field, value, cppFieldName); case GuiRemoteProtocolFields::MessageDecl_response: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpMessageDecl::response, object, field, value, cppFieldName); case GuiRemoteProtocolFields::MessageRequest_type: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpMessageRequest::type, object, field, value, cppFieldName); case GuiRemoteProtocolFields::MessageResponse_type: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpMessageResponse::type, object, field, value, cppFieldName); case GuiRemoteProtocolFields::OptionalType_element: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpOptionalType::element, object, field, value, cppFieldName); case GuiRemoteProtocolFields::Schema_declarations: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpSchema::declarations, object, field, value, cppFieldName); case GuiRemoteProtocolFields::StructDecl_members: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpStructDecl::members, object, field, value, cppFieldName); case GuiRemoteProtocolFields::StructMember_type: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpStructMember::type, object, field, value, cppFieldName); case GuiRemoteProtocolFields::UnionDecl_members: return vl::glr::AssemblerSetObjectField(&vl::presentation::remoteprotocol::GuiRpUnionDecl::members, object, field, value, cppFieldName); default: return vl::glr::AssemblyThrowFieldNotObject(field, cppFieldName); } } void GuiRemoteProtocolAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, const vl::regex::RegexToken& token, vl::vint32_t tokenIndex) { auto cppFieldName = GuiRemoteProtocolCppFieldName((GuiRemoteProtocolFields)field); switch((GuiRemoteProtocolFields)field) { case GuiRemoteProtocolFields::ArrayMapType_element: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpArrayMapType::element, object, field, token, tokenIndex, cppFieldName); case GuiRemoteProtocolFields::ArrayMapType_keyField: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpArrayMapType::keyField, object, field, token, tokenIndex, cppFieldName); case GuiRemoteProtocolFields::Attribute_cppType: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpAttribute::cppType, object, field, token, tokenIndex, cppFieldName); case GuiRemoteProtocolFields::Attribute_name: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpAttribute::name, object, field, token, tokenIndex, cppFieldName); case GuiRemoteProtocolFields::Declaration_name: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpDeclaration::name, object, field, token, tokenIndex, cppFieldName); case GuiRemoteProtocolFields::EnumMember_name: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpEnumMember::name, object, field, token, tokenIndex, cppFieldName); case GuiRemoteProtocolFields::ReferenceType_name: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpReferenceType::name, object, field, token, tokenIndex, cppFieldName); case GuiRemoteProtocolFields::StructMember_name: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpStructMember::name, object, field, token, tokenIndex, cppFieldName); case GuiRemoteProtocolFields::UnionMember_name: return vl::glr::AssemblerSetTokenField(&vl::presentation::remoteprotocol::GuiRpUnionMember::name, object, field, token, tokenIndex, cppFieldName); default: return vl::glr::AssemblyThrowFieldNotToken(field, cppFieldName); } } void GuiRemoteProtocolAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::vint32_t enumItem, bool weakAssignment) { auto cppFieldName = GuiRemoteProtocolCppFieldName((GuiRemoteProtocolFields)field); switch((GuiRemoteProtocolFields)field) { case GuiRemoteProtocolFields::PrimitiveType_type: return vl::glr::AssemblerSetEnumField(&vl::presentation::remoteprotocol::GuiRpPrimitiveType::type, object, field, enumItem, weakAssignment, cppFieldName); case GuiRemoteProtocolFields::StructDecl_type: return vl::glr::AssemblerSetEnumField(&vl::presentation::remoteprotocol::GuiRpStructDecl::type, object, field, enumItem, weakAssignment, cppFieldName); default: return vl::glr::AssemblyThrowFieldNotEnum(field, cppFieldName); } } const wchar_t* GuiRemoteProtocolTypeName(GuiRemoteProtocolClasses type) { const wchar_t* results[] = { L"ArrayMapType", L"ArrayType", L"Attribute", L"Declaration", L"EnumDecl", L"EnumMember", L"EventDecl", L"EventRequest", L"MapType", L"MessageDecl", L"MessageRequest", L"MessageResponse", L"OptionalType", L"PrimitiveType", L"ReferenceType", L"Schema", L"StructDecl", L"StructMember", L"Type", L"UnionDecl", L"UnionMember", }; vl::vint index = (vl::vint)type; return 0 <= index && index < 21 ? results[index] : nullptr; } const wchar_t* GuiRemoteProtocolCppTypeName(GuiRemoteProtocolClasses type) { const wchar_t* results[] = { L"vl::presentation::remoteprotocol::GuiRpArrayMapType", L"vl::presentation::remoteprotocol::GuiRpArrayType", L"vl::presentation::remoteprotocol::GuiRpAttribute", L"vl::presentation::remoteprotocol::GuiRpDeclaration", L"vl::presentation::remoteprotocol::GuiRpEnumDecl", L"vl::presentation::remoteprotocol::GuiRpEnumMember", L"vl::presentation::remoteprotocol::GuiRpEventDecl", L"vl::presentation::remoteprotocol::GuiRpEventRequest", L"vl::presentation::remoteprotocol::GuiRpMapType", L"vl::presentation::remoteprotocol::GuiRpMessageDecl", L"vl::presentation::remoteprotocol::GuiRpMessageRequest", L"vl::presentation::remoteprotocol::GuiRpMessageResponse", L"vl::presentation::remoteprotocol::GuiRpOptionalType", L"vl::presentation::remoteprotocol::GuiRpPrimitiveType", L"vl::presentation::remoteprotocol::GuiRpReferenceType", L"vl::presentation::remoteprotocol::GuiRpSchema", L"vl::presentation::remoteprotocol::GuiRpStructDecl", L"vl::presentation::remoteprotocol::GuiRpStructMember", L"vl::presentation::remoteprotocol::GuiRpType", L"vl::presentation::remoteprotocol::GuiRpUnionDecl", L"vl::presentation::remoteprotocol::GuiRpUnionMember", }; vl::vint index = (vl::vint)type; return 0 <= index && index < 21 ? results[index] : nullptr; } const wchar_t* GuiRemoteProtocolFieldName(GuiRemoteProtocolFields field) { const wchar_t* results[] = { L"ArrayMapType::element", L"ArrayMapType::keyField", L"ArrayType::element", L"Attribute::cppType", L"Attribute::name", L"Declaration::attributes", L"Declaration::name", L"EnumDecl::members", L"EnumMember::name", L"EventDecl::request", L"EventRequest::type", L"MapType::element", L"MapType::keyType", L"MessageDecl::request", L"MessageDecl::response", L"MessageRequest::type", L"MessageResponse::type", L"OptionalType::element", L"PrimitiveType::type", L"ReferenceType::name", L"Schema::declarations", L"StructDecl::members", L"StructDecl::type", L"StructMember::name", L"StructMember::type", L"UnionDecl::members", L"UnionMember::name", }; vl::vint index = (vl::vint)field; return 0 <= index && index < 27 ? results[index] : nullptr; } const wchar_t* GuiRemoteProtocolCppFieldName(GuiRemoteProtocolFields field) { const wchar_t* results[] = { L"vl::presentation::remoteprotocol::GuiRpArrayMapType::element", L"vl::presentation::remoteprotocol::GuiRpArrayMapType::keyField", L"vl::presentation::remoteprotocol::GuiRpArrayType::element", L"vl::presentation::remoteprotocol::GuiRpAttribute::cppType", L"vl::presentation::remoteprotocol::GuiRpAttribute::name", L"vl::presentation::remoteprotocol::GuiRpDeclaration::attributes", L"vl::presentation::remoteprotocol::GuiRpDeclaration::name", L"vl::presentation::remoteprotocol::GuiRpEnumDecl::members", L"vl::presentation::remoteprotocol::GuiRpEnumMember::name", L"vl::presentation::remoteprotocol::GuiRpEventDecl::request", L"vl::presentation::remoteprotocol::GuiRpEventRequest::type", L"vl::presentation::remoteprotocol::GuiRpMapType::element", L"vl::presentation::remoteprotocol::GuiRpMapType::keyType", L"vl::presentation::remoteprotocol::GuiRpMessageDecl::request", L"vl::presentation::remoteprotocol::GuiRpMessageDecl::response", L"vl::presentation::remoteprotocol::GuiRpMessageRequest::type", L"vl::presentation::remoteprotocol::GuiRpMessageResponse::type", L"vl::presentation::remoteprotocol::GuiRpOptionalType::element", L"vl::presentation::remoteprotocol::GuiRpPrimitiveType::type", L"vl::presentation::remoteprotocol::GuiRpReferenceType::name", L"vl::presentation::remoteprotocol::GuiRpSchema::declarations", L"vl::presentation::remoteprotocol::GuiRpStructDecl::members", L"vl::presentation::remoteprotocol::GuiRpStructDecl::type", L"vl::presentation::remoteprotocol::GuiRpStructMember::name", L"vl::presentation::remoteprotocol::GuiRpStructMember::type", L"vl::presentation::remoteprotocol::GuiRpUnionDecl::members", L"vl::presentation::remoteprotocol::GuiRpUnionMember::name", }; vl::vint index = (vl::vint)field; return 0 <= index && index < 27 ? results[index] : nullptr; } vl::Ptr<vl::glr::ParsingAstBase> GuiRemoteProtocolAstInsReceiver::ResolveAmbiguity(vl::vint32_t type, vl::collections::Array<vl::Ptr<vl::glr::ParsingAstBase>>& candidates) { auto cppTypeName = GuiRemoteProtocolCppTypeName((GuiRemoteProtocolClasses)type); return vl::glr::AssemblyThrowTypeNotAllowAmbiguity(type, cppTypeName); } } /*********************************************************************** .\REMOTEPROTOCOL\GENERATED\GUIREMOTEPROTOCOL_LEXER.CPP ***********************************************************************/ /*********************************************************************** This file is generated by: Vczh Parser Generator From parser definition:GuiRemoteProtocol Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ namespace vl::presentation::remoteprotocol { bool GuiRemoteProtocolTokenDeleter(vl::vint token) { switch((GuiRemoteProtocolTokens)token) { case GuiRemoteProtocolTokens::SPACE: return true; default: return false; } } const wchar_t* GuiRemoteProtocolTokenId(GuiRemoteProtocolTokens token) { static const wchar_t* results[] = { L"VAR", L"ENUM", L"UNION", L"STRUCT", L"CLASS", L"MESSAGE", L"REQUEST", L"RESPONSE", L"EVENT", L"BOOLEAN", L"INTEGER", L"FLOAT", L"DOUBLE", L"STRING", L"CHAR", L"KEY", L"COLOR", L"BINARY", L"CPP_NAME", L"ATT_NAME", L"NAME", L"OPEN_BRACE", L"CLOSE_BRACE", L"OPEN_ARRAY", L"CLOSE_ARRAY", L"OPEN", L"CLOSE", L"COLON", L"SEMICOLON", L"COMMA", L"DOT", L"QUESTION", L"SPACE", }; vl::vint index = (vl::vint)token; return 0 <= index && index < GuiRemoteProtocolTokenCount ? results[index] : nullptr; } const wchar_t* GuiRemoteProtocolTokenDisplayText(GuiRemoteProtocolTokens token) { static const wchar_t* results[] = { L"var", L"enum", L"union", L"struct", L"class", L"message", L"request", L"response", L"event", L"bool", L"int", L"float", L"double", L"string", L"char", L"key", L"color", L"binary", nullptr, nullptr, nullptr, L"{", L"}", L"[", L"]", L"(", L")", L":", L";", L",", L".", L"?", nullptr, }; vl::vint index = (vl::vint)token; return 0 <= index && index < GuiRemoteProtocolTokenCount ? results[index] : nullptr; } const wchar_t* GuiRemoteProtocolTokenRegex(GuiRemoteProtocolTokens token) { static const wchar_t* results[] = { L"var", L"enum", L"union", L"struct", L"class", L"message", L"request", L"response", L"event", L"bool", L"int", L"float", L"double", L"string", L"char", L"key", L"color", L"binary", L"(::[a-zA-Z_][a-zA-Z_0-9<>]*){1,}", L"@[a-zA-Z_][a-zA-Z_0-9]*", L"[a-zA-Z_][a-zA-Z_0-9]*", L"/{", L"/}", L"/[", L"/]", L"/(", L"/)", L":", L";", L",", L".", L"/?", L"/s+", }; vl::vint index = (vl::vint)token; return 0 <= index && index < GuiRemoteProtocolTokenCount ? results[index] : nullptr; } void GuiRemoteProtocolLexerData(vl::stream::IStream& outputStream) { static const vl::vint dataLength = 1775; // 21330 bytes before compressing static const vl::vint dataBlock = 256; static const vl::vint dataRemain = 239; static const vl::vint dataSolidRows = 6; static const vl::vint dataRows = 7; static const char* compressed[] = { "\x52\x53\x00\x00\xE7\x06\x00\x00\x6D\x00\x01\xAF\x01\x84\x81\x82\x16\x82\x09\x08\x84\x8A\x0B\x84\x81\x06\x87\x04\xA0\x11\x84\x88\x14\x88\x83\x14\x17\x84\xAC\x1A\x84\x87\x82\x82\x82\x30\x04\xB9\x04\x8A\x1C\x90\x83\x1D\x27\x84\xBC\x0A\x94\x86\x1D\x96\x82\x3F\x30\x84\x80\x23\x9C\x81\x20\x82\x5A\x04\x9B\x3A\x94\x85\x2D\x9E\x82\x5F\x40\x84\x81\x33\xA4\x82\x30\xA3\x04\xE3\x09\xA4\x84\x34\xA4\x83\x32\x4F\x84\xA6\x32\xA4\x87\x31\xAA\x82\x68\x58\x84\x89\x3B\xAC\x82\x34\xAF\x04\xEB\x21\xA4\x8C\x34\xB0\x82\x80\x01\xE8\x80\x0E\x34\x84\xB5\x81\x37\x04\xF0\x81\x90\x34\x84\xB9\x81\x38\x04\xF8\x81\x92\x34\x84\xBD\x81\x39\x04\x80\xC1\x94\x34\x84\xC1\x81\x3A\x04\x88\xC1\x96\x34\x84\xC5\x81\x3B\x04\xF8\x04\x99\x33\xCC\x82\x3C\xCB\x04\xFB\x19\xC4\x8D\x3C\xCC\x82\x0D\x9F\xA1\xC1\x80\xD1\x84\x08\x83\x0A\x04\x97\x04\x98\x04\x87\x7E\xD7\x7F\x0F\x81\x96\x0D\xDF\xD5\xD9\x0C\x82\x0E\x04\x8F\x04\x82\x0C\x83\x08\xDD\xC0\x81\x88\x04\x85\x04\x83\x04\x82\x02\x0D\x81\x9B\xDB\xE2\x85\xE7\x80\x0C\x41\xC0\x06\x02\xEC\xE4\x00\xEB\xD6\x87\x04\x84", "\x02\xEB\x00\x83\x00\xD5\xD2\xD0\x04\x81\x0C\xD9\xDB\xF3\xE8\xE9\xEA\xF5\xDC\x0E\xF3\xF5\xF7\xAE\xED\xC1\x8A\xF2\xF8\x03\x0C\x82\xF5\xF9\xF8\xFB\xF1\x82\xFD\xFE\xFE\x00\x3E\x71\x80\x80\x02\x85\x84\x83\x81\xFF\x49\x80\x00\x7C\x0C\x8D\x84\x7E\x7B\x0E\xA8\x75\x7F\x83\x0A\x86\x85\x84\x82\x03\x97\x8A\x84\x00\x1D\x18\x86\x85\x86\x20\x9E\x0E\x84\x84\x11\xA5\x84\x87\x82\x26\x92\x84\x89\x7C\x23\x9B\x8F\x87\x8B\x00\x9F\x0D\x88\x88\x30\xAE\x8B\x89\x8A\x38\x93\x88\x8C\x7B\x37\xB5\x84\x8F\x8C\x3E\x81\x98\x86\x44\x36\x9B\x8B\x8F\x91\xAF\x7A\x88\x92\x92\xE7\x42\x95\x90\x00\x22\x33\x81\x08\x86\x23\x00\x96\x96\x91\x48\x87\x9C\x93\x8E\x5B\x89\x97\x94\x00\x24\x1F\x9E\x93\x8F\x4F\xA3\x9D\x95\x96\x11\xA7\x96\x8A\x9A\x63\xA5\x02\x9B\x9B\x65\xB0\x90\x88\x9A\x5C\xB7\x85\x88\x9B\x72\x9F\x87\x0A\x9C\x26\x39\x9F\x94\x9D\x39\xB6\x99\x99\x8F\x7E\xB1\x9F\x91\x45\x86\xA4\x9A\xA3\x87\x80\xA9\x8A\x9B\x9D\x84\x89\xA6\x98\x80\x18\x52\xA5\xA2\xA2\x8D\xAB\x92\xA2\x83\x78\x96\xAE\xA7\xA2\x00\xAA\x07\xA6\x8F\x99\x90\xA3\x7D\x96\x9D\xA0\xAA\x83\x0A", "\xA3\xAD\xAF\xA7\xA3\xA5\xAF\x7B\x47\xA9\xB1\xB5\xA6\xAF\xAD\xB8\xB9\xA0\x7D\x0B\x37\xBC\xA1\x42\xAF\x00\x00\xB2\xB0\x41\xC3\xBF\xA4\xB3\xB1\xC6\x89\xB1\xB0\xB2\xCB\x8A\xB5\xB1\xB3\xD0\x8F\xB2\xB4\xB3\xBA\xA7\x88\x99\xAA\x93\xAF\xAE\xAA\xAA\xDC\x95\xBE\xB7\xB7\xE0\xA1\xB2\xBB\xB8\xE4\xA5\xB6\xBB\xB9\xE8\xA9\xBA\xBB\xBA\xEC\xAD\xBE\xBB\xBB\xF0\xB1\xB2\xBF\xBC\xF4\xB5\xB6\xBF\xBD\xF8\xB9\xBA\xBF\xBE\xFC\xBD\xBE\xBF\xBF\xAE\x5E\x40\x02\xC0\x04\xDB\xA0\xC3\xC1\xE8\xB0\xAC\xA5\xA4\xDC\x99\xBD\xC3\x97\x03\x5A\xBA\x80\xB9\x0A\xCD\x88\xB7\xB6\x0E\xD9\xCF\x9F\xB8\x15\xCC\x87\xC6\xC4\x0F\xE0\xCF\x85\x48\x89\x94\xC6\xC2\xC7\x0C\xFE\x81\x0C\xC6\x2C\xE5\xCC\xC7\xC9\xF0\x5F\xC1\xC8\xB7\x32\x2D\xC3\xCC\xA9\x2F\xF4\xAA\x95\xCA\x36\xDA\xCA\x83\x0C\xDB\xA6\xCA\xCD\x9D\x43\xDE\x91\x40\x0D\x3D\xC9\xD0\xCA\xD0\x28\x8B\x9C\xC1\x0D\x4A\xF7\xC1\xD5\xC7\xB5\x94\xDF\x7A\xCC\x3E\xDC\xB6\x0F\xD4\x33\x8C\xD7\xB4\xCF\x22\xDC\xD1\x43\x0D\x97\x9E\xD8\xA8\xD8\x52\xE1\xDF\x90\x0E\x00\xA3\x4B\xD1\xCE\x4D\xFB\xC5\xD0\x8B\x6A\xE9\xDA\xA1\x49\x75", "\xCC\xA0\xDF\xD7\x73\xFF\x39\xD5\xD6\x28\x79\xDD\xD7\xDE\x67\xFD\xDF\xDE\xD8\x8A\xAB\x4F\xA6\xD9\x4E\xC6\xE8\xE2\x8F\x3D\x08\xEC\xE2\xDC\x71\xFC\x82\xE3\xE5\x33\xEE\x4E\xCA\xB8\x56\xEB\x78\xD7\xE3\x88\xF1\x43\xC7\xBF\x34\x7D\xD5\xE8\x00\xA7\xE9\xE5\x4D\x40\xAA\xEC\xEB\xE8\xEA\xAF\xED\xE0\xEE\xEB\xB4\xF3\xE6\xEE\xEC\xB8\xF1\xEF\xE8\xB9\x37\x7D\xD5\x89\xEF\x95\xEF\x60\xF3\xF0\x36\x45\xF1\x40\xF1\xC7\xC6\xF0\x00\xF2\xCB\xCA\xFC\xF3\xF3\xCE\xD1\xF9\xF3\xF4\xCD\xD4\xFC\x81\xC1\x1F\x59\xF1\xF0\xC2\xDC\xE9\xBD\xE6\xB5\xE9\x47\xE8\xE6\xF8\x98\x84\xED\xE3\xF6\x7E\xE0\xEA\x82\x10\xEA\xF3\x96\xF8\xE5\x27\xA4\xF3\x9B\x10\xED\xD3\xE4\xD0\xFA\xF2\xD7\xA4\x12\xE4\xEF\xF7\xF1\xFF\xB6\x46\x0D\x7D\x11\x1B\x6C\x72\x98\x57\x68\x6D\xF9\x78\x73\x11\x65\x6D\x7F\x40\x4E\x73\x7C\x36\x68\x09\xD0\x0D\x8E\x50\x04\xAD\x7D\x3E\x49\x1C\x7D\x01\xBE\x73\x51\x07\xB6\x69\x81\x33\x6A\x08\x03\x9B\x88\x7C\x53\x78\x7F\x82\x36\x6B\x08\x01\xE1\x5F\x7B\xF0\x56\x80\x82\x89\x4C\x09\xD4\x76\x7E\x81\x13\xB0\x82\x51\x4D\x08\x87\xE8\x24\x8C\x6E\x1B\x80\x06", "\x09\x3A\x9F\x83\x08\xAC\x86\x80\xCF\x6F\x82\x88\x37\x84\x7C\x0D\x95\x8E\x83\x27\x01\x88\x84\x7A\x7C\x85\xE1\x3E\x85\x3E\x28\x0F\x8A\x83\x44\x9C\x83\xC2\x1E\x80\x8B\x2B\x98\x4A\x5C\x51\x04\x22\x14\x6E\x31\x8D\x80\x25\x88\x7D\x67\x8A\x3F\x19\xEB\x84\x20\x36\xA6\x8D\x8D\x70\x8F\x8E\x1C\x80\x0E\x8C\x3A\xB1\x8E\x8E\x73\x95\x8E\x1E\xF7\x8B\x8F\x39\xBC\x75\x88\xEA\x20\x79\x20\xD2\x75\x7B\x42\x90\x7C\x7A\x87\x86\x90\x21\x89\x9C\x91\x45\x80\x95\x51\x2D\x8A\x44\x17\xDE\x88\x88\xBB\x4B\x8A\x53\x93\x89\x8A\xCD\x53\x02\x4F\x4B\xA6\x87\x7F\x9A\x9B\x40\x15\x75\x74\x82\x4C\x94\x88\x40\x55\x14\x90\x08\x9E\x9D\x83\x53\xA1\x92\x51\x56\x04\x96\x14\xE7\x70\x95\x4A\x9D\x8A\x41\x57\x03\x88\xB8\x11\x9D\x49\x23\xB7\x96\x96\xBA\x9F\x58\x2F\x96\x7E\x94\x60\xB7\x80\x0B\x13\x93\x94\xFC\x2E\x81\x21\x2C\x2A\x90\x8B\xBB\x8F\x92\x24\xC5\x9F\x43\x9C\x2F\x97\x97\xAC\x9B\x88\x35\xC1\x8B\x27\x57\x99\x9E\x62\xBE\x8F\x98\xE6\x5F\x98\x65\x4C\x86\x9F\x9C\x02\x5C\x09\x32\xD9\x85\x85\x56\xB5\x97\x97\xE4\x7E\x27\xE2\x25\x9F\x92\x66\xA8\x9B\x46\x5E\x14", "\x90\xB9\x67\x83\x8C\x9D\x75\x8A\x8D\x37\x5D\x8C\x1E\x83\xA2\xA1\x82\xBC\x8F\xA0\x79\x88\xA0\x41\x8A\xAF\x9F\x73\x41\x2A\x8B\xDD\x71\xA1\x3D\xB4\x96\x9E\x78\xA2\x9D\x9D\xB8\x43\x9A\xD1\x5B\x97\x9B\x20\xA4\x99\x66\xE1\x9D\xA3\xA7\x60\x0D\x92\x7A\xAE\x9D\xA2\x72\x44\x2A\x48\xE7\x9F\xA3\x03\xA6\x9E\xA2\x2B\xA2\x41\x4B\xC6\x8F\xA5\x8B\xAB\x96\xA4\xDA\x8F\x9F\x97\x47\x21\xA7\x60\x9E\x5A\xA3\x74\x7C\xA3\x3D\x98\x7A\x29\xB7\x4A\x9E\x7F\x28\xBD\xA5\x40\x4D\x2B\xA5\x99\xA0\x7B\x9A\x30\xA3\xAB\xCC\x50\x2B\x86\x76\xBD\x82\xA7\x4A\xB2\xA9\x14\xD6\xA3\x8A\xAC\x8A\x53\x2A\x59\xAA\x8B\xBF\x56\x2D\x6E\xB2\x80\x06\xAC\x68\xB7\x29\x40\x69\xAB\xAC\xB5\xA7\xAE\xAD\x6C\xAF\xAD\x5B\xF3\xA2\xAF\xBA\xB1\xAF\xAE\x70\xAE\xAE\x53\xF6\x9E\xAB\xA8\xBE\xAA\x9A\x74\x40\xA9\xFA\x35\xA1\xAC\x68\x82\x98\xB0\xC4\x9D\xAC\x80\x59\x25\xB1\xBA\x7B\xAB\x9A\x8A\xAD\xB0\xB7\x5C\x23\x9F\xA3\xB5\x81\xB2\x5A\xB7\x53\x57\x46\xAC\xAA\x8A\x90\xAE\xA6\x33\x98\xA4\x38\x84\xB9\xB2\xC9\x82\xB3\x47\x62\x21\x21\x3F\xF1\x69\xB4\x00\x2D\xB2\x3D\xAF\xA9\x3D\x6B\xB3", "\xB3\x2D\x80\x34\xB6\xB6\xB5\xAE\xB5\x6E\xB7\xBA\xB6\xDC\xBE\xB5\xB7\xC0\xBC\xB6\x70\xBB\xB4\xB8\x88\xB6\x52\xB0\x9F\x66\xB5\x68\x96\xBC\x88\xA1\xBF\xAD\xA9\xA2\xA5\x9E\x73\x80\x45\x2C\xE5\x9C\xB0\x5C\xAD\xAB\xB5\x6D\x3C\xB0\xB7\x1B\x43\xBF\xB7\xDF\xA1\xB9\x71\xE2\xB0\xBD\xF1\xA1\xBF\xBC\xE3\xAF\xB1\x2F\xA4\xBF\xB9\xD2\xA5\x7F\x3D\xFE\x1F\x17\x6B\x6F\x15\x37\x7D\x3F\x0F\x1F\x1F\x0A\x2D\x41\x26\x35\x34\x82\x3C\xB8\x00\xFF\xA1\xC2\x7F\x83\xCD\xBF\x02\xC0\xC4\xC0\xF6\x24\x23\x94\x06\xC8\x34\xD9\x29\x33\x35\x04\x37\x37\x68\x00\x4D\x43\x80\x22\x41\x20\x32\x41\x20\x91\x07\xC6\xC0\x01\xDD\xC0\xC1\x1E\xDC\xC2\x88\xA1\xC4\xC4\x04\xCB\xC0\x00\xBF\x3A\xC1\x41\x20\xCC\xC5\x0F\xEE\xC3\xC4\x2D\xC0\x00\x43\x2F\xC6\x3B\xDE\x01\x21\xC5\x00\x00\x3F\x8B\xA5\xC1\x21\xDC\x3B\xC0\xC1\x09\x3F\xC5\x40\x36\xC0\x01\x13\xC3\x39\x20\xC9\x2F\xC4\x77\x01\x23\x3C\x21\xE2\xC7\x38\x06\xC7\xC6\x77\x01\x21\x36\x18\xC6\xC5\x3C\xD0\x3C\x34\x71\x04\x24\x3A\x03\xC4\xCA\x3B\x01\x20", }; vl::glr::DecompressSerializedData(compressed, true, dataSolidRows, dataRows, dataBlock, dataRemain, outputStream); } } /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWCODEGEN.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace workflow; using namespace workflow::analyzer; using namespace workflow::runtime; using namespace reflection::description; using namespace collections; using namespace controls; using namespace compositions; using namespace templates; /*********************************************************************** FindInstanceLoadingSource ***********************************************************************/ template<typename TCallback> auto FindByTag(Ptr<GuiInstanceContext> context, GlobalStringKey namespaceName, const WString& typeName, TCallback callback) -> std::remove_cvref_t<decltype(callback({}).Value())> { vint index = context->namespaces.Keys().IndexOf(namespaceName); if (index != -1) { Ptr<GuiInstanceContext::NamespaceInfo> namespaceInfo = context->namespaces.Values()[index]; for (auto ns : namespaceInfo->namespaces) { auto fullName = GlobalStringKey::Get(ns->prefix + typeName + ns->postfix); if (auto nullable = callback(fullName)) { return nullable.Value(); } } } return {}; } InstanceLoadingSource FindInstanceLoadingSource(Ptr<GuiInstanceContext> context, GlobalStringKey namespaceName, const WString& typeName) { return FindByTag(context, namespaceName, typeName, [](GlobalStringKey fullName)->Nullable<InstanceLoadingSource> { if (auto loader = GetInstanceLoaderManager()->GetLoader(fullName)) { return { { loader, fullName } }; } return {}; }); } Ptr<GuiResourceItem> FindInstanceResourceItem(Ptr<GuiInstanceContext> context, GuiConstructorRepr* ctor, Ptr<GuiResourceClassNameRecord> record) { return FindByTag(context, ctor->typeNamespace, ctor->typeName.ToString(), [=](GlobalStringKey fullName)->Nullable<Ptr<GuiResourceItem>> { vint index = record->classResources.Keys().IndexOf(fullName.ToString()); if (index != -1) { return record->classResources.Values()[index]; } return {}; }); } InstanceLoadingSource FindInstanceLoadingSource(Ptr<GuiInstanceContext> context, GuiConstructorRepr* ctor) { return FindInstanceLoadingSource(context, ctor->typeNamespace, ctor->typeName.ToString()); } /*********************************************************************** Workflow_PrecompileInstanceContext ***********************************************************************/ Ptr<workflow::WfModule> Workflow_PrecompileInstanceContext(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, types::ResolvingResult& resolvingResult, GuiResourceError::List& errors) { auto module = Workflow_CreateModuleWithUsings(resolvingResult.context, moduleName); { auto block = Workflow_InstallCtorClass(resolvingResult, module); Workflow_GenerateCreating(precompileContext, resolvingResult, block, errors); Workflow_GenerateBindings(precompileContext, resolvingResult, block, errors); } return module; } /*********************************************************************** WorkflowEventNamesVisitor ***********************************************************************/ class WorkflowEventNamesVisitor : public Object, public GuiValueRepr::IVisitor { public: GuiResourcePrecompileContext& precompileContext; types::ResolvingResult& resolvingResult; List<types::PropertyResolving>& candidatePropertyTypeInfos; Ptr<WfClassDeclaration> instanceClass; GuiResourceError::List& errors; IGuiInstanceLoader::TypeInfo resolvedTypeInfo; WorkflowEventNamesVisitor(GuiResourcePrecompileContext& _precompileContext, types::ResolvingResult& _resolvingResult, List<types::PropertyResolving>& _candidatePropertyTypeInfos, Ptr<WfClassDeclaration> _instanceClass, GuiResourceError::List& _errors) :precompileContext(_precompileContext) , resolvingResult(_resolvingResult) , candidatePropertyTypeInfos(_candidatePropertyTypeInfos) , instanceClass(_instanceClass) , errors(_errors) { } /////////////////////////////////////////////////////////////////////////////////// Ptr<WfDeclaration> ProcessEvent( Ptr<GuiAttSetterRepr::EventValue> handler, GlobalStringKey propertyName ) { if (auto eventInfo = resolvedTypeInfo.typeInfo->GetTypeDescriptor()->GetEventByName(propertyName.ToString(), true)) { auto decl = Workflow_GenerateEventHandler(precompileContext, eventInfo); decl->functionKind = WfFunctionKind::Normal; decl->anonymity = WfFunctionAnonymity::Named; decl->name.value = handler->value; { auto att = Ptr(new WfAttribute); att->category.value = L"cpp"; att->name.value = L"Protected"; decl->attributes.Add(att); } { auto att = Ptr(new WfAttribute); att->category.value = L"cpp"; att->name.value = L"UserImpl"; decl->attributes.Add(att); } { auto block = Ptr(new WfBlockStatement); decl->statement = block; auto stringExpr = Ptr(new WfStringExpression); stringExpr->value.value = L"Not Implemented: " + handler->value; auto raiseStat = Ptr(new WfRaiseExceptionStatement); raiseStat->expression = stringExpr; block->statements.Add(raiseStat); } return decl; } else { errors.Add(GuiResourceError({ resolvingResult.resource }, handler->attPosition, L"Precompile: Event \"" + propertyName.ToString() + L"\" cannot be found in type \"" + resolvedTypeInfo.typeName.ToString() + L"\".")); } return nullptr; } /////////////////////////////////////////////////////////////////////////////////// void Visit(GuiTextRepr* repr)override { } void Visit(GuiAttSetterRepr* repr)override { // TODO: (enumerable) foreach on dictionary for (auto [setter, index] : indexed(repr->setters.Values())) { auto loader = GetInstanceLoaderManager()->GetLoader(resolvedTypeInfo.typeName); List<types::PropertyResolving> possibleInfos; auto prop = repr->setters.Keys()[index]; WString errorPrefix; if (Workflow_GetPropertyTypes(precompileContext, errorPrefix, resolvingResult, loader, resolvedTypeInfo, prop, setter, possibleInfos, errors)) { if (setter->binding == GlobalStringKey::_Set) { if (possibleInfos[0].info->support == GuiInstancePropertyInfo::SupportSet) { auto setTarget = dynamic_cast<GuiAttSetterRepr*>(setter->values[0].Obj()); List<types::PropertyResolving> infos; WorkflowEventNamesVisitor visitor(precompileContext, resolvingResult, infos, instanceClass, errors); auto typeInfo = possibleInfos[0].info->acceptableTypes[0]; visitor.resolvedTypeInfo.typeName = GlobalStringKey::Get(typeInfo->GetTypeDescriptor()->GetTypeName()); visitor.resolvedTypeInfo.typeInfo = typeInfo; setTarget->Accept(&visitor); } else { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, errorPrefix + L" does not support the \"-set\" binding.")); } } else { for (auto value : setter->values) { WorkflowEventNamesVisitor visitor(precompileContext, resolvingResult, possibleInfos, instanceClass, errors); value->Accept(&visitor); } } } } // TODO: (enumerable) foreach on dictionary for (auto [handler, index] : indexed(repr->eventHandlers.Values())) { if (handler->binding == GlobalStringKey::Empty) { auto propertyName = repr->eventHandlers.Keys()[index]; if (auto decl = ProcessEvent(handler, propertyName)) { Workflow_RecordScriptPosition(precompileContext, handler->valuePosition, decl); instanceClass->declarations.Add(decl); } } } } void Visit(GuiConstructorRepr* repr)override { auto context = resolvingResult.context; bool inferType = repr->typeNamespace == GlobalStringKey::Empty&&repr->typeName == GlobalStringKey::_InferType; bool noContextToInfer = false; if (inferType) { if (candidatePropertyTypeInfos.Count() == 1) { auto info = candidatePropertyTypeInfos[0].info; if (info->acceptableTypes.Count() == 1) { auto typeInfo = info->acceptableTypes[0]; resolvedTypeInfo.typeName = GlobalStringKey::Get(typeInfo->GetTypeDescriptor()->GetTypeName()); resolvedTypeInfo.typeInfo = typeInfo; } else if (info->acceptableTypes.Count() == 0) { noContextToInfer = true; } } else if (candidatePropertyTypeInfos.Count() == 0) { noContextToInfer = true; } } else { if (repr == context->instance.Obj()) { auto fullName = GlobalStringKey::Get(context->className); if (auto reprType = GetInstanceLoaderManager()->GetTypeInfoForType(fullName)) { resolvedTypeInfo.typeName = fullName; resolvedTypeInfo.typeInfo = reprType; } } if (!resolvedTypeInfo.typeInfo) { auto source = FindInstanceLoadingSource(context, repr); resolvedTypeInfo.typeName = source.typeName; resolvedTypeInfo.typeInfo = GetInstanceLoaderManager()->GetTypeInfoForType(source.typeName); } } if (resolvedTypeInfo.typeInfo) { if (repr->setters.Count() == 1 && repr->setters.Keys()[0] == GlobalStringKey::Empty) { auto setter = repr->setters.Values()[0]; if (setter->values.Count() == 1) { if (auto text = setter->values[0].Cast<GuiTextRepr>()) { return; } } } Visit((GuiAttSetterRepr*)repr); } else if (inferType) { if (noContextToInfer) { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Unable to resolve type \"_\" without any context.")); } else { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Unable to resolve type \"_\" since the current property accepts multiple types.")); } } else { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Failed to find type \"" + (repr->typeNamespace == GlobalStringKey::Empty ? repr->typeName.ToString() : repr->typeNamespace.ToString() + L":" + repr->typeName.ToString() ) + L"\".")); } } }; /*********************************************************************** Workflow_GenerateInstanceClass ***********************************************************************/ class ReplaceDeclImplVisitor : public workflow::empty_visitor::DeclarationVisitor , public workflow::empty_visitor::VirtualCfeDeclarationVisitor , public workflow::empty_visitor::VirtualCseDeclarationVisitor { public: Func<Ptr<WfStatement>()> statCtor; List<Ptr<WfDeclaration>>& unprocessed; ReplaceDeclImplVisitor(Func<Ptr<WfStatement>()> _statCtor, List<Ptr<WfDeclaration>>& _unprocessed) :statCtor(_statCtor) , unprocessed(_unprocessed) { } void Dispatch(WfVirtualCfeDeclaration* node)override { node->Accept(static_cast<WfVirtualCfeDeclaration::IVisitor*>(this)); } void Dispatch(WfVirtualCseDeclaration* node)override { node->Accept(static_cast<WfVirtualCseDeclaration::IVisitor*>(this)); } void Visit(WfFunctionDeclaration* node)override { node->statement = statCtor(); } void Visit(WfConstructorDeclaration* node)override { node->statement = statCtor(); } void Visit(WfDestructorDeclaration* node)override { node->statement = statCtor(); } void Visit(WfClassDeclaration* node)override { CopyFrom(unprocessed, node->declarations, true); } }; Ptr<workflow::WfModule> Workflow_GenerateInstanceClass(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, types::ResolvingResult& resolvingResult, GuiResourceError::List& errors, vint passIndex) { bool needFunctionBody = false; bool needEventHandler = false; switch (passIndex) { case IGuiResourceTypeResolver_Precompile::Instance_CollectInstanceTypes: needFunctionBody = false; needEventHandler = false; break; case IGuiResourceTypeResolver_Precompile::Instance_CollectEventHandlers: needFunctionBody = false; needEventHandler = true; break; case IGuiResourceTypeResolver_Precompile::Instance_GenerateInstanceClass: needFunctionBody = true; needEventHandler = true; break; } auto classNameRecord = precompileContext.targetFolder->GetValueByPath(L"ClassNameRecord").Cast<GuiResourceClassNameRecord>(); Ptr<ITypeInfo> baseType; Ptr<GuiResourceItem> baseTypeResourceItem; Ptr<GuiInstanceContext> baseTypeContext; Ptr<WfType> baseWfType; auto context = resolvingResult.context; { auto source = FindInstanceLoadingSource(context, context->instance.Obj()); baseType = GetInstanceLoaderManager()->GetTypeInfoForType(source.typeName); if (!baseType) { baseTypeResourceItem = FindInstanceResourceItem(context, context->instance.Obj(), classNameRecord); } if (!baseType && !baseTypeResourceItem) { errors.Add(GuiResourceError({ resolvingResult.resource }, context->instance->tagPosition, L"Precompile: Failed to find type \"" + (context->instance->typeNamespace == GlobalStringKey::Empty ? context->instance->typeName.ToString() : context->instance->typeNamespace.ToString() + L":" + context->instance->typeName.ToString() ) + L"\".")); return nullptr; } if (baseTypeResourceItem && needEventHandler) { errors.Add(GuiResourceError({ resolvingResult.resource }, context->instance->tagPosition, L"[INTERNAL ERROR] Precompile: Failed to find compiled type in previous passes \"" + (context->instance->typeNamespace == GlobalStringKey::Empty ? context->instance->typeName.ToString() : context->instance->typeNamespace.ToString() + L":" + context->instance->typeName.ToString() ) + L"\".")); return nullptr; } } if (baseTypeResourceItem) { baseTypeContext = baseTypeResourceItem->GetContent().Cast<GuiInstanceContext>(); List<WString> fragments; SplitTypeName(baseTypeContext->className, fragments); for (auto fragment : fragments) { if (baseWfType) { auto type = Ptr(new WfChildType); type->parent = baseWfType; type->name.value = fragment; baseWfType = type; } else { auto type = Ptr(new WfTopQualifiedType); type->name.value = fragment; baseWfType = type; } } } /////////////////////////////////////////////////////////////// // Instance Class /////////////////////////////////////////////////////////////// auto module = Workflow_CreateModuleWithUsings(context, moduleName); auto instanceClass = Workflow_InstallClass(context->className, module); { if (baseWfType) { instanceClass->baseTypes.Add(baseWfType); } else { auto typeInfo = Ptr(new TypeDescriptorTypeInfo(baseType->GetTypeDescriptor(), TypeInfoHint::Normal)); auto baseType = GetTypeFromTypeInfo(typeInfo.Obj()); instanceClass->baseTypes.Add(baseType); } if (context->codeBehind) { auto value = Ptr(new WfStringExpression); value->value.value = instanceClass->name.value; auto att = Ptr(new WfAttribute); att->category.value = L"cpp"; att->name.value = L"File"; att->value = value; instanceClass->attributes.Add(att); } } /////////////////////////////////////////////////////////////// // Inherit from Constructor Class /////////////////////////////////////////////////////////////// if (needFunctionBody) { auto baseConstructorType = Ptr(new WfReferenceType); baseConstructorType->name.value = instanceClass->name.value + L"Constructor"; instanceClass->baseTypes.Add(baseConstructorType); { auto value = Ptr(new WfTypeOfTypeExpression); value->type = CopyType(baseConstructorType); auto att = Ptr(new WfAttribute); att->category.value = L"cpp"; att->name.value = L"Friend"; att->value = value; instanceClass->attributes.Add(att); } } /////////////////////////////////////////////////////////////// // Helpers /////////////////////////////////////////////////////////////// auto parseClassMembers = [&](const WString& code, const WString& name, List<Ptr<WfDeclaration>>& memberDecls, GuiResourceTextPos position) { WString wrappedCode = L"module parse_members; class Class {\r\n" + code + L"\r\n}"; if (auto module = Workflow_ParseModule(precompileContext, { resolvingResult.resource }, wrappedCode, position, errors, { 1,0 })) { CopyFrom(memberDecls, module->declarations[0].Cast<WfClassDeclaration>()->declarations); } }; auto notImplemented = []() { auto block = Ptr(new WfBlockStatement); auto stringExpr = Ptr(new WfStringExpression); stringExpr->value.value = L"Not Implemented"; auto raiseStat = Ptr(new WfRaiseExceptionStatement); raiseStat->expression = stringExpr; block->statements.Add(raiseStat); return block; }; auto getDefaultType = [&](const WString& className)->Tuple<Ptr<ITypeInfo>, WString> { auto paramTd = GetTypeDescriptor(className); if (!paramTd) { auto source = FindInstanceLoadingSource(resolvingResult.context, {}, className); if (auto typeInfo = GetInstanceLoaderManager()->GetTypeInfoForType(source.typeName)) { paramTd = typeInfo->GetTypeDescriptor(); } } if (paramTd) { auto typeInfo = Workflow_GetSuggestedParameterType(precompileContext, paramTd); switch (typeInfo->GetDecorator()) { case ITypeInfo::RawPtr: return { typeInfo,className + L"*" }; case ITypeInfo::SharedPtr: return { typeInfo,className + L"^" }; default: return { typeInfo,className }; } } return { nullptr,className }; }; /////////////////////////////////////////////////////////////// // ref.Members /////////////////////////////////////////////////////////////// if (context->memberScript != L"") { List<Ptr<WfDeclaration>> memberDecls; parseClassMembers(context->memberScript, L"members of instance \"" + context->className + L"\"", memberDecls, context->memberPosition); if (!needFunctionBody) { List<Ptr<WfDeclaration>> unprocessed; CopyFrom(unprocessed, memberDecls); ReplaceDeclImplVisitor visitor(notImplemented, unprocessed); // TODO: (enumerable) foreach for (vint i = 0; i < unprocessed.Count(); i++) { unprocessed[i]->Accept(&visitor); } } CopyFrom(instanceClass->declarations, memberDecls, true); } /////////////////////////////////////////////////////////////// // Constructor Declaration /////////////////////////////////////////////////////////////// auto ctor = Ptr(new WfConstructorDeclaration); ctor->constructorType = WfConstructorType::RawPtr; auto ctorBlock = (!needFunctionBody ? notImplemented() : Ptr(new WfBlockStatement)); ctor->statement = ctorBlock; if (baseWfType) { auto call = Ptr(new WfBaseConstructorCall); ctor->baseConstructorCalls.Add(call); call->type = CopyType(instanceClass->baseTypes[0]); baseTypeContext = baseTypeResourceItem->GetContent().Cast<GuiInstanceContext>(); // TODO: (enumerable) foreach for (auto parameter : baseTypeContext->parameters) { auto parameterTypeInfoTuple = getDefaultType(parameter->className.ToString()); auto expression = Workflow_ParseExpression( precompileContext, parameter->classPosition.originalLocation, L"cast("+parameterTypeInfoTuple.get<1>() + L") (null of object)", parameter->classPosition, errors, { 0,5 } ); if (!expression) { auto nullExpr = Ptr(new WfLiteralExpression); nullExpr->value = WfLiteralValue::Null; expression = nullExpr; } call->arguments.Add(expression); } } else if (auto group = baseType->GetTypeDescriptor()->GetConstructorGroup()) { auto ctorInfo = group->GetMethod(0); vint count = ctorInfo->GetParameterCount(); if (count > 0) { if (needFunctionBody) { if (auto call = resolvingResult.rootLoader->CreateRootInstance(precompileContext, resolvingResult, resolvingResult.rootTypeInfo, resolvingResult.rootCtorArguments, errors)) { ctor->baseConstructorCalls.Add(call); } } else { auto call = Ptr(new WfBaseConstructorCall); ctor->baseConstructorCalls.Add(call); call->type = CopyType(instanceClass->baseTypes[0]); for (vint i = 0; i < count; i++) { call->arguments.Add(CreateDefaultValue(ctorInfo->GetParameter(i)->GetType())); } } } } /////////////////////////////////////////////////////////////// // ref.LocalizedString (Property) /////////////////////////////////////////////////////////////// for (auto localized : context->localizeds) { if (auto lsTd = GetTypeDescriptor(localized->className.ToString())) { ITypeDescriptor* lsiTd = nullptr; if (auto group = lsTd->GetMethodGroupByName(L"Get", false)) { vint count = group->GetMethodCount(); for (vint i = 0; i < count; i++) { auto method = group->GetMethod(i); if (method->GetParameterCount() == 1) { auto paramTd = method->GetParameter(0)->GetType()->GetTypeDescriptor(); if (paramTd == description::GetTypeDescriptor<Locale>()) { lsiTd = method->GetReturn()->GetTypeDescriptor(); break; } } } } if (lsiTd) { auto prop = Ptr(new WfAutoPropertyDeclaration); instanceClass->declarations.Add(prop); prop->functionKind = WfFunctionKind::Normal; prop->name.value = localized->name.ToString(); prop->type = GetTypeFromTypeInfo(Workflow_GetSuggestedParameterType(precompileContext, lsiTd).Obj()); prop->configConst = WfAPConst::Writable; prop->configObserve = WfAPObserve::Observable; auto localeNameExpr = Ptr(new WfStringExpression); localeNameExpr->value.value = L"en-US"; auto defaultLocalExpr = Ptr(new WfTypeCastingExpression); defaultLocalExpr->strategy = WfTypeCastingStrategy::Strong; defaultLocalExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver<Locale>::CreateTypeInfo().Obj()); defaultLocalExpr->expression = localeNameExpr; auto getExpr = Ptr(new WfChildExpression); getExpr->parent = GetExpressionFromTypeDescriptor(lsTd); getExpr->name.value = L"Get"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = getExpr; callExpr->arguments.Add(defaultLocalExpr); prop->expression = callExpr; } else { errors.Add(GuiResourceError({ resolvingResult.resource }, localized->classPosition, L"Precompile: Class \"" + localized->className.ToString() + L"\" of localized strings \"" + localized->name.ToString() + L"\" is not a correct localized strings class.")); } } else { errors.Add(GuiResourceError({ resolvingResult.resource }, localized->classPosition, L"Precompile: Class \"" + localized->className.ToString() + L"\" of localized strings \"" + localized->name.ToString() + L"\" cannot be found.")); } } /////////////////////////////////////////////////////////////// // ref.Parameter (Variable, Getter, CtorArgument) /////////////////////////////////////////////////////////////// for (auto parameter : context->parameters) { auto parameterTypeInfoTuple = getDefaultType(parameter->className.ToString()); vint errorCount = errors.Count(); auto type = Workflow_ParseType(precompileContext, { resolvingResult.resource }, parameterTypeInfoTuple.get<1>(), parameter->classPosition, errors); if (!needFunctionBody && !parameterTypeInfoTuple.get<0>() && errorCount == errors.Count()) { if (!type || type.Cast<WfReferenceType>() || type.Cast<WfChildType>() || type.Cast<WfTopQualifiedType>()) { type = Workflow_ParseType(precompileContext, { resolvingResult.resource }, parameter->className.ToString() + L"*", parameter->classPosition, errors); } } if (type) { if (needFunctionBody) { auto decl = Ptr(new WfVariableDeclaration); instanceClass->declarations.Add(decl); decl->name.value = L"<parameter>" + parameter->name.ToString(); decl->type = CopyType(type); decl->expression = CreateDefaultValue(parameterTypeInfoTuple.get<0>().Obj()); auto att = Ptr(new WfAttribute); att->category.value = L"cpp"; att->name.value = L"Private"; decl->attributes.Add(att); Workflow_RecordScriptPosition(precompileContext, parameter->tagPosition, (Ptr<WfDeclaration>)decl); } { auto decl = Ptr(new WfFunctionDeclaration); instanceClass->declarations.Add(decl); decl->functionKind = WfFunctionKind::Normal; decl->anonymity = WfFunctionAnonymity::Named; decl->name.value = L"Get" + parameter->name.ToString(); decl->returnType = CopyType(type); if (needFunctionBody) { auto block = Ptr(new WfBlockStatement); decl->statement = block; auto ref = Ptr(new WfReferenceExpression); ref->name.value = L"<parameter>" + parameter->name.ToString(); auto returnStat = Ptr(new WfReturnStatement); returnStat->expression = ref; block->statements.Add(returnStat); } else { decl->statement = notImplemented(); } Workflow_RecordScriptPosition(precompileContext, parameter->tagPosition, (Ptr<WfDeclaration>)decl); } { auto decl = Ptr(new WfPropertyDeclaration); instanceClass->declarations.Add(decl); decl->name.value = parameter->name.ToString(); decl->type = type; decl->getter.value = L"Get" + parameter->name.ToString(); Workflow_RecordScriptPosition(precompileContext, parameter->tagPosition, (Ptr<WfDeclaration>)decl); } { auto argument = Ptr(new WfFunctionArgument); argument->name.value = L"<ctor-parameter>" + parameter->name.ToString(); argument->type = CopyType(type); ctor->arguments.Add(argument); } if (needFunctionBody) { auto refLeft = Ptr(new WfReferenceExpression); refLeft->name.value = L"<parameter>" + parameter->name.ToString(); auto refRight = Ptr(new WfReferenceExpression); refRight->name.value = L"<ctor-parameter>" + parameter->name.ToString(); auto assignExpr = Ptr(new WfBinaryExpression); assignExpr->op = WfBinaryOperator::Assign; assignExpr->first = refLeft; assignExpr->second = refRight; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = assignExpr; ctorBlock->statements.Add(exprStat); Workflow_RecordScriptPosition(precompileContext, parameter->tagPosition, (Ptr<WfStatement>)exprStat); } } } /////////////////////////////////////////////////////////////// // Event Handlers /////////////////////////////////////////////////////////////// if (needEventHandler) { List<types::PropertyResolving> infos; WorkflowEventNamesVisitor visitor(precompileContext, resolvingResult, infos, instanceClass, errors); context->instance->Accept(&visitor); } instanceClass->declarations.Add(ctor); /////////////////////////////////////////////////////////////// // Calling Constructor Class /////////////////////////////////////////////////////////////// if (needFunctionBody) { { auto getRmExpr = Ptr(new WfChildExpression); getRmExpr->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<IGuiResourceManager>()); getRmExpr->name.value = L"GetResourceManager"; auto call1Expr = Ptr(new WfCallExpression); call1Expr->function = getRmExpr; auto getResExpr = Ptr(new WfMemberExpression); getResExpr->parent = call1Expr; getResExpr->name.value = L"GetResourceFromClassName"; auto classNameExpr = Ptr(new WfStringExpression); classNameExpr->value.value = context->className; auto call2Expr = Ptr(new WfCallExpression); call2Expr->function = getResExpr; call2Expr->arguments.Add(classNameExpr); auto varDecl = Ptr(new WfVariableDeclaration); varDecl->name.value = L"<resource>"; varDecl->expression = call2Expr; auto varStat = Ptr(new WfVariableStatement); varStat->variable = varDecl; ctorBlock->statements.Add(varStat); } { auto resRef = Ptr(new WfReferenceExpression); resRef->name.value = L"<resource>"; auto resRef2 = Ptr(new WfReferenceExpression); resRef2->name.value = L"<resource>"; auto wdRef = Ptr(new WfMemberExpression); wdRef->parent = resRef2; wdRef->name.value = L"WorkingDirectory"; auto newClassExpr = Ptr(new WfNewClassExpression); newClassExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<GuiResourcePathResolver>>::CreateTypeInfo().Obj()); newClassExpr->arguments.Add(resRef); newClassExpr->arguments.Add(wdRef); auto varDecl = Ptr(new WfVariableDeclaration); varDecl->name.value = L"<resolver>"; varDecl->expression = newClassExpr; auto varStat = Ptr(new WfVariableStatement); varStat->variable = varDecl; ctorBlock->statements.Add(varStat); } { auto setRef = Ptr(new WfMemberExpression); setRef->parent = Ptr(new WfThisExpression); setRef->name.value = L"SetResourceResolver"; auto resolverRef = Ptr(new WfReferenceExpression); resolverRef->name.value = L"<resolver>"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = setRef; callExpr->arguments.Add(resolverRef); auto stat = Ptr(new WfExpressionStatement); stat->expression = callExpr; ctorBlock->statements.Add(stat); } { auto initRef = Ptr(new WfMemberExpression); initRef->parent = Ptr(new WfThisExpression); { List<WString> fragments; SplitTypeName(resolvingResult.context->className, fragments); initRef->name.value = L"<" + From(fragments).Aggregate([](const WString& a, const WString& b) {return a + L"-" + b; }) + L">Initialize"; } auto callExpr = Ptr(new WfCallExpression); callExpr->function = initRef; callExpr->arguments.Add(Ptr(new WfThisExpression)); auto stat = Ptr(new WfExpressionStatement); stat->expression = callExpr; ctorBlock->statements.Add(stat); } } /////////////////////////////////////////////////////////////// // ref.Ctor /////////////////////////////////////////////////////////////// if (context->ctorScript != L"") { if (auto stat = Workflow_ParseStatement(precompileContext, { resolvingResult.resource }, context->ctorScript, context->ctorPosition, errors)) { if (needFunctionBody) { if (!stat.Cast<WfBlockStatement>()) { auto block = Ptr(new WfBlockStatement); block->statements.Add(stat); stat = block; } auto decl = Ptr(new WfFunctionDeclaration); decl->functionKind = WfFunctionKind::Normal; decl->anonymity = WfFunctionAnonymity::Named; decl->name.value = L"<instance-ctor>"; decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<void>::CreateTypeInfo().Obj()); decl->statement = stat; instanceClass->declarations.Add(decl); { auto refCtor = Ptr(new WfReferenceExpression); refCtor->name.value = L"<instance-ctor>"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refCtor; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = callExpr; ctorBlock->statements.Add(exprStat); } } } } /////////////////////////////////////////////////////////////// // Destructor /////////////////////////////////////////////////////////////// auto dtor = Ptr(new WfDestructorDeclaration); auto dtorBlock = Ptr(new WfBlockStatement); dtor->statement = dtorBlock; /////////////////////////////////////////////////////////////// // ref.Dtor /////////////////////////////////////////////////////////////// if (context->dtorScript != L"") { if (auto stat = Workflow_ParseStatement(precompileContext, { resolvingResult.resource }, context->dtorScript, context->dtorPosition, errors)) { if (needFunctionBody) { if (!stat.Cast<WfBlockStatement>()) { auto block = Ptr(new WfBlockStatement); block->statements.Add(stat); stat = block; } auto decl = Ptr(new WfFunctionDeclaration); decl->functionKind = WfFunctionKind::Normal; decl->anonymity = WfFunctionAnonymity::Named; decl->name.value = L"<instance-dtor>"; decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<void>::CreateTypeInfo().Obj()); decl->statement = stat; instanceClass->declarations.Add(decl); { auto refDtor = Ptr(new WfReferenceExpression); refDtor->name.value = L"<instance-dtor>"; auto callExpr = Ptr(new WfCallExpression); callExpr->function = refDtor; auto exprStat = Ptr(new WfExpressionStatement); exprStat->expression = callExpr; dtorBlock->statements.Add(exprStat); } } } } /////////////////////////////////////////////////////////////// // Clear Binding Subscriptions /////////////////////////////////////////////////////////////// { auto ref = Ptr(new WfReferenceExpression); ref->name.value = L"FinalizeGeneralInstance"; Ptr<WfExpression> thisExpr = Ptr(new WfThisExpression); ITypeDescriptor* types[] = { description::GetTypeDescriptor<GuiTemplate>(), description::GetTypeDescriptor<GuiCustomControl>(), description::GetTypeDescriptor<GuiControlHost>(), }; if (!baseType) { auto currentContext = context; while (!baseType) { auto item = FindInstanceResourceItem(currentContext, currentContext->instance.Obj(), classNameRecord); if (!item) break; currentContext = item->GetContent().Cast<GuiInstanceContext>(); auto source = FindInstanceLoadingSource(currentContext, currentContext->instance.Obj()); baseType = GetInstanceLoaderManager()->GetTypeInfoForType(source.typeName); } } if (baseType) { for (auto td : types) { if (baseType->GetTypeDescriptor()->CanConvertTo(td)) { ref->name.value = L"FinalizeInstanceRecursively"; Ptr<ITypeInfo> typeInfo = Ptr(new TypeDescriptorTypeInfo(td, TypeInfoHint::Normal)); typeInfo = Ptr(new RawPtrTypeInfo(typeInfo)); auto inferExpr = Ptr(new WfInferExpression); inferExpr->type = GetTypeFromTypeInfo(typeInfo.Obj()); inferExpr->expression = thisExpr; thisExpr = inferExpr; break; } } } auto call = Ptr(new WfCallExpression); call->function = ref; call->arguments.Add(thisExpr); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; dtorBlock->statements.Add(stat); } instanceClass->declarations.Add(dtor); return module; } /*********************************************************************** GuiWorkflowSharedManagerPlugin ***********************************************************************/ #undef ERROR_CODE_PREFIX class GuiWorkflowSharedManagerPlugin; GuiWorkflowSharedManagerPlugin* sharedManagerPlugin = 0; class GuiWorkflowSharedManagerPlugin : public Object, public IGuiPlugin { protected: workflow::Parser workflowParser; Ptr<WfLexicalScopeManager> workflowManager; public: GUI_PLUGIN_NAME(GacUI_Compiler_WorkflowSharedManager) { } void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { if (controllerUnrelatedPlugins) { sharedManagerPlugin = this; } } void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override { if (controllerUnrelatedPlugins) { sharedManagerPlugin = 0; } } WfLexicalScopeManager* GetWorkflowManager(GuiResourceCpuArchitecture targetCpuArchitecture) { WfCpuArchitecture wfCpuArchitecture = WfCpuArchitecture::AsExecutable; switch (targetCpuArchitecture) { case GuiResourceCpuArchitecture::x86: wfCpuArchitecture = WfCpuArchitecture::x86; break; case GuiResourceCpuArchitecture::x64: wfCpuArchitecture = WfCpuArchitecture::x64; break; default: CHECK_FAIL(L"The target CPU architecture is unspecified."); } if (!workflowManager) { workflowManager = Ptr(new WfLexicalScopeManager(workflowParser, wfCpuArchitecture)); } else { CHECK_ERROR(workflowManager->cpuArchitecture == wfCpuArchitecture, L"The target CPU architecture cannot be changed."); } return workflowManager.Obj(); } Ptr<WfLexicalScopeManager> TransferWorkflowManager() { auto result = workflowManager; workflowManager = nullptr; return result; } }; GUI_REGISTER_PLUGIN(GuiWorkflowSharedManagerPlugin) WfLexicalScopeManager* Workflow_GetSharedManager(GuiResourceCpuArchitecture targetCpuArchitecture) { return sharedManagerPlugin->GetWorkflowManager(targetCpuArchitecture); } Ptr<WfLexicalScopeManager> Workflow_TransferSharedManager() { return sharedManagerPlugin->TransferWorkflowManager(); } } } /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWCOLLECTREFERENCES.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace reflection::description; using namespace collections; using namespace workflow::analyzer; /*********************************************************************** Workflow_AdjustPropertySearchType ***********************************************************************/ IGuiInstanceLoader::TypeInfo Workflow_AdjustPropertySearchType(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader::TypeInfo resolvedTypeInfo, GlobalStringKey prop) { if (resolvedTypeInfo.typeName.ToString() == resolvingResult.context->className) { if (auto propTd = resolvedTypeInfo.typeInfo->GetTypeDescriptor()) { vint baseCount = propTd->GetBaseTypeDescriptorCount(); for (vint i = 0; i < baseCount; i++) { auto baseTd = propTd->GetBaseTypeDescriptor(i); if (auto ctorGroup = baseTd->GetConstructorGroup()) { if (ctorGroup->GetMethodCount() == 1) { auto ctor = ctorGroup->GetMethod(0); auto propertyName = prop.ToString(); auto ctorArgumentName = L"<ctor-parameter>" + propertyName; vint paramCount = ctor->GetParameterCount(); for (vint j = 0; j < paramCount; j++) { auto parameterInfo = ctor->GetParameter(j); if (parameterInfo->GetName() == ctorArgumentName) { if (baseTd->GetPropertyByName(propertyName, false)) { resolvedTypeInfo.typeInfo = CopyTypeInfo(ctor->GetReturn()); resolvedTypeInfo.typeName = GlobalStringKey::Get(baseTd->GetTypeName()); return resolvedTypeInfo; } break; } } } } } } } return resolvedTypeInfo; } /*********************************************************************** Workflow_GetPropertyTypes ***********************************************************************/ bool Workflow_GetPropertyTypes(GuiResourcePrecompileContext& precompileContext, WString& errorPrefix, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, IGuiInstanceLoader::TypeInfo resolvedTypeInfo, GlobalStringKey prop, Ptr<GuiAttSetterRepr::SetterValue> setter, collections::List<types::PropertyResolving>& possibleInfos, GuiResourceError::List& errors) { resolvedTypeInfo = Workflow_AdjustPropertySearchType(precompileContext, resolvingResult, resolvedTypeInfo, prop); bool reportedNotSupported = false; IGuiInstanceLoader::PropertyInfo propertyInfo(resolvedTypeInfo, prop); errorPrefix = L"Precompile: Property \"" + propertyInfo.propertyName.ToString() + L"\" of type \"" + resolvedTypeInfo.typeName.ToString() + L"\""; { auto currentLoader = loader; while (currentLoader) { if (auto propertyTypeInfo = currentLoader->GetPropertyType(precompileContext, propertyInfo)) { if (propertyTypeInfo->support == GuiInstancePropertyInfo::NotSupport) { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, errorPrefix + L" is not supported.")); reportedNotSupported = true; break; } else { types::PropertyResolving resolving; resolving.loader = currentLoader; resolving.propertyInfo = propertyInfo; resolving.info = propertyTypeInfo; possibleInfos.Add(resolving); if (setter->binding == GlobalStringKey::_Set) { break; } } if (propertyTypeInfo->mergability == GuiInstancePropertyInfo::NotMerge) { break; } } currentLoader = GetInstanceLoaderManager()->GetParentLoader(currentLoader); } } if (possibleInfos.Count() == 0) { if (!reportedNotSupported) { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, errorPrefix + L" does not exist.")); } return false; } else { return true; } } /*********************************************************************** WorkflowReferenceNamesVisitor ***********************************************************************/ class WorkflowReferenceNamesVisitor : public Object, public GuiValueRepr::IVisitor { public: GuiResourcePrecompileContext& precompileContext; types::ResolvingResult& resolvingResult; vint& generatedNameCount; GuiResourceError::List& errors; List<types::PropertyResolving>& candidatePropertyTypeInfos; IGuiInstanceLoader::TypeInfo resolvedTypeInfo; vint selectedPropertyTypeInfo = -1; WorkflowReferenceNamesVisitor(GuiResourcePrecompileContext& _precompileContext, types::ResolvingResult& _resolvingResult, List<types::PropertyResolving>& _candidatePropertyTypeInfos, vint& _generatedNameCount, GuiResourceError::List& _errors) :precompileContext(_precompileContext) , resolvingResult(_resolvingResult) , candidatePropertyTypeInfos(_candidatePropertyTypeInfos) , generatedNameCount(_generatedNameCount) , errors(_errors) { } void Visit(GuiTextRepr* repr)override { if (selectedPropertyTypeInfo == -1) { selectedPropertyTypeInfo = 0; } auto candidate = candidatePropertyTypeInfos[selectedPropertyTypeInfo]; auto propertyInfo = candidate.propertyInfo; ITypeDescriptor* td = nullptr; { auto typeInfo = candidate.info->acceptableTypes[0]; if (auto deserializer = GetInstanceLoaderManager()->GetInstanceDeserializer(propertyInfo, typeInfo.Obj())) { td = deserializer->DeserializeAs(propertyInfo, typeInfo.Obj())->GetTypeDescriptor(); } else { td = typeInfo->GetTypeDescriptor(); } } if (auto st = td->GetSerializableType()) { Value value; if (st->Deserialize(repr->text, value)) { resolvingResult.propertyResolvings.Add(repr, candidate); } else { auto error = L"Precompile: Property \"" + propertyInfo.propertyName.ToString() + L"\" of type \"" + propertyInfo.typeInfo.typeName.ToString() + L"\" does not accept a value of text \"" + repr->text + L"\" because it is not in a correct format of the serializable type \"" + td->GetTypeName() + L"\"."; errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, error)); } } else { switch (td->GetTypeDescriptorFlags()) { case TypeDescriptorFlags::FlagEnum: case TypeDescriptorFlags::NormalEnum: case TypeDescriptorFlags::Struct: { if (auto expression = Workflow_ParseTextValue(precompileContext, td, { resolvingResult.resource }, repr->text, repr->tagPosition, errors)) { resolvingResult.propertyResolvings.Add(repr, candidate); } } break; default: { auto error = L"Precompile: Property \"" + propertyInfo.propertyName.ToString() + L"\" of type \"" + propertyInfo.typeInfo.typeName.ToString() + L"\" does not accept a value of text \"" + repr->text + L"\" because its type \"" + td->GetTypeName() + L"\" is not serializable."; errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, error)); } } } } void Visit(GuiAttSetterRepr* repr)override { if (candidatePropertyTypeInfos.Count() > 0) { resolvingResult.propertyResolvings.Add(repr, candidatePropertyTypeInfos[selectedPropertyTypeInfo]); } bool isReferenceType = (resolvedTypeInfo.typeInfo->GetTypeDescriptor()->GetTypeDescriptorFlags() & TypeDescriptorFlags::ReferenceType) != TypeDescriptorFlags::Undefined; if (repr->instanceName == GlobalStringKey::Empty) { if (isReferenceType) { auto name = GlobalStringKey::Get(L"<precompile>" + itow(generatedNameCount++)); repr->instanceName = name; resolvingResult.typeInfos.Add(name, resolvedTypeInfo); } } else if (resolvingResult.typeInfos.Keys().Contains(repr->instanceName)) { auto error = L"Precompile: Referece name \"" + repr->instanceName.ToString() + L"\" conflict with an existing named object."; errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, error)); } else if (!isReferenceType) { auto error = L"Precompile: Reference name \"" + repr->instanceName.ToString() + L"\" cannot be added to a non-reference instance of type \"" + resolvedTypeInfo.typeName.ToString() + L"\"."; errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, error)); } else { resolvingResult.referenceNames.Add(repr->instanceName); resolvingResult.typeInfos.Add(repr->instanceName, resolvedTypeInfo); } auto loader = GetInstanceLoaderManager()->GetLoader(resolvedTypeInfo.typeName); // TODO: (enumerable) foreach on dictionary for (auto [setter, index] : indexed(repr->setters.Values())) { List<types::PropertyResolving> possibleInfos; auto prop = repr->setters.Keys()[index]; WString errorPrefix; if (Workflow_GetPropertyTypes(precompileContext, errorPrefix, resolvingResult, loader, resolvedTypeInfo, prop, setter, possibleInfos, errors)) { if (setter->binding == GlobalStringKey::Empty) { for (auto value : setter->values) { WorkflowReferenceNamesVisitor visitor(precompileContext, resolvingResult, possibleInfos, generatedNameCount, errors); value->Accept(&visitor); } } else if (setter->binding == GlobalStringKey::_Set) { if (possibleInfos[0].info->support == GuiInstancePropertyInfo::SupportSet) { auto setTarget = dynamic_cast<GuiAttSetterRepr*>(setter->values[0].Obj()); WorkflowReferenceNamesVisitor visitor(precompileContext, resolvingResult, possibleInfos, generatedNameCount, errors); auto typeInfo = possibleInfos[0].info->acceptableTypes[0]; visitor.selectedPropertyTypeInfo = 0; visitor.resolvedTypeInfo.typeName = GlobalStringKey::Get(typeInfo->GetTypeDescriptor()->GetTypeName()); visitor.resolvedTypeInfo.typeInfo = typeInfo; setTarget->Accept(&visitor); } else { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, L"[INTERNAL-ERROR] " + errorPrefix + L" does not support the \"-set\" binding.")); } } else if (setter->binding != GlobalStringKey::Empty) { auto binder = GetInstanceLoaderManager()->GetInstanceBinder(setter->binding); if (binder) { if (possibleInfos[0].info->usage == GuiInstancePropertyInfo::ConstructorArgument) { if (possibleInfos[0].info->bindability == GuiInstancePropertyInfo::NotBindable) { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, errorPrefix + L" cannot be assigned using binding \"-" + setter->binding.ToString() + L"\". Because it is a non-bindable constructor argument.")); } else if (!binder->ApplicableToConstructorArgument()) { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, errorPrefix + L" cannot be assigned using binding \"-" + setter->binding.ToString() + L"\". Because it is a constructor argument, and this binding does not apply to any constructor argument.")); } } } else { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, errorPrefix + L" cannot be assigned using an unexisting binding \"-" + setter->binding.ToString() + L"\".")); } if (setter->values.Count() == 1 && setter->values[0].Cast<GuiTextRepr>()) { resolvingResult.propertyResolvings.Add(setter->values[0].Obj(), possibleInfos[0]); } else { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, L"Precompile: Binder \"" + setter->binding.ToString() + L"\" requires the text value of property \"" + prop.ToString() + L"\".")); } } } } Group<GlobalStringKey, IGuiInstanceLoader*> properties; CopyFrom( properties, From(repr->setters) .SelectMany([=, this](Pair<GlobalStringKey, Ptr<GuiAttSetterRepr::SetterValue>> item) { return From(item.value->values) .Where([=, this](Ptr<GuiValueRepr> value) { return resolvingResult.propertyResolvings.Keys().Contains(value.Obj()); }) .Select([=, this](Ptr<GuiValueRepr> value) { auto loader = resolvingResult.propertyResolvings[value.Obj()].loader; return Pair<GlobalStringKey, IGuiInstanceLoader*>(item.key, loader); }); }) .Distinct() ); if (resolvingResult.context->instance.Obj() != repr) { List<GlobalStringKey> requiredProps; { auto currentLoader = loader; while (currentLoader) { currentLoader->GetRequiredPropertyNames(precompileContext, resolvedTypeInfo, requiredProps); currentLoader = GetInstanceLoaderManager()->GetParentLoader(currentLoader); } } for (auto prop : From(requiredProps).Distinct()) { if (!properties.Keys().Contains(prop)) { Ptr<GuiInstancePropertyInfo> info; { auto currentLoader = loader; while (currentLoader && !info) { info = currentLoader->GetPropertyType(precompileContext, { resolvedTypeInfo, prop }); currentLoader = GetInstanceLoaderManager()->GetParentLoader(currentLoader); } } errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Missing required " + WString(info->usage == GuiInstancePropertyInfo::ConstructorArgument ? L"constructor argument" : L"property") + L" \"" + prop.ToString() + L"\" of type \"" + resolvedTypeInfo.typeName.ToString() + L"\".")); } } } while (properties.Count() > 0) { auto prop = properties.Keys()[0]; auto loader = properties.GetByIndex(0)[0]; IGuiInstanceLoader::PropertyInfo propertyInfo(resolvedTypeInfo, prop); List<GlobalStringKey> pairProps; loader->GetPairedProperties(precompileContext, propertyInfo, pairProps); if (pairProps.Count() > 0) { List<GlobalStringKey> missingProps; for (auto key : pairProps) { if (!properties.Contains(key, loader)) { missingProps.Add(key); } } if (missingProps.Count() > 0) { WString error = L"Precompile: When you assign to property \"" + prop.ToString() + L"\" of type \"" + resolvedTypeInfo.typeName.ToString() + L"\", the following missing properties are required: "; for (auto [key, index] : indexed(missingProps)) { if (index > 0)error += L", "; error += L"\"" + key.ToString() + L"\""; } error += L"."; errors.Add(GuiResourceError({ resolvingResult.resource }, repr->setters[prop]->attPosition, error)); } for (auto key : pairProps) { properties.Remove(key, loader); } } else { properties.Remove(prop, loader); } } for (auto handler : repr->eventHandlers.Values()) { if (handler->binding != GlobalStringKey::Empty) { auto binder = GetInstanceLoaderManager()->GetInstanceEventBinder(handler->binding); if (!binder) { errors.Add(GuiResourceError({ resolvingResult.resource }, handler->attPosition, L"The appropriate IGuiInstanceEventBinder of binding \"-" + handler->binding.ToString() + L"\" cannot be found.")); } } } } void Visit(GuiConstructorRepr* repr)override { bool found = false; bool inferType = repr->typeNamespace == GlobalStringKey::Empty && repr->typeName == GlobalStringKey::_InferType; if (inferType) { if (candidatePropertyTypeInfos.Count() == 1) { auto info = candidatePropertyTypeInfos[0].info; if (info->acceptableTypes.Count() == 1) { auto typeInfo = info->acceptableTypes[0]; resolvedTypeInfo.typeName = GlobalStringKey::Get(typeInfo->GetTypeDescriptor()->GetTypeName()); resolvedTypeInfo.typeInfo = typeInfo; } } } else { if (repr == resolvingResult.context->instance.Obj()) { auto fullName = GlobalStringKey::Get(resolvingResult.context->className); if (auto typeInfo = GetInstanceLoaderManager()->GetTypeInfoForType(fullName)) { resolvedTypeInfo.typeName = fullName; resolvedTypeInfo.typeInfo = typeInfo; found = true; } } if (!found) { auto source = FindInstanceLoadingSource(resolvingResult.context, repr); resolvedTypeInfo.typeName = source.typeName; resolvedTypeInfo.typeInfo = GetInstanceLoaderManager()->GetTypeInfoForType(source.typeName); } } if (resolvingResult.context->instance == repr) { static const wchar_t Prefix[] = L"<ctor-parameter>"; static const vint PrefixLength = (vint)sizeof(Prefix) / sizeof(*Prefix) - 1; auto source = FindInstanceLoadingSource(resolvingResult.context, repr); if (auto baseTd = description::GetTypeDescriptor(source.typeName.ToString())) { if (auto ctorGroup = baseTd->GetConstructorGroup()) { if (ctorGroup->GetMethodCount() == 1) { auto ctor = ctorGroup->GetMethod(0); vint paramCount = ctor->GetParameterCount(); for (vint i = 0; i < paramCount; i++) { auto parameterInfo = ctor->GetParameter(i); auto ctorArg = parameterInfo->GetName(); if (ctorArg.Length() > PrefixLength && ctorArg.Left(PrefixLength) == Prefix) { auto propName = ctorArg.Right(ctorArg.Length() - PrefixLength); if (baseTd->GetPropertyByName(propName, false)) { if (!repr->setters.Keys().Contains(GlobalStringKey::Get(propName))) { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Missing required property \"" + propName + L"\" of type \"" + resolvedTypeInfo.typeName.ToString() + L"\" for its base type \"" + baseTd->GetTypeName() + L"\".")); } } } } } } } } if (resolvedTypeInfo.typeInfo) { for (vint i = 0; i < candidatePropertyTypeInfos.Count(); i++) { const auto& typeInfos = candidatePropertyTypeInfos[i].info->acceptableTypes; // TODO: (enumerable) foreach for (vint j = 0; j < typeInfos.Count(); j++) { if (resolvedTypeInfo.typeInfo->GetTypeDescriptor()->CanConvertTo(typeInfos[j]->GetTypeDescriptor())) { selectedPropertyTypeInfo = i; goto FINISH_MATCHING; } } } FINISH_MATCHING: if (selectedPropertyTypeInfo == -1 && candidatePropertyTypeInfos.Count() > 0) { auto propertyInfo = candidatePropertyTypeInfos[0].propertyInfo; auto error = L"Precompile: Property \"" + propertyInfo.propertyName.ToString() + L"\" of type \"" + propertyInfo.typeInfo.typeName.ToString() + L"\" does not accept a value of type \"" + resolvedTypeInfo.typeName.ToString() + L"\" because it only accepts value of the following types: "; // TODO: (enumerable) foreach for (vint i = 0; i < candidatePropertyTypeInfos.Count(); i++) { const auto& typeInfos = candidatePropertyTypeInfos[i].info->acceptableTypes; // TODO: (enumerable) LinqLAggregate for (vint j = 0; j < typeInfos.Count(); j++) { if (i != 0 || j != 0) { error += L", "; } error += L"\"" + typeInfos[j]->GetTypeFriendlyName() + L"\""; } } error += L"."; errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, error)); } else { if (repr->setters.Count() == 1 && repr->setters.Keys()[0] == GlobalStringKey::Empty) { auto setter = repr->setters.Values()[0]; if (setter->values.Count() == 1) { if (auto text = setter->values[0].Cast<GuiTextRepr>()) { if (candidatePropertyTypeInfos.Count() == 0) { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Type \"" + resolvedTypeInfo.typeName.ToString() + L"\" cannot be used to create an instance.")); } else { Visit(text.Obj()); auto index = resolvingResult.propertyResolvings.Keys().IndexOf(text.Obj()); if (index != -1) { auto value = resolvingResult.propertyResolvings.Values()[index]; resolvingResult.propertyResolvings.Remove(text.Obj()); resolvingResult.propertyResolvings.Add(repr, value); } } return; } } } if (resolvingResult.context->instance.Obj() != repr) { auto loader = GetInstanceLoaderManager()->GetLoader(resolvedTypeInfo.typeName); while (loader) { if (loader->CanCreate(resolvedTypeInfo)) { break; } loader = GetInstanceLoaderManager()->GetParentLoader(loader); } if (loader) { if (repr == resolvingResult.context->instance.Obj()) { List<GlobalStringKey> propertyNames; loader->GetPropertyNames(precompileContext, resolvedTypeInfo, propertyNames); // TODO: (enumerable) foreach:indexed(alterable(reversed)) for (vint i = propertyNames.Count() - 1; i >= 0; i--) { auto info = loader->GetPropertyType(precompileContext, { resolvedTypeInfo, propertyNames[i] }); if (!info || info->usage == GuiInstancePropertyInfo::Property) { propertyNames.RemoveAt(i); } } if (propertyNames.Count() == 1) { if (propertyNames[0] != GlobalStringKey::_ControlTemplate) { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Type \"" + resolvedTypeInfo.typeName.ToString() + L"\" cannot be used to create a root instance, because its only constructor parameter is not for a the control template.")); } } else if (propertyNames.Count() > 1) { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Type \"" + resolvedTypeInfo.typeName.ToString() + L"\" cannot be used to create a root instance, because it has more than one constructor parameters. A root instance type can only have one constructor parameter, which is for the control template.")); } } } else { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"Precompile: Type \"" + resolvedTypeInfo.typeName.ToString() + L"\" cannot be used to create an instance.")); } } Visit((GuiAttSetterRepr*)repr); } } else { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"[INTERNAL-ERROR] Precompile: Failed to find type \"" + (repr->typeNamespace == GlobalStringKey::Empty ? repr->typeName.ToString() : repr->typeNamespace.ToString() + L":" + repr->typeName.ToString() ) + L"\".")); } } }; Ptr<reflection::description::ITypeInfo> Workflow_GetSuggestedParameterType(GuiResourcePrecompileContext& precompileContext, reflection::description::ITypeDescriptor* typeDescriptor) { auto elementType = Ptr(new TypeDescriptorTypeInfo(typeDescriptor, TypeInfoHint::Normal)); if ((typeDescriptor->GetTypeDescriptorFlags() & TypeDescriptorFlags::ReferenceType) != TypeDescriptorFlags::Undefined) { bool isShared = false; bool isRaw = false; if (auto ctorGroup = typeDescriptor->GetConstructorGroup()) { vint count = ctorGroup->GetMethodCount(); for (vint i = 0; i < count; i++) { auto returnType = ctorGroup->GetMethod(i)->GetReturn(); switch (returnType->GetDecorator()) { case ITypeInfo::RawPtr: isRaw = true; break; case ITypeInfo::SharedPtr: isShared = true; break; default:; } } } if (!isShared && !isRaw) { return Ptr(new SharedPtrTypeInfo(elementType)); } else if (isShared) { return Ptr(new SharedPtrTypeInfo(elementType)); } else { return Ptr(new RawPtrTypeInfo(elementType)); } } else { return elementType; } } IGuiInstanceLoader::TypeInfo Workflow_CollectReferences(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GuiResourceError::List& errors) { for (auto parameter : resolvingResult.context->parameters) { auto type = GetTypeDescriptor(parameter->className.ToString()); if (!type) { errors.Add(GuiResourceError({ resolvingResult.resource }, parameter->classPosition, L"Precompile: Cannot find type \"" + parameter->className.ToString() + L"\".")); } else if (resolvingResult.typeInfos.Keys().Contains(parameter->name)) { errors.Add(GuiResourceError({ resolvingResult.resource }, parameter->classPosition, L"[INTERNAL-ERROR] Precompile: Parameter \"" + parameter->name.ToString() + L"\" conflict with an existing named object.")); } else { auto referenceType = Workflow_GetSuggestedParameterType(precompileContext, type); resolvingResult.typeInfos.Add(parameter->name, { GlobalStringKey::Get(type->GetTypeName()),referenceType }); } } List<types::PropertyResolving> infos; vint generatedNameCount = 0; WorkflowReferenceNamesVisitor visitor(precompileContext, resolvingResult, infos, generatedNameCount, errors); resolvingResult.context->instance->Accept(&visitor); return visitor.resolvedTypeInfo; } } } /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWGENERATEBINDINGS.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace workflow; using namespace collections; using namespace reflection::description; /*********************************************************************** WorkflowGenerateBindingVisitor ***********************************************************************/ class WorkflowGenerateBindingVisitor : public Object, public GuiValueRepr::IVisitor { public: GuiResourcePrecompileContext& precompileContext; types::ResolvingResult& resolvingResult; Ptr<WfBlockStatement> statements; GuiResourceError::List& errors; WorkflowGenerateBindingVisitor(GuiResourcePrecompileContext& _precompileContext, types::ResolvingResult& _resolvingResult, Ptr<WfBlockStatement> _statements, GuiResourceError::List& _errors) :precompileContext(_precompileContext) , resolvingResult(_resolvingResult) , errors(_errors) , statements(_statements) { } /////////////////////////////////////////////////////////////////////////////////// Ptr<WfStatement> ProcessPropertyBinding( GuiAttSetterRepr* repr, IGuiInstanceLoader::TypeInfo reprTypeInfo, Ptr<GuiAttSetterRepr::SetterValue> setter, GlobalStringKey propertyName ) { if (auto binder = GetInstanceLoaderManager()->GetInstanceBinder(setter->binding)) { auto propertyResolving = resolvingResult.propertyResolvings[setter->values[0].Obj()]; if (propertyResolving.info->usage == GuiInstancePropertyInfo::Property) { WString expressionCode = setter->values[0].Cast<GuiTextRepr>()->text; auto instancePropertyInfo = reprTypeInfo.typeInfo->GetTypeDescriptor()->GetPropertyByName(propertyName.ToString(), true); if (instancePropertyInfo || !binder->RequirePropertyExist()) { if (auto statement = binder->GenerateInstallStatement( precompileContext, resolvingResult, repr->instanceName, instancePropertyInfo, propertyResolving.loader, propertyResolving.propertyInfo, propertyResolving.info, expressionCode, setter->values[0]->tagPosition, errors)) { return statement; } } else { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, L"Precompile: Binder \"" + setter->binding.ToString() + L"\" requires property \"" + propertyName.ToString() + L"\" to physically appear in type \"" + reprTypeInfo.typeName.ToString() + L"\".")); } } } else { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, L"[INTERNAL-ERROR] Precompile: The appropriate IGuiInstanceBinder of binding \"-" + setter->binding.ToString() + L"\" cannot be found.")); } return nullptr; } /////////////////////////////////////////////////////////////////////////////////// Ptr<WfStatement> ProcessEventBinding( GuiAttSetterRepr* repr, IGuiInstanceLoader::TypeInfo reprTypeInfo, Ptr<GuiAttSetterRepr::EventValue> handler, GlobalStringKey propertyName ) { auto td = reprTypeInfo.typeInfo->GetTypeDescriptor(); auto eventInfo = td->GetEventByName(propertyName.ToString(), true); if (!eventInfo) { errors.Add(GuiResourceError({ resolvingResult.resource }, handler->attPosition, L"[INTERNAL-ERROR] Precompile: Event \"" + propertyName.ToString() + L"\" cannot be found in type \"" + reprTypeInfo.typeName.ToString() + L"\".")); } else { if (handler->binding == GlobalStringKey::Empty) { return Workflow_InstallEvent(precompileContext, resolvingResult, repr->instanceName, eventInfo, handler->value); } else { auto binder = GetInstanceLoaderManager()->GetInstanceEventBinder(handler->binding); if (binder) { return binder->GenerateInstallStatement(precompileContext, resolvingResult, repr->instanceName, eventInfo, handler->value, handler->valuePosition, errors); } else { errors.Add(GuiResourceError({ resolvingResult.resource }, handler->attPosition, L"[INTERNAL-ERROR] The appropriate IGuiInstanceEventBinder of binding \"-" + handler->binding.ToString() + L"\" cannot be found.")); } } } return nullptr; } /////////////////////////////////////////////////////////////////////////////////// void Visit(GuiTextRepr* repr)override { } void Visit(GuiAttSetterRepr* repr)override { IGuiInstanceLoader::TypeInfo reprTypeInfo; if (repr->instanceName != GlobalStringKey::Empty) { reprTypeInfo = resolvingResult.typeInfos[repr->instanceName]; } if (reprTypeInfo.typeInfo && (reprTypeInfo.typeInfo->GetTypeDescriptor()->GetTypeDescriptorFlags() & TypeDescriptorFlags::ReferenceType) != TypeDescriptorFlags::Undefined) { WORKFLOW_ENVIRONMENT_VARIABLE_ADD // TODO: (enumerable) foreach on dictionary for (auto [setter, index] : indexed(repr->setters.Values())) { auto propertyName = repr->setters.Keys()[index]; if (setter->binding != GlobalStringKey::Empty && setter->binding != GlobalStringKey::_Set) { if (auto statement = ProcessPropertyBinding(repr, reprTypeInfo, setter, propertyName)) { Workflow_RecordScriptPosition(precompileContext, setter->values[0]->tagPosition, statement); statements->statements.Add(statement); } } else { for (auto value : setter->values) { value->Accept(this); } } } // TODO: (enumerable) foreach on dictionary for (auto [handler, index] : indexed(repr->eventHandlers.Values())) { if (reprTypeInfo.typeInfo) { GlobalStringKey propertyName = repr->eventHandlers.Keys()[index]; if (auto statement = ProcessEventBinding(repr, reprTypeInfo, handler, propertyName)) { Workflow_RecordScriptPosition(precompileContext, handler->valuePosition, statement); statements->statements.Add(statement); } } } WORKFLOW_ENVIRONMENT_VARIABLE_REMOVE } } void Visit(GuiConstructorRepr* repr)override { Visit((GuiAttSetterRepr*)repr); } }; void Workflow_GenerateBindings(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, Ptr<WfBlockStatement> statements, GuiResourceError::List& errors) { WorkflowGenerateBindingVisitor visitor(precompileContext, resolvingResult, statements, errors); resolvingResult.context->instance->Accept(&visitor); for (auto localized : resolvingResult.context->localizeds) { auto code = L"bind(" + localized->className.ToString() + L"::Get(presentation::controls::GuiApplication::GetApplication().Locale))"; if (auto bindExpr = Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, code, localized->tagPosition, errors)) { auto instancePropertyInfo = resolvingResult.rootTypeInfo.typeInfo->GetTypeDescriptor()->GetPropertyByName(localized->name.ToString(), true); if (auto statement = Workflow_InstallBindProperty(precompileContext, resolvingResult, resolvingResult.context->instance->instanceName, instancePropertyInfo, bindExpr)) { Workflow_RecordScriptPosition(precompileContext, localized->tagPosition, statement); statements->statements.Add(statement); } } } } } } /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWGENERATECREATING.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace workflow; using namespace workflow::analyzer; using namespace reflection::description; /*********************************************************************** WorkflowGenerateCreatingVisitor ***********************************************************************/ class WorkflowGenerateCreatingVisitor : public Object, public GuiValueRepr::IVisitor { public: GuiResourcePrecompileContext& precompileContext; types::ResolvingResult& resolvingResult; Ptr<WfBlockStatement> statements; GuiResourceError::List& errors; WorkflowGenerateCreatingVisitor(GuiResourcePrecompileContext& _precompileContext, types::ResolvingResult& _resolvingResult, Ptr<WfBlockStatement> _statements, GuiResourceError::List& _errors) :precompileContext(_precompileContext) , resolvingResult(_resolvingResult) , errors(_errors) , statements(_statements) { } /////////////////////////////////////////////////////////////////////////////////// IGuiInstanceLoader::ArgumentInfo GetArgumentInfo(GuiResourceTextPos attPosition, GuiValueRepr* repr) { IGuiInstanceLoader::PropertyInfo propertyInfo; Ptr<ITypeInfo> typeInfo = nullptr; bool serializable = false; WString textValue; GuiResourceTextPos textValuePosition; GuiConstructorRepr* ctor = nullptr; if (auto text = dynamic_cast<GuiTextRepr*>(repr)) { auto resolving = resolvingResult.propertyResolvings[repr]; propertyInfo = resolving.propertyInfo; typeInfo = resolving.info->acceptableTypes[0]; serializable = true; textValue = text->text; textValuePosition = text->tagPosition; } else if ((ctor = dynamic_cast<GuiConstructorRepr*>(repr))) { if (ctor->instanceName == GlobalStringKey::Empty) { auto resolving = resolvingResult.propertyResolvings[repr]; propertyInfo = resolving.propertyInfo; typeInfo = resolving.info->acceptableTypes[0]; } else { typeInfo = resolvingResult.typeInfos[ctor->instanceName].typeInfo; } if ((typeInfo->GetTypeDescriptor()->GetTypeDescriptorFlags() & TypeDescriptorFlags::StructType) != TypeDescriptorFlags::Undefined) { serializable = true; auto value = ctor->setters.Values()[0]->values[0].Cast<GuiTextRepr>(); textValue = value->text; textValuePosition = value->tagPosition; } } IGuiInstanceLoader::ArgumentInfo argumentInfo; argumentInfo.typeInfo = typeInfo; argumentInfo.attPosition = attPosition; if (serializable) { if (auto deserializer = GetInstanceLoaderManager()->GetInstanceDeserializer(propertyInfo, typeInfo.Obj())) { auto typeInfoAs = deserializer->DeserializeAs(propertyInfo, typeInfo.Obj()); if (auto expression = Workflow_ParseTextValue(precompileContext, typeInfoAs->GetTypeDescriptor(), { resolvingResult.resource }, textValue, textValuePosition, errors)) { argumentInfo.expression = deserializer->Deserialize(precompileContext, resolvingResult, propertyInfo, typeInfo.Obj(), expression, textValuePosition, errors); } } else { argumentInfo.expression = Workflow_ParseTextValue(precompileContext, typeInfo->GetTypeDescriptor(), { resolvingResult.resource }, textValue, textValuePosition, errors); } argumentInfo.valuePosition = textValuePosition; } else { repr->Accept(this); auto ref = Ptr(new WfReferenceExpression); ref->name.value = ctor->instanceName.ToString(); argumentInfo.expression = ref; } if (argumentInfo.expression) { Workflow_RecordScriptPosition(precompileContext, repr->tagPosition, argumentInfo.expression); } return argumentInfo; } /////////////////////////////////////////////////////////////////////////////////// Ptr<WfStatement> ProcessPropertySet( IGuiInstanceLoader::PropertyInfo propInfo, GuiAttSetterRepr* repr, Ptr<GuiAttSetterRepr::SetterValue> setter, GuiAttSetterRepr* setTarget ) { auto info = resolvingResult.propertyResolvings[setTarget]; vint errorCount = errors.Count(); if (auto expr = info.loader->GetParameter(precompileContext, resolvingResult, propInfo, repr->instanceName, setter->attPosition, errors)) { auto refInstance = Ptr(new WfReferenceExpression); refInstance->name.value = setTarget->instanceName.ToString(); auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refInstance; assign->second = expr; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; return stat; } else if (errorCount == errors.Count()) { errors.Add(GuiResourceError({ resolvingResult.resource }, setTarget->tagPosition, L"[INTERNAL-ERROR] Precompile: Something is wrong when retriving the property \"" + propInfo.propertyName.ToString() + L"\" from an instance of type \"" + propInfo.typeInfo.typeName.ToString() + L"\".")); } return nullptr; } /////////////////////////////////////////////////////////////////////////////////// Ptr<WfStatement> ProcessPropertyCollection( IGuiInstanceLoader::PropertyInfo propInfo, GuiAttSetterRepr* repr, Group<GlobalStringKey, IGuiInstanceLoader*>& usedProps, Ptr<GuiAttSetterRepr::SetterValue> setter, types::PropertyResolving info, Ptr<GuiValueRepr> value ) { if (!usedProps.Contains(propInfo.propertyName, info.loader)) { usedProps.Add(propInfo.propertyName, info.loader); } vint errorCount = errors.Count(); IGuiInstanceLoader::ArgumentMap arguments; arguments.Add(propInfo.propertyName, GetArgumentInfo(setter->attPosition, value.Obj())); if (auto stat = info.loader->AssignParameters(precompileContext, resolvingResult, propInfo.typeInfo, repr->instanceName, arguments, setter->attPosition, errors)) { return stat; } else if (errorCount == errors.Count()) { errors.Add(GuiResourceError({ resolvingResult.resource }, value->tagPosition, L"[INTERNAL-ERROR] Precompile: Something is wrong when assigning to property " + propInfo.propertyName.ToString() + L" to an instance of type \"" + propInfo.typeInfo.typeName.ToString() + L"\".")); } return nullptr; } /////////////////////////////////////////////////////////////////////////////////// Ptr<WfStatement> ProcessPropertyOthers( IGuiInstanceLoader::PropertyInfo propInfo, GuiAttSetterRepr* repr, Group<GlobalStringKey, IGuiInstanceLoader*>& usedProps, Ptr<GuiAttSetterRepr::SetterValue> setter, types::PropertyResolving info, Ptr<GuiValueRepr> value ) { List<GlobalStringKey> pairedProps; info.loader->GetPairedProperties(precompileContext, propInfo, pairedProps); if (pairedProps.Count() == 0) { pairedProps.Add(propInfo.propertyName); } vint errorCount = errors.Count(); IGuiInstanceLoader::ArgumentMap arguments; for (auto pairedProp : pairedProps) { usedProps.Add(pairedProp, info.loader); auto pairedSetter = repr->setters[pairedProp]; for (auto pairedValue : pairedSetter->values) { auto pairedInfo = resolvingResult.propertyResolvings[pairedValue.Obj()]; if (pairedInfo.loader == info.loader) { arguments.Add(pairedProp, GetArgumentInfo(pairedSetter->attPosition, pairedValue.Obj())); } } } if (auto stat = info.loader->AssignParameters(precompileContext, resolvingResult, propInfo.typeInfo, repr->instanceName, arguments, setter->attPosition, errors)) { return stat; } else if (errorCount == errors.Count()) { WString propNames; // TODO: (enumerable) Linq:Aggregate for (auto [pairedProp, propIndex] : indexed(pairedProps)) { if (propIndex > 0)propNames += L", "; propNames += L"\"" + pairedProp.ToString() + L"\""; } errors.Add(GuiResourceError({ resolvingResult.resource }, value->tagPosition, L"[INTERNAL-ERROR] Precompile: Something is wrong when assigning to properties " + propNames + L" to an instance of type \"" + propInfo.typeInfo.typeName.ToString() + L"\".")); } return nullptr; } /////////////////////////////////////////////////////////////////////////////////// void Visit(GuiTextRepr* repr)override { } void Visit(GuiAttSetterRepr* repr)override { auto reprTypeInfo = resolvingResult.typeInfos[repr->instanceName]; if (reprTypeInfo.typeInfo && (reprTypeInfo.typeInfo->GetTypeDescriptor()->GetTypeDescriptorFlags() & TypeDescriptorFlags::ReferenceType) != TypeDescriptorFlags::Undefined) { WORKFLOW_ENVIRONMENT_VARIABLE_ADD Group<GlobalStringKey, IGuiInstanceLoader*> usedProps; // TODO: (enumerable) foreach:reversed on dictionary for (auto prop : From(repr->setters.Keys()).Reverse()) { auto setter = repr->setters[prop]; IGuiInstanceLoader::PropertyInfo propInfo(reprTypeInfo, prop); if (setter->binding == GlobalStringKey::_Set) { auto setTarget = dynamic_cast<GuiAttSetterRepr*>(setter->values[0].Obj()); if (auto statement = ProcessPropertySet(propInfo, repr, setter, setTarget)) { Workflow_RecordScriptPosition(precompileContext, setTarget->tagPosition, statement); statements->statements.Add(statement); } setTarget->Accept(this); } else if (setter->binding == GlobalStringKey::Empty) { for (auto value : setter->values) { auto info = resolvingResult.propertyResolvings[value.Obj()]; if (info.info->usage == GuiInstancePropertyInfo::Property) { if (info.info->support == GuiInstancePropertyInfo::SupportCollection) { if (auto statement = ProcessPropertyCollection(propInfo, repr, usedProps, setter, info, value)) { Workflow_RecordScriptPosition(precompileContext, value->tagPosition, statement); statements->statements.Add(statement); } } else if (!usedProps.Contains(prop, info.loader)) { if (auto statement = ProcessPropertyOthers(propInfo, repr, usedProps, setter, info, value)) { Workflow_RecordScriptPosition(precompileContext, value->tagPosition, statement); statements->statements.Add(statement); } } } } } } WORKFLOW_ENVIRONMENT_VARIABLE_REMOVE } } void FillCtorArguments(GuiConstructorRepr* repr, IGuiInstanceLoader* loader, const IGuiInstanceLoader::TypeInfo& typeInfo, IGuiInstanceLoader::ArgumentMap& arguments) { WORKFLOW_ENVIRONMENT_VARIABLE_ADD // TODO: (enumerable) foreach on dictionary for (auto [prop, index] : indexed(repr->setters.Keys())) { auto setter = repr->setters.Values()[index]; auto propertyResolving = resolvingResult.propertyResolvings[setter->values[0].Obj()]; if (propertyResolving.info->usage != GuiInstancePropertyInfo::ConstructorArgument) continue; if (setter->binding == GlobalStringKey::Empty) { for (auto value : setter->values) { auto argument = GetArgumentInfo(setter->attPosition, value.Obj()); if (argument.typeInfo && argument.expression) { arguments.Add(prop, argument); } } } else if (auto binder = GetInstanceLoaderManager()->GetInstanceBinder(setter->binding)) { auto value = setter->values[0].Cast<GuiTextRepr>(); if (auto expression = binder->GenerateConstructorArgument(precompileContext, resolvingResult, loader, propertyResolving.propertyInfo, propertyResolving.info, value->text, value->tagPosition, errors)) { Workflow_RecordScriptPosition(precompileContext, value->tagPosition, expression); IGuiInstanceLoader::ArgumentInfo argument; argument.expression = expression; argument.typeInfo = propertyResolving.info->acceptableTypes[0]; argument.attPosition = setter->attPosition; arguments.Add(prop, argument); } } else if (setter->binding != GlobalStringKey::_Set) { errors.Add(GuiResourceError({ resolvingResult.resource }, setter->attPosition, L"[INTERNAL-ERROR] Precompile: The appropriate IGuiInstanceBinder of binding \"-" + setter->binding.ToString() + L"\" cannot be found.")); } } WORKFLOW_ENVIRONMENT_VARIABLE_REMOVE } void Visit(GuiConstructorRepr* repr)override { IGuiInstanceLoader::TypeInfo ctorTypeInfo; if (resolvingResult.context->instance.Obj() == repr) { auto source = FindInstanceLoadingSource(resolvingResult.context, repr); ctorTypeInfo.typeName = source.typeName; auto typeInfo = GetInstanceLoaderManager()->GetTypeInfoForType(source.typeName); ctorTypeInfo.typeInfo = typeInfo; } else { ctorTypeInfo = resolvingResult.typeInfos[repr->instanceName]; } auto ctorLoader = GetInstanceLoaderManager()->GetLoader(ctorTypeInfo.typeName); while (ctorLoader) { if (ctorLoader->CanCreate(ctorTypeInfo)) { break; } ctorLoader = GetInstanceLoaderManager()->GetParentLoader(ctorLoader); } if (resolvingResult.context->instance.Obj() == repr) { resolvingResult.rootLoader = ctorLoader; FillCtorArguments(repr, ctorLoader, ctorTypeInfo, resolvingResult.rootCtorArguments); { auto refInstance = Ptr(new WfReferenceExpression); refInstance->name.value = repr->instanceName.ToString(); auto refThis = Ptr(new WfReferenceExpression); refThis->name.value = L"<this>"; auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refInstance; assign->second = refThis; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; statements->statements.Add(stat); } if (resolvingResult.rootCtorArguments.Count() > 0) { if (auto stat = ctorLoader->InitializeRootInstance(precompileContext, resolvingResult, ctorTypeInfo, repr->instanceName, resolvingResult.rootCtorArguments, errors)) { Workflow_RecordScriptPosition(precompileContext, resolvingResult.context->tagPosition, stat); statements->statements.Add(stat); } } for (auto parameter : resolvingResult.context->parameters) { auto refInstance = Ptr(new WfReferenceExpression); refInstance->name.value = parameter->name.ToString(); auto refThis = Ptr(new WfReferenceExpression); refThis->name.value = L"<this>"; auto refParameter = Ptr(new WfMemberExpression); refParameter->parent = refThis; refParameter->name.value = parameter->name.ToString(); auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = refInstance; assign->second = refParameter; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; statements->statements.Add(stat); Workflow_RecordScriptPosition(precompileContext, parameter->tagPosition, (Ptr<WfStatement>)stat); } } else { IGuiInstanceLoader::ArgumentMap arguments; FillCtorArguments(repr, ctorLoader, ctorTypeInfo, arguments); vint errorCount = errors.Count(); if (auto ctorStats = ctorLoader->CreateInstance(precompileContext, resolvingResult, ctorTypeInfo, repr->instanceName, arguments, repr->tagPosition, errors)) { Workflow_RecordScriptPosition(precompileContext, resolvingResult.context->tagPosition, ctorStats); statements->statements.Add(ctorStats); auto instanceName = repr->instanceName.ToString(); auto generatedNamePrefix = WString::Unmanaged(L"<precompile>"); if (instanceName.Length() < generatedNamePrefix.Length() || instanceName.Left(generatedNamePrefix.Length()) != generatedNamePrefix) { auto refName = Ptr(new WfStringExpression); refName->value.value = instanceName; auto refInstance = Ptr(new WfReferenceExpression); refInstance->name.value = instanceName; auto refThis = Ptr(new WfReferenceExpression); refThis->name.value = L"<this>"; auto refSetNamedObject = Ptr(new WfMemberExpression); refSetNamedObject->parent = refThis; refSetNamedObject->name.value = L"SetNamedObject"; auto refCall = Ptr(new WfCallExpression); refCall->function = refSetNamedObject; refCall->arguments.Add(refName); refCall->arguments.Add(refInstance); auto statSetNamedObject = Ptr(new WfExpressionStatement); statSetNamedObject->expression = refCall; if (auto block = ctorStats.Cast<WfBlockStatement>()) { block->statements.Add(statSetNamedObject); } else { statements->statements.Add(statSetNamedObject); } } } else if (errorCount == errors.Count()) { errors.Add(GuiResourceError({ resolvingResult.resource }, repr->tagPosition, L"[INTERNAL-ERROR] Precompile: Something is wrong when creating an instance of type \"" + ctorTypeInfo.typeName.ToString() + L"\".")); } } Visit((GuiAttSetterRepr*)repr); } }; void Workflow_GenerateCreating(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, Ptr<WfBlockStatement> statements, GuiResourceError::List& errors) { WorkflowGenerateCreatingVisitor visitor(precompileContext, resolvingResult, statements, errors); resolvingResult.context->instance->Accept(&visitor); } } } /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWINSTALLBINDINGS.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace workflow; using namespace workflow::analyzer; using namespace reflection::description; using namespace collections; using namespace controls; using namespace compositions; /*********************************************************************** Workflow_InstallBindProperty ***********************************************************************/ Ptr<workflow::WfExpression> Workflow_GetUriProperty(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> propInfo, const WString& protocol, const WString& path, GuiResourceTextPos attPosition, GuiResourceError::List& errors) { Ptr<WfExpression> resourceExpr; { auto refResolver = Ptr(new WfReferenceExpression); refResolver->name.value = L"<this>"; auto member = Ptr(new WfMemberExpression); member->parent = refResolver; member->name.value = L"ResolveResource"; auto valueProtocol = Ptr(new WfStringExpression); valueProtocol->value.value = protocol; auto valuePath = Ptr(new WfStringExpression); valuePath->value.value = path; auto valueBool = Ptr(new WfLiteralExpression); valueBool->value = WfLiteralValue::True; auto call = Ptr(new WfCallExpression); call->function = member; call->arguments.Add(valueProtocol); call->arguments.Add(valuePath); call->arguments.Add(valueBool); resourceExpr = call; } auto td = propInfo->acceptableTypes[0]->GetTypeDescriptor(); Ptr<ITypeInfo> convertedType; { if (td->GetSerializableType()) { convertedType = TypeInfoRetriver<Ptr<GuiTextData>>::CreateTypeInfo(); } else if (td == description::GetTypeDescriptor<INativeImage>() || td == description::GetTypeDescriptor<GuiImageData>()) { convertedType = TypeInfoRetriver<Ptr<GuiImageData>>::CreateTypeInfo(); } else { auto elementType = Ptr(new TypeDescriptorTypeInfo(td, TypeInfoHint::Normal)); auto pointerType = Ptr(new SharedPtrTypeInfo(elementType)); convertedType = pointerType; } } Ptr<WfExpression> convertedExpr; { auto cast = Ptr(new WfTypeCastingExpression); cast->expression = resourceExpr; cast->type = GetTypeFromTypeInfo(convertedType.Obj()); cast->strategy = WfTypeCastingStrategy::Strong; convertedExpr = cast; } Ptr<WfExpression> evalExpr; { if (td->GetSerializableType()) { auto member = Ptr(new WfMemberExpression); member->parent = convertedExpr; member->name.value = L"Text"; auto elementType = Ptr(new TypeDescriptorTypeInfo(td, TypeInfoHint::Normal)); auto cast = Ptr(new WfTypeCastingExpression); cast->expression = member; cast->type = GetTypeFromTypeInfo(elementType.Obj()); cast->strategy = WfTypeCastingStrategy::Strong; evalExpr = cast; } else if (td == description::GetTypeDescriptor<INativeImage>()) { auto member = Ptr(new WfMemberExpression); member->parent = convertedExpr; member->name.value = L"Image"; evalExpr = member; } else { evalExpr = convertedExpr; } } return evalExpr; } Ptr<workflow::WfStatement> Workflow_InstallUriProperty(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> propInfo, const WString& protocol, const WString& path, GuiResourceTextPos attPosition, GuiResourceError::List& errors) { auto evalExpr = Workflow_GetUriProperty(precompileContext, resolvingResult, loader, prop, propInfo, protocol, path, attPosition, errors); IGuiInstanceLoader::ArgumentMap arguments; { IGuiInstanceLoader::ArgumentInfo argumentInfo; argumentInfo.typeInfo = propInfo->acceptableTypes[0]; argumentInfo.expression = evalExpr; argumentInfo.attPosition = attPosition; arguments.Add(prop.propertyName, argumentInfo); } return loader->AssignParameters(precompileContext, resolvingResult, prop.typeInfo, variableName, arguments, attPosition, errors); } /*********************************************************************** Workflow_InstallBindProperty ***********************************************************************/ Ptr<workflow::WfStatement> Workflow_InstallBindProperty(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, Ptr<workflow::WfExpression> bindExpression) { auto subBlock = Ptr(new WfBlockStatement); { auto var = Ptr(new WfVariableDeclaration); var->name.value = L"<created-subscription>"; var->expression = bindExpression; auto stat = Ptr(new WfVariableStatement); stat->variable = var; subBlock->statements.Add(stat); } { auto callback = Ptr(new WfFunctionDeclaration); callback->functionKind = WfFunctionKind::Normal; callback->anonymity = WfFunctionAnonymity::Anonymous; callback->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<void>::CreateTypeInfo().Obj());; { auto arg = Ptr(new WfFunctionArgument); arg->name.value = L"<value>"; arg->type = GetTypeFromTypeInfo(TypeInfoRetriver<Value>::CreateTypeInfo().Obj()); callback->arguments.Add(arg); } auto callbackBlock = Ptr(new WfBlockStatement); callback->statement = callbackBlock; { auto refSubscribee = Ptr(new WfReferenceExpression); refSubscribee->name.value = variableName.ToString(); auto member = Ptr(new WfMemberExpression); member->parent = refSubscribee; member->name.value = propertyInfo->GetName(); auto var = Ptr(new WfVariableDeclaration); var->name.value = L"<old>"; var->expression = member; auto stat = Ptr(new WfVariableStatement); stat->variable = var; callbackBlock->statements.Add(stat); } { ITypeInfo* propertyType = propertyInfo->GetReturn(); if (propertyInfo->GetSetter() && propertyInfo->GetSetter()->GetParameterCount() == 1) { propertyType = propertyInfo->GetSetter()->GetParameter(0)->GetType(); } auto refValue = Ptr(new WfReferenceExpression); refValue->name.value = L"<value>"; auto cast = Ptr(new WfTypeCastingExpression); cast->strategy = WfTypeCastingStrategy::Strong; cast->expression = refValue; cast->type = GetTypeFromTypeInfo(propertyType); auto var = Ptr(new WfVariableDeclaration); var->name.value = L"<new>"; var->expression = cast; auto stat = Ptr(new WfVariableStatement); stat->variable = var; callbackBlock->statements.Add(stat); } { auto refOld = Ptr(new WfReferenceExpression); refOld->name.value = L"<old>"; auto refNew = Ptr(new WfReferenceExpression); refNew->name.value = L"<new>"; auto compare = Ptr(new WfBinaryExpression); compare->op = WfBinaryOperator::EQ; compare->first = refOld; compare->second = refNew; auto ifStat = Ptr(new WfIfStatement); ifStat->expression = compare; callbackBlock->statements.Add(ifStat); auto ifBlock = Ptr(new WfBlockStatement); ifStat->trueBranch = ifBlock; auto returnStat = Ptr(new WfReturnStatement); ifBlock->statements.Add(returnStat); } { auto refSubscribee = Ptr(new WfReferenceExpression); refSubscribee->name.value = variableName.ToString(); auto member = Ptr(new WfMemberExpression); member->parent = refSubscribee; member->name.value = propertyInfo->GetName(); auto refNew = Ptr(new WfReferenceExpression); refNew->name.value = L"<new>"; auto assign = Ptr(new WfBinaryExpression); assign->op = WfBinaryOperator::Assign; assign->first = member; assign->second = refNew; auto stat = Ptr(new WfExpressionStatement); stat->expression = assign; callbackBlock->statements.Add(stat); } auto funcExpr = Ptr(new WfFunctionExpression); funcExpr->function = callback; auto refBind = Ptr(new WfReferenceExpression); refBind->name.value = L"<created-subscription>"; auto refEvent = Ptr(new WfMemberExpression); refEvent->parent = refBind; refEvent->name.value = L"ValueChanged"; auto attachExpr = Ptr(new WfAttachEventExpression); attachExpr->event = refEvent; attachExpr->function = funcExpr; auto stat = Ptr(new WfExpressionStatement); stat->expression = attachExpr; subBlock->statements.Add(stat); } { auto refThis = Ptr(new WfReferenceExpression); refThis->name.value = L"<this>"; auto member = Ptr(new WfMemberExpression); member->parent = refThis; member->name.value = L"AddSubscription"; auto refBind = Ptr(new WfReferenceExpression); refBind->name.value = L"<created-subscription>"; auto call = Ptr(new WfCallExpression); call->function = member; call->arguments.Add(refBind); auto stat = Ptr(new WfExpressionStatement); stat->expression = call; subBlock->statements.Add(stat); } return subBlock; } /*********************************************************************** Workflow_InstallEvalProperty ***********************************************************************/ Ptr<workflow::WfStatement> Workflow_InstallEvalProperty(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> propInfo, Ptr<workflow::WfExpression> evalExpression, GuiResourceTextPos attPosition, GuiResourceError::List& errors) { IGuiInstanceLoader::ArgumentMap arguments; { IGuiInstanceLoader::ArgumentInfo argumentInfo; argumentInfo.typeInfo = propInfo->acceptableTypes[0]; argumentInfo.expression = evalExpression; argumentInfo.attPosition = attPosition; arguments.Add(prop.propertyName, argumentInfo); } return loader->AssignParameters(precompileContext, resolvingResult, prop.typeInfo, variableName, arguments, attPosition, errors); } /*********************************************************************** Workflow_InstallEvent ***********************************************************************/ Ptr<workflow::WfStatement> Workflow_InstallEvent(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IEventInfo* eventInfo, const WString& handlerName) { vint count = eventInfo->GetHandlerType()->GetElementType()->GetGenericArgumentCount() - 1; auto subBlock = Ptr(new WfBlockStatement); { auto var = Ptr(new WfReferenceExpression); var->name.value = variableName.ToString(); auto member = Ptr(new WfMemberExpression); member->parent = var; member->name.value = eventInfo->GetName(); auto refThis = Ptr(new WfReferenceExpression); refThis->name.value = L"<this>"; auto handler = Ptr(new WfMemberExpression); handler->parent = refThis; handler->name.value = handlerName; auto call = Ptr(new WfCallExpression); call->function = handler; for (vint i = 0; i < count; i++) { auto argument = Ptr(new WfOrderedNameExpression); argument->name.value = L"$" + itow(i + 1); call->arguments.Add(argument); } auto eventHandler = Ptr(new WfOrderedLambdaExpression); eventHandler->body = call; auto attachEvent = Ptr(new WfAttachEventExpression); attachEvent->event = member; attachEvent->function = eventHandler; auto stat = Ptr(new WfExpressionStatement); stat->expression = attachEvent; subBlock->statements.Add(stat); } return subBlock; } /*********************************************************************** Workflow_GenerateEventHandler ***********************************************************************/ Ptr<workflow::WfFunctionDeclaration> Workflow_GenerateEventHandler(GuiResourcePrecompileContext& precompileContext, description::IEventInfo* eventInfo) { auto func = Ptr(new WfFunctionDeclaration); func->functionKind = WfFunctionKind::Normal; func->anonymity = WfFunctionAnonymity::Anonymous; func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<void>::CreateTypeInfo().Obj()); vint count = eventInfo->GetHandlerType()->GetElementType()->GetGenericArgumentCount() - 1; bool standardName = false; if (count == 2) { auto senderType = eventInfo->GetHandlerType()->GetElementType()->GetGenericArgument(1)->GetTypeDescriptor(); auto argumentType = eventInfo->GetHandlerType()->GetElementType()->GetGenericArgument(2)->GetTypeDescriptor(); if (senderType == GetTypeDescriptor<GuiGraphicsComposition>()) { auto expectedType = GetTypeDescriptor<GuiEventArgs>(); List<ITypeDescriptor*> types; types.Add(argumentType); // TODO: (enumerable) foreach for (vint i = 0; i < types.Count(); i++) { auto type = types[i]; if (type == expectedType) { standardName = true; break; } vint baseCount = type->GetBaseTypeDescriptorCount(); for (vint j = 0; j < baseCount; j++) { auto baseType = type->GetBaseTypeDescriptor(j); if (!types.Contains(baseType)) { types.Add(baseType); } } } } } if (standardName) { { auto arg = Ptr(new WfFunctionArgument); arg->name.value = L"sender"; arg->type = GetTypeFromTypeInfo(eventInfo->GetHandlerType()->GetElementType()->GetGenericArgument(1)); func->arguments.Add(arg); } { auto arg = Ptr(new WfFunctionArgument); arg->name.value = L"arguments"; arg->type = GetTypeFromTypeInfo(eventInfo->GetHandlerType()->GetElementType()->GetGenericArgument(2)); func->arguments.Add(arg); } } else { for (vint i = 0; i < count; i++) { auto arg = Ptr(new WfFunctionArgument); arg->name.value = L"arg" + itow(i + 1); arg->type = GetTypeFromTypeInfo(eventInfo->GetHandlerType()->GetElementType()->GetGenericArgument(i + 1)); func->arguments.Add(arg); } } return func; } /*********************************************************************** Workflow_InstallEvalEvent ***********************************************************************/ Ptr<workflow::WfStatement> Workflow_InstallEvalEvent(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IEventInfo* eventInfo, Ptr<workflow::WfStatement> evalStatement) { auto func = Workflow_GenerateEventHandler(precompileContext, eventInfo); if (evalStatement.Cast<WfBlockStatement>()) { func->statement = evalStatement; } else if (evalStatement.Cast<WfCoProviderStatement>()) { func->statement = evalStatement; } else { auto funcBlock = Ptr(new WfBlockStatement); funcBlock->statements.Add(evalStatement); func->statement = funcBlock; } auto subBlock = Ptr(new WfBlockStatement); { auto eventHandlerLambda = Ptr(new WfFunctionExpression); eventHandlerLambda->function = func; auto eventHandler = Ptr(new WfVariableDeclaration); eventHandler->name.value = L"<event-handler>"; eventHandler->expression = eventHandlerLambda; auto stat = Ptr(new WfVariableStatement); stat->variable = eventHandler; subBlock->statements.Add(stat); } { auto var = Ptr(new WfReferenceExpression); var->name.value = variableName.ToString(); auto member = Ptr(new WfMemberExpression); member->parent = var; member->name.value = eventInfo->GetName(); auto eventHandler = Ptr(new WfReferenceExpression); eventHandler->name.value = L"<event-handler>"; auto attachEvent = Ptr(new WfAttachEventExpression); attachEvent->event = member; attachEvent->function = eventHandler; auto stat = Ptr(new WfExpressionStatement); stat->expression = attachEvent; subBlock->statements.Add(stat); } return subBlock; } } } /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWMODULE.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace workflow; using namespace workflow::analyzer; using namespace reflection::description; using namespace collections; /*********************************************************************** Workflow_CreateModuleWithUsings ***********************************************************************/ Ptr<workflow::WfModule> Workflow_CreateModuleWithUsings(Ptr<GuiInstanceContext> context, const WString& moduleName) { auto module = Ptr(new WfModule); module->moduleType = WfModuleType::Module; module->name.value = moduleName; vint index = context->namespaces.Keys().IndexOf(GlobalStringKey()); if (index != -1) { auto nss = context->namespaces.Values()[index]; for (auto ns : nss->namespaces) { auto path = Ptr(new WfModuleUsingPath); module->paths.Add(path); auto pathCode = ns->prefix + L"*" + ns->postfix; auto reading = pathCode.Buffer(); while (reading) { auto delimiter = wcsstr(reading, L"::"); auto begin = reading; auto end = delimiter ? delimiter : begin + wcslen(reading); auto wildcard = wcschr(reading, L'*'); if (wildcard >= end) { wildcard = nullptr; } auto item = Ptr(new WfModuleUsingItem); path->items.Add(item); if (wildcard) { if (begin < wildcard) { auto fragment = Ptr(new WfModuleUsingNameFragment); item->fragments.Add(fragment); fragment->name.value = WString::CopyFrom(begin, vint(wildcard - begin)); } { auto fragment = Ptr(new WfModuleUsingWildCardFragment); item->fragments.Add(fragment); } if (wildcard + 1 < end) { auto fragment = Ptr(new WfModuleUsingNameFragment); item->fragments.Add(fragment); fragment->name.value = WString::CopyFrom(wildcard + 1, vint(end - wildcard - 1)); } } else if (begin < end) { auto fragment = Ptr(new WfModuleUsingNameFragment); item->fragments.Add(fragment); fragment->name.value = WString::CopyFrom(begin, vint(end - begin)); } if (delimiter) { reading = delimiter + 2; } else { reading = nullptr; } } } } return module; } /*********************************************************************** Workflow_InstallWithClass ***********************************************************************/ WString Workflow_InstallWithClass(const WString& className, Ptr<workflow::WfModule> module, Ptr<workflow::WfDeclaration> decl) { auto decls = &module->declarations; auto reading = className.Buffer(); while (true) { auto delimiter = wcsstr(reading, L"::"); if (delimiter) { auto ns = Ptr(new WfNamespaceDeclaration); ns->name.value = WString::CopyFrom(reading, delimiter - reading); decls->Add(ns); decls = &ns->declarations; } else { decls->Add(decl); return reading; } reading = delimiter + 2; } } /*********************************************************************** Workflow_InstallClass ***********************************************************************/ Ptr<workflow::WfClassDeclaration> Workflow_InstallClass(const WString& className, Ptr<workflow::WfModule> module) { auto ctorClass = Ptr(new WfClassDeclaration); ctorClass->kind = WfClassKind::Class; ctorClass->constructorType = WfConstructorType::Undefined; ctorClass->name.value = Workflow_InstallWithClass(className, module, ctorClass); return ctorClass; } /*********************************************************************** Workflow_InstallCtorClass ***********************************************************************/ Ptr<workflow::WfBlockStatement> Workflow_InstallCtorClass(types::ResolvingResult& resolvingResult, Ptr<workflow::WfModule> module) { auto ctorClass = Workflow_InstallClass(resolvingResult.context->className + L"Constructor", module); Workflow_CreateVariablesForReferenceValues(ctorClass, resolvingResult); auto thisParam = Ptr(new WfFunctionArgument); thisParam->name.value = L"<this>"; thisParam->type = GetTypeFromTypeInfo(resolvingResult.rootTypeInfo.typeInfo.Obj()); auto block = Ptr(new WfBlockStatement); auto func = Ptr(new WfFunctionDeclaration); func->functionKind = WfFunctionKind::Normal; func->anonymity = WfFunctionAnonymity::Named; func->arguments.Add(thisParam); func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<void>::CreateTypeInfo().Obj()); func->statement = block; { List<WString> fragments; SplitTypeName(resolvingResult.context->className, fragments); func->name.value = L"<" + From(fragments).Aggregate([](const WString& a, const WString& b) {return a + L"-" + b; }) + L">Initialize"; } { auto att = Ptr(new WfAttribute); att->category.value = L"cpp"; att->name.value = L"Protected"; func->attributes.Add(att); } ctorClass->declarations.Add(func); return block; } /*********************************************************************** Variable ***********************************************************************/ void Workflow_CreatePointerVariable(Ptr<workflow::WfClassDeclaration> ctorClass, GlobalStringKey name, description::ITypeInfo* typeInfo) { auto var = Ptr(new WfVariableDeclaration); var->name.value = name.ToString(); var->type = GetTypeFromTypeInfo(typeInfo); { auto att = Ptr(new WfAttribute); att->category.value = L"cpp"; att->name.value = L"Protected"; var->attributes.Add(att); } if (!var->type) { if (auto ctors = typeInfo->GetTypeDescriptor()->GetConstructorGroup()) { if (ctors->GetMethodCount() > 0) { auto ctor = ctors->GetMethod(0); var->type = GetTypeFromTypeInfo(ctor->GetReturn()); } } } var->expression = CreateDefaultValue(typeInfo); ctorClass->declarations.Add(var); } void Workflow_CreateVariablesForReferenceValues(Ptr<workflow::WfClassDeclaration> ctorClass, types::ResolvingResult& resolvingResult) { const auto& typeInfos = resolvingResult.typeInfos; // TODO: (enumerable) foreach on dictionary for (vint i = 0; i < typeInfos.Count(); i++) { auto key = typeInfos.Keys()[i]; auto value = typeInfos.Values()[i].typeInfo.Obj(); Workflow_CreatePointerVariable(ctorClass, key, value); } } } } /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWPARSER.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace stream; using namespace reflection::description; using namespace workflow; using namespace workflow::analyzer; /*********************************************************************** Parser ***********************************************************************/ template<typename T> Ptr<T> Workflow_Parse(GuiResourcePrecompileContext& precompileContext, const WString& parserName, GuiResourceLocation location, const WString& code, GuiResourceTextPos position, collections::List<GuiResourceError>& errors, glr::ParsingTextPos availableAfter) { vint errorCount = errors.Count(); auto parser = GetParserManager()->GetParser<T>(parserName); auto result = parser->Parse(location, code, position, errors); if (availableAfter.row != 0 || availableAfter.column != 0) { // TODO: (enumerable) Linq:Skip for (vint i = errorCount; i < errors.Count(); i++) { auto& error = errors[i]; if (error.position.row > position.row) { error.position.row -= availableAfter.row; } else if (error.position.row == position.row && error.position.column >= position.column) { error.position.column -= availableAfter.column; } } } if (result) { Workflow_RecordScriptPosition(precompileContext, position, result, availableAfter); } return result; } Ptr<workflow::WfType> Workflow_ParseType(GuiResourcePrecompileContext& precompileContext, GuiResourceLocation location, const WString& code, GuiResourceTextPos position, collections::List<GuiResourceError>& errors, glr::ParsingTextPos availableAfter) { return Workflow_Parse<WfType>(precompileContext, L"WORKFLOW-TYPE", location, code, position, errors, availableAfter); } Ptr<workflow::WfExpression> Workflow_ParseExpression(GuiResourcePrecompileContext& precompileContext, GuiResourceLocation location, const WString& code, GuiResourceTextPos position, collections::List<GuiResourceError>& errors, glr::ParsingTextPos availableAfter) { return Workflow_Parse<WfExpression>(precompileContext, L"WORKFLOW-EXPRESSION", location, code, position, errors, availableAfter); } Ptr<workflow::WfStatement> Workflow_ParseStatement(GuiResourcePrecompileContext& precompileContext, GuiResourceLocation location, const WString& code, GuiResourceTextPos position, collections::List<GuiResourceError>& errors, glr::ParsingTextPos availableAfter) { return Workflow_Parse<WfStatement>(precompileContext, L"WORKFLOW-STATEMENT", location, code, position, errors, availableAfter); } Ptr<workflow::WfStatement> Workflow_ParseCoProviderStatement(GuiResourcePrecompileContext& precompileContext, GuiResourceLocation location, const WString& code, GuiResourceTextPos position, collections::List<GuiResourceError>& errors, glr::ParsingTextPos availableAfter) { return Workflow_Parse<WfStatement>(precompileContext, L"WORKFLOW-COPROVIDER-STATEMENT", location, code, position, errors, availableAfter); } Ptr<workflow::WfModule> Workflow_ParseModule(GuiResourcePrecompileContext& precompileContext, GuiResourceLocation location, const WString& code, GuiResourceTextPos position, collections::List<GuiResourceError>& errors, glr::ParsingTextPos availableAfter) { return Workflow_Parse<WfModule>(precompileContext, L"WORKFLOW-MODULE", location, code, position, errors, availableAfter); } /*********************************************************************** Workflow_ModuleToString ***********************************************************************/ WString Workflow_ModuleToString(Ptr<workflow::WfModule> module) { return GenerateToStream([&](StreamWriter& writer) { WfPrint(module, L"", writer); }); } /*********************************************************************** Converter ***********************************************************************/ Ptr<workflow::WfExpression> Workflow_ParseTextValue(GuiResourcePrecompileContext& precompileContext, description::ITypeDescriptor* typeDescriptor, GuiResourceLocation location, const WString& textValue, GuiResourceTextPos position, collections::List<GuiResourceError>& errors) { if (typeDescriptor == description::GetTypeDescriptor<WString>()) { auto valueExpr = Ptr(new WfStringExpression); valueExpr->value.value = textValue; return valueExpr; } else if (typeDescriptor == description::GetTypeDescriptor<bool>()) { bool value = false; if (!TypedValueSerializerProvider<bool>::Deserialize(textValue, value)) return nullptr; auto valueExpr = Ptr(new WfLiteralExpression); valueExpr->value = value ? WfLiteralValue::True : WfLiteralValue::False; return valueExpr; } #define INTEGER_BRANCH(TYPE) \ else if (typeDescriptor == description::GetTypeDescriptor<TYPE>()) \ { \ auto valueExpr = Ptr(new WfIntegerExpression); \ valueExpr->value.value = textValue; \ auto type = Ptr(new TypeDescriptorTypeInfo(typeDescriptor, TypeInfoHint::Normal)); \ auto infer = Ptr(new WfInferExpression); \ infer->type = GetTypeFromTypeInfo(type.Obj()); \ infer->expression = valueExpr; \ return infer; \ } INTEGER_BRANCH(vint8_t) INTEGER_BRANCH(vint16_t) INTEGER_BRANCH(vint32_t) INTEGER_BRANCH(vint64_t) INTEGER_BRANCH(vuint8_t) INTEGER_BRANCH(vuint16_t) INTEGER_BRANCH(vuint32_t) INTEGER_BRANCH(vuint64_t) #undef INTEGER_BRANCH #define FLOATING_BRANCH(TYPE) \ else if (typeDescriptor == description::GetTypeDescriptor<TYPE>()) \ { \ auto valueExpr = Ptr(new WfFloatingExpression); \ valueExpr->value.value = textValue; \ auto type = Ptr(new TypeDescriptorTypeInfo(typeDescriptor, TypeInfoHint::Normal)); \ auto infer = Ptr(new WfInferExpression); \ infer->type = GetTypeFromTypeInfo(type.Obj()); \ infer->expression = valueExpr; \ return infer; \ } FLOATING_BRANCH(float) FLOATING_BRANCH(double) #undef FLOATING_BRANCH else if (typeDescriptor->GetSerializableType()) { auto str = Ptr(new WfStringExpression); str->value.value = textValue; auto type = Ptr(new TypeDescriptorTypeInfo(typeDescriptor, TypeInfoHint::Normal)); auto cast = Ptr(new WfTypeCastingExpression); cast->type = GetTypeFromTypeInfo(type.Obj()); cast->strategy = WfTypeCastingStrategy::Strong; cast->expression = str; return cast; } else if (typeDescriptor->GetTypeDescriptorFlags() == TypeDescriptorFlags::Struct) { if (auto valueExpr = Workflow_ParseExpression(precompileContext, location, L"{" + textValue + L"}", position, errors, { 0,1 })) // { { auto type = Ptr(new TypeDescriptorTypeInfo(typeDescriptor, TypeInfoHint::Normal)); auto infer = Ptr(new WfInferExpression); infer->type = GetTypeFromTypeInfo(type.Obj()); infer->expression = valueExpr; return infer; } return nullptr; } else if ((typeDescriptor->GetTypeDescriptorFlags() & TypeDescriptorFlags::EnumType) != TypeDescriptorFlags::Undefined) { if (auto valueExpr = Workflow_ParseExpression(precompileContext, location, L"(" + textValue + L")", position, errors, { 0,1 })) // { { auto type = Ptr(new TypeDescriptorTypeInfo(typeDescriptor, TypeInfoHint::Normal)); auto infer = Ptr(new WfInferExpression); infer->type = GetTypeFromTypeInfo(type.Obj()); infer->expression = valueExpr; return infer; } return nullptr; } else { CHECK_FAIL(L"vl::presentation::Workflow_ParseTextValue(ITypeDescriptor*, const WString&, GuiResourceError::List&)#This is not a value type."); } } } } /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWSCRIPTPOSITION.CPP ***********************************************************************/ namespace vl { namespace presentation { using namespace collections; using namespace workflow; /*********************************************************************** WorkflowScriptPositionVisitor ***********************************************************************/ class WorkflowScriptPositionVisitor : public workflow::traverse_visitor::AstVisitor { public: GuiResourcePrecompileContext& context; GuiResourceTextPos position; glr::ParsingTextPos availableAfter; Ptr<types::ScriptPosition> sp; WorkflowScriptPositionVisitor(GuiResourcePrecompileContext& _context, GuiResourceTextPos _position, glr::ParsingTextPos _availableAfter) :context(_context) , position(_position) , availableAfter(_availableAfter) { vint index = context.additionalProperties.Keys().IndexOf(nullptr); if (index == -1) { context.additionalProperties.Add(nullptr, Ptr(new types::ScriptPosition)); } sp = context.additionalProperties[nullptr].Cast<types::ScriptPosition>(); } void Traverse(glr::ParsingAstBase* node) override { if (!sp->nodePositions.Keys().Contains(node)) { auto pos = node->codeRange.start; if (pos.row == availableAfter.row && pos.column > availableAfter.column) { pos.column -= availableAfter.column; } else if (pos.row > availableAfter.row) { pos.row -= availableAfter.row; } types::ScriptPositionRecord record; record.position = position; record.availableAfter = availableAfter; if (pos.row < 0 || pos.column < 0) { record.computedPosition = position; } else if (pos.row == 0) { record.computedPosition = { position.originalLocation,{position.row,position.column + pos.column} }; } else { record.computedPosition = { position.originalLocation,{ position.row + pos.row,pos.column } }; } sp->nodePositions.Add(Ptr(node), record); } } }; /*********************************************************************** WorkflowCompiler_ScriptPosition ***********************************************************************/ void Workflow_RecordScriptPosition(GuiResourcePrecompileContext& context, GuiResourceTextPos position, Ptr<workflow::WfType> node, glr::ParsingTextPos availableAfter) { WorkflowScriptPositionVisitor(context, position, availableAfter).InspectInto(node.Obj()); } void Workflow_RecordScriptPosition(GuiResourcePrecompileContext& context, GuiResourceTextPos position, Ptr<workflow::WfExpression> node, glr::ParsingTextPos availableAfter) { WorkflowScriptPositionVisitor(context, position, availableAfter).InspectInto(node.Obj()); } void Workflow_RecordScriptPosition(GuiResourcePrecompileContext& context, GuiResourceTextPos position, Ptr<workflow::WfStatement> node, glr::ParsingTextPos availableAfter) { WorkflowScriptPositionVisitor(context, position, availableAfter).InspectInto(node.Obj()); } void Workflow_RecordScriptPosition(GuiResourcePrecompileContext& context, GuiResourceTextPos position, Ptr<workflow::WfDeclaration> node, glr::ParsingTextPos availableAfter) { WorkflowScriptPositionVisitor(context, position, availableAfter).InspectInto(node.Obj()); } void Workflow_RecordScriptPosition(GuiResourcePrecompileContext& context, GuiResourceTextPos position, Ptr<workflow::WfModule> node, glr::ParsingTextPos availableAfter) { WorkflowScriptPositionVisitor(context, position, availableAfter).InspectInto(node.Obj()); } Ptr<types::ScriptPosition> Workflow_GetScriptPosition(GuiResourcePrecompileContext& context) { vint index = context.additionalProperties.Keys().IndexOf(nullptr); if (index == -1) return nullptr; return context.additionalProperties.Values()[index].Cast<types::ScriptPosition>(); } void Workflow_ClearScriptPosition(GuiResourcePrecompileContext& context) { context.additionalProperties.Remove(nullptr); } } }