Files
GacUI/Import/GacUICompiler.cpp
T
2025-09-05 23:56:20 -07:00

16669 lines
608 KiB
C++

/***********************************************************************
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<GuiResourceError>& errors,
const filesystem::FilePath& errorPath)
{
List<WString> output;
GuiResourceError::SortAndLog(errors, output);
return File(errorPath).WriteAllLines(output, true, BomEncoder::Utf8);
}
Ptr<GuiResourceFolder> PrecompileResource(
Ptr<GuiResource> resource,
GuiResourceCpuArchitecture targetCpuArchitecture,
IGuiResourcePrecompileCallback* callback,
collections::List<GuiResourceError>& errors)
{
auto precompiledFolder = resource->Precompile(targetCpuArchitecture, callback, errors);
return precompiledFolder;
}
Ptr<GuiInstanceCompiledWorkflow> WriteWorkflowScript(
Ptr<GuiResourceFolder> precompiledFolder,
const WString& assemblyResourcePath,
const filesystem::FilePath& workflowPath)
{
if (precompiledFolder)
{
if (auto compiled = precompiledFolder->GetValueByPath(assemblyResourcePath).Cast<GuiInstanceCompiledWorkflow>())
{
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<workflow::cppcodegen::WfCppOutput> WriteCppCodesToFile(
Ptr<GuiResource> resource,
Ptr<GuiInstanceCompiledWorkflow> compiled,
Ptr<workflow::cppcodegen::WfCppInput> cppInput,
const filesystem::FilePath& cppFolder,
collections::List<GuiResourceError>& 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<GuiResource> resource,
bool compress,
bool includeAssemblyInResource,
Nullable<filesystem::FilePath> resourceOutput,
Nullable<filesystem::FilePath> 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<GuiInstanceCompiledWorkflow>())
{
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<GuiResource> resource,
Ptr<workflow::cppcodegen::WfCppInput> cppInput,
Ptr<workflow::cppcodegen::WfCppOutput> 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<GuiResourceError> 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> GuiInstanceGradientAnimation::LoadFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlDocument> 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<XmlCData>())
{
animation->interpolation = cdata->content.value;
animation->interpolationPosition = { { resource },cdata->codeRange.start };
animation->interpolationPosition.column += 9; // <![CDATA[
}
else
{
errors.Add({
{ { resource },interpolationElement->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<XmlCData>())
{
target.interpolation = cdata->content.value;
target.interpolationPosition = { { resource },cdata->codeRange.start };
target.interpolationPosition.column += 9; // <![CDATA[
}
else
{
errors.Add({
{ { resource },interpolationElement->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<glr::xml::XmlElement> 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<vint8_t>()) return true;
if (td == description::GetTypeDescriptor<vint16_t>()) return true;
if (td == description::GetTypeDescriptor<vint32_t>()) return true;
if (td == description::GetTypeDescriptor<vint64_t>()) return true;
if (td == description::GetTypeDescriptor<vuint8_t>()) return true;
if (td == description::GetTypeDescriptor<vuint16_t>()) return true;
if (td == description::GetTypeDescriptor<vuint32_t>()) return true;
if (td == description::GetTypeDescriptor<vuint64_t>()) return true;
if (td == description::GetTypeDescriptor<float>()) return true;
if (td == description::GetTypeDescriptor<double>()) 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<WfExpression> 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<Color>())
{
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<workflow::WfExpression> GuiInstanceGradientAnimation::InitStruct(description::IPropertyInfo* propInfo, const WString& prefix, collections::SortedList<WString>& 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"<ani>" + name;
return ref;
}
else
{
List<ITypeDescriptor*> 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<workflow::WfModule> 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 : <TYPE> = <DEFAULT> {}
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 : <TYPE> = <DEFAULT> {}
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 : <TYPE> = <DEFAULT> {}
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 <ani-int> : (func(double):double) = <VALUE> {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"<ani-int>" + name;
var->type = GetTypeFromTypeInfo(TypeInfoRetriver<Func<double(double)>>::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<IPropertyInfo*> props;
List<Ptr<WfExpression>> 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<WfExpression> 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(<ani>begin : <TYPE>, <ani>end : <TYPE>, <ani>current : <TYPE>) : 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"<ani>begin";
argument->type = GetTypeFromTypeInfo(typeInfo.Obj());
func->arguments.Add(argument);
}
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<ani>end";
argument->type = GetTypeFromTypeInfo(typeInfo.Obj());
func->arguments.Add(argument);
}
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<ani>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"<ani>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<double>::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<double>::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<Math>());
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"<ani>begin", L"<ani>end", L"<ani>ref");
createVariable(L"<ani>current", L"<ani>end", L"<ani>cur");
{
auto refRef = Ptr(new WfReferenceExpression);
refRef->name.value = L"<ani>ref";
auto refEpsilon = Ptr(new WfFloatingExpression);
refEpsilon->value.value = L"0.000001";
auto refMaxEpsilon = Ptr(new WfChildExpression);
refMaxEpsilon->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<Math>());
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"<ani>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<Math>());
refMax->name.value = L"Max";
auto refScale = Ptr(new WfReferenceExpression);
refScale->name.value = L"<ani>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"<ani>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"<ani>scale";
auto refMin = Ptr(new WfChildExpression);
refMin->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<Math>());
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(<ani>begin : <TYPE>, <ani>end : <TYPE>, <ani>current : <TYPE>, <ani>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"<ani>begin";
argument->type = GetTypeFromTypeInfo(typeInfo.Obj());
func->arguments.Add(argument);
}
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<ani>end";
argument->type = GetTypeFromTypeInfo(typeInfo.Obj());
func->arguments.Add(argument);
}
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<ani>current";
argument->type = GetTypeFromTypeInfo(typeInfo.Obj());
func->arguments.Add(argument);
}
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<ani>ratio";
argument->type = GetTypeFromTypeInfo(typeInfoDouble.Obj());
func->arguments.Add(argument);
}
func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<void>::CreateTypeInfo().Obj());
if (generateImpl)
{
auto block = Ptr(new WfBlockStatement);
func->statement = block;
SortedList<WString> varNames;
EnumerateProperties([&](EnumerateMemberAccessor accessor, description::IPropertyInfo* propInfo, description::IPropertyInfo* originPropInfo)
{
WString intFunc = L"<ani-int>";
if (From(targets).Any([=](const Target& target)
{
return target.name == originPropInfo->GetName() && target.interpolation != L"";
}))
{
intFunc += originPropInfo->GetName();
}
Ptr<WfExpression> part1, part2, propChain;
{
auto refParent = Ptr(new WfReferenceExpression);
refParent->name.value = L"<ani>begin";
auto refProp = Ptr(new WfTypeCastingExpression);
refProp->expression = (propChain = accessor(refParent));
refProp->type = GetTypeFromTypeInfo(TypeInfoRetriver<double>::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"<ani>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"<ani>end";
auto refProp = Ptr(new WfTypeCastingExpression);
refProp->expression = accessor(refParent);
refProp->type = GetTypeFromTypeInfo(TypeInfoRetriver<double>::CreateTypeInfo().Obj());
refProp->strategy = WfTypeCastingStrategy::Strong;
auto refInt = Ptr(new WfReferenceExpression);
refInt->name.value = intFunc;
auto refRatio = Ptr(new WfReferenceExpression);
refRatio->name.value = L"<ani>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<WfExpression> exprMixed;
{
auto addExpr = Ptr(new WfBinaryExpression);
addExpr->first = part1;
addExpr->second = part2;
addExpr->op = WfBinaryOperator::Add;
if (propInfo->GetReturn()->GetTypeDescriptor() == description::GetTypeDescriptor<double>())
{
exprMixed = addExpr;
}
else if(propInfo->GetReturn()->GetTypeDescriptor() == description::GetTypeDescriptor<double>())
{
exprMixed = addExpr;
}
else
{
auto refRound = Ptr(new WfChildExpression);
refRound->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<Math>());
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<WfMemberExpression>())
{
name = L"_" + member->name.value + name;
propChain = member->parent;
}
varNames.Add(name);
varRef->name.value = L"<ani>" + 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"<ani>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(<ani>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"<ani>ratio";
argument->type = GetTypeFromTypeInfo(typeInfoDouble.Obj());
func->arguments.Add(argument);
}
func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<void>::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"<ani>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(<ani>target : <TYPE>, <ani>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"<ani>target";
argument->type = GetTypeFromTypeInfo(typeInfo.Obj());
func->arguments.Add(argument);
}
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<ani>time";
argument->type = GetTypeFromTypeInfo(TypeInfoRetriver<vuint64_t>::CreateTypeInfo().Obj());
func->arguments.Add(argument);
}
func->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<IGuiAnimation>>::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"<ani>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"<ani>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<Math>());
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<vuint64_t>::CreateTypeInfo().Obj());
castExpr->expression = callRoundExpr;
castExpr->strategy = WfTypeCastingStrategy::Strong;
auto varDecl = Ptr(new WfVariableDeclaration);
varDecl->name.value = L"<ani>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"<ani>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<IGuiAnimation>());
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"<ani>currentTime";
argument->type = GetTypeFromTypeInfo(TypeInfoRetriver<vuint64_t>::CreateTypeInfo().Obj());
funcDecl->arguments.Add(argument);
}
funcDecl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<void>::CreateTypeInfo().Obj());
auto subBlock = Ptr(new WfBlockStatement);
funcDecl->statement = subBlock;
{
auto refCurrentTime = Ptr(new WfReferenceExpression);
refCurrentTime->name.value = L"<ani>currentTime";
auto firstExpr = Ptr(new WfTypeCastingExpression);
firstExpr->expression = refCurrentTime;
firstExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver<double>::CreateTypeInfo().Obj());
firstExpr->strategy = WfTypeCastingStrategy::Strong;
auto refTime = Ptr(new WfReferenceExpression);
refTime->name.value = L"<ani>time";
auto secondExpr = Ptr(new WfTypeCastingExpression);
secondExpr->expression = refTime;
secondExpr->type = GetTypeFromTypeInfo(TypeInfoRetriver<double>::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"<ani>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 (<ani>current : <TYPE>)
auto func = Ptr(new WfConstructorDeclaration);
animationClass->declarations.Add(func);
func->constructorType = WfConstructorType::SharedPtr;
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<ani>current";
argument->type = GetTypeFromTypeInfo(typeInfo.Obj());
func->arguments.Add(argument);
}
if (generateImpl)
{
auto block = Ptr(new WfBlockStatement);
func->statement = block;
{
List<WString> 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"<ani>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> GuiInstancePropertyInfo::Unsupported()
{
return Ptr(new GuiInstancePropertyInfo);
}
Ptr<GuiInstancePropertyInfo> GuiInstancePropertyInfo::Assign(Ptr<description::ITypeInfo> typeInfo)
{
auto info = Ptr(new GuiInstancePropertyInfo);
info->support = SupportAssign;
if (typeInfo) info->acceptableTypes.Add(typeInfo);
return info;
}
Ptr<GuiInstancePropertyInfo> GuiInstancePropertyInfo::AssignWithParent(Ptr<description::ITypeInfo> typeInfo)
{
auto info = Assign(typeInfo);
info->mergability = MergeWithParent;
return info;
}
Ptr<GuiInstancePropertyInfo> GuiInstancePropertyInfo::Collection(Ptr<description::ITypeInfo> typeInfo)
{
auto info = Assign(typeInfo);
info->support = SupportCollection;
return info;
}
Ptr<GuiInstancePropertyInfo> GuiInstancePropertyInfo::CollectionWithParent(Ptr<description::ITypeInfo> typeInfo)
{
auto info = Collection(typeInfo);
info->mergability = MergeWithParent;
return info;
}
Ptr<GuiInstancePropertyInfo> GuiInstancePropertyInfo::Set(Ptr<description::ITypeInfo> typeInfo)
{
auto info = Ptr(new GuiInstancePropertyInfo);
info->support = SupportSet;
if (typeInfo) info->acceptableTypes.Add(typeInfo);
return info;
}
Ptr<GuiInstancePropertyInfo> GuiInstancePropertyInfo::Array(Ptr<description::ITypeInfo> 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<GlobalStringKey>& propertyNames)
{
}
void IGuiInstanceLoader::GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List<GlobalStringKey>& propertyNames)
{
}
void IGuiInstanceLoader::GetPairedProperties(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo, collections::List<GlobalStringKey>& propertyNames)
{
}
Ptr<GuiInstancePropertyInfo> IGuiInstanceLoader::GetPropertyType(GuiResourcePrecompileContext& precompileContext, const PropertyInfo& propertyInfo)
{
return nullptr;
}
bool IGuiInstanceLoader::CanCreate(const TypeInfo& typeInfo)
{
return false;
}
Ptr<workflow::WfBaseConstructorCall> 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<workflow::WfExpression>, ArgumentMap&, GuiResourceError::List&)#This function is not implemented.");
}
Ptr<workflow::WfStatement> IGuiInstanceLoader::InitializeRootInstance(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, ArgumentMap& arguments, GuiResourceError::List& errors)
{
return nullptr;
}
Ptr<workflow::WfStatement> 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<workflow::WfStatement> 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<workflow::WfExpression> 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<GuiInstanceContext::ElementName>
{
typedef GuiInstanceContext::ElementName ElementName;
public:
Regex regexElementName;
const vint _namespaceName;
const vint _category;
const vint _name;
const vint _binding;
GuiInstanceContextElementNameParser()
: regexElementName(L"((<namespaceName>[a-zA-Z_]/w*):)?((<category>[a-zA-Z_]/w*).)?(<name>[a-zA-Z_]/w*)(-(<binding>[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<ElementName> ParseInternal(const WString& text, collections::List<glr::ParsingError>& errors)override
{
Ptr<RegexMatch> 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"<ctor-parameter>";\
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<ITypeDescriptor*, GlobalStringKey> FieldKey;
typedef Tuple<Ptr<GuiInstancePropertyInfo>, IPropertyInfo*> PropertyType;
Dictionary<FieldKey, PropertyType> propertyTypes;
Dictionary<ITypeDescriptor*, IMethodInfo*> defaultConstructors;
Dictionary<ITypeDescriptor*, IMethodInfo*> 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<WfClass*>(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<IValueList>())
{
readableList = true;
writableList = true;
collectionType = true;
return genericType->GetGenericArgument(0);
}
else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor<IValueObservableList>())
{
readableList = true;
writableList = true;
collectionType = true;
return genericType->GetGenericArgument(0);
}
else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor<IValueEnumerator>())
{
collectionType = true;
return genericType->GetGenericArgument(0);
}
else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor<IValueEnumerable>())
{
readableList = true;
collectionType = true;
return genericType->GetGenericArgument(0);
}
else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor<IValueReadonlyList>())
{
readableList = true;
collectionType = true;
return genericType->GetGenericArgument(0);
}
else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor<IValueReadonlyDictionary>())
{
collectionType = true;
return nullptr;
}
else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor<IValueDictionary>())
{
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<GlobalStringKey>& 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<GlobalStringKey>& 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<GlobalStringKey>& 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<GuiInstancePropertyInfo> 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<workflow::WfBaseConstructorCall> 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<workflow::WfStatement> 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<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);
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"<collection>";
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"<collection>";
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<workflow::WfExpression> 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<GlobalStringKey, Ptr<IGuiInstanceBinder>> BinderMap;
typedef Dictionary<GlobalStringKey, Ptr<IGuiInstanceEventBinder>> EventBinderMap;
typedef List<Ptr<IGuiInstanceDeserializer>> DeserializerList;
struct VirtualTypeInfo
{
GlobalStringKey typeName;
ITypeDescriptor* typeDescriptor = nullptr;
GlobalStringKey parentTypeName; // for virtual type only
Ptr<IGuiInstanceLoader> loader;
List<ITypeDescriptor*> parentTypes; // all direct or indirect base types that does not has a type info
List<VirtualTypeInfo*> parentTypeInfos; // type infos for all registered direct or indirect base types
};
typedef Dictionary<GlobalStringKey, Ptr<VirtualTypeInfo>> VirtualTypeInfoMap;
Ptr<IGuiInstanceLoader> 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<VirtualTypeInfo> 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<VirtualTypeInfo> 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<IGuiInstanceBinder> 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<IGuiInstanceEventBinder> 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<IGuiInstanceDeserializer> 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<IGuiInstanceLoader> 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<IGuiInstanceLoader> 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<VirtualTypeInfo> typeInfo = typeInfos.Values()[index];
if (typeInfo->parentTypeInfos.Count() > 0)
{
return typeInfo->parentTypeInfos[0]->loader.Obj();
}
return rootLoader.Obj();
}
return 0;
}
Ptr<description::ITypeInfo> 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<elements::IGuiGraphicsElement>())
{
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<GlobalStringKey>& 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<WString>& 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<WString>& fragments)
{
Split(input, L"::", fragments);
}
void SplitBySemicolon(const WString& input, collections::List<WString>& 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<workflow::WfExpression> GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfStatement> GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfExpression> GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfStatement> GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfExpression> GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> propInfo, const WString& code, GuiResourceTextPos position, GuiResourceError::List& errors)override
{
return Workflow_ParseExpression(precompileContext, { resolvingResult.resource }, code, position, errors);
}
Ptr<workflow::WfStatement> GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfExpression> GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfStatement> GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfExpression> GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfStatement> GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfExpression> GenerateConstructorArgument(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<workflow::WfStatement> GenerateInstallStatement(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GlobalStringKey variableName, description::IPropertyInfo* propertyInfo, IGuiInstanceLoader* loader, const IGuiInstanceLoader::PropertyInfo& prop, Ptr<GuiInstancePropertyInfo> 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<WfCallExpression>())
{
if (auto refExpr = callExpr->function.Cast<WfReferenceExpression>())
{
auto defaultLs=From(resolvingResult.context->localizeds)
.Where([](Ptr<GuiInstanceLocalized> ls)
{
return ls->defaultStrings;
})
.First(nullptr);
if (defaultLs)
{
auto thisExpr = Ptr(new WfReferenceExpression);
thisExpr->name.value = L"<this>";
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 <ref.LocalizedStrings> by adding a Default=\"true\" attribute." });
}
}
else if (auto memberExpr = callExpr->function.Cast<WfMemberExpression>())
{
if (auto refStrings = memberExpr->parent.Cast<WfReferenceExpression>())
{
auto thisExpr = Ptr(new WfReferenceExpression);
thisExpr->name.value = L"<this>";
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 \"<string-name>\" or \"<localized-strings-name>.<string-name>\"." });
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<workflow::WfStatement> 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<WfType>
{
protected:
Ptr<workflow::Parser> parser;
public:
GuiParser_WorkflowType(Ptr<workflow::Parser> _parser)
:parser(_parser)
{
}
Ptr<WfType> ParseInternal(const WString& text, List<glr::ParsingError>& 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<WfExpression>
{
protected:
Ptr<workflow::Parser> parser;
public:
GuiParser_WorkflowExpression(Ptr<workflow::Parser> _parser)
:parser(_parser)
{
}
Ptr<WfExpression> ParseInternal(const WString& text, List<glr::ParsingError>& 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<WfStatement>
{
protected:
Ptr<workflow::Parser> parser;
public:
GuiParser_WorkflowStatement(Ptr<workflow::Parser> _parser)
:parser(_parser)
{
}
Ptr<WfStatement> ParseInternal(const WString& text, List<glr::ParsingError>& 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<WfStatement>
{
protected:
Ptr<workflow::Parser> parser;
public:
GuiParser_WorkflowCoProviderStatement(Ptr<workflow::Parser> _parser)
:parser(_parser)
{
}
Ptr<WfStatement> ParseInternal(const WString& text, List<glr::ParsingError>& 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<WfDeclaration>
{
protected:
Ptr<workflow::Parser> parser;
public:
GuiParser_WorkflowDeclaration(Ptr<workflow::Parser> _parser)
:parser(_parser)
{
}
Ptr<WfDeclaration> ParseInternal(const WString& text, List<glr::ParsingError>& 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<WfModule>
{
protected:
Ptr<workflow::Parser> parser;
public:
GuiParser_WorkflowModule(Ptr<workflow::Parser> _parser)
:parser(_parser)
{
}
Ptr<WfModule> ParseInternal(const WString& text, List<glr::ParsingError>& 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<GuiIqQuery>
{
protected:
instancequery::Parser parser;
public:
Ptr<GuiIqQuery> ParseInternal(const WString& text, List<glr::ParsingError>& 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<ITypeInfo> 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<IValueFunctionProxy>())
{
if (genericType->GetGenericArgument(1)->GetTypeDescriptor() == description::GetTypeDescriptor<Value>())
{
auto returnType = genericType->GetGenericArgument(0);
if (returnType->GetDecorator() == ITypeInfo::RawPtr)
{
if (returnType->GetElementType()->GetTypeDescriptor()->CanConvertTo(description::GetTypeDescriptor<GuiTemplate>()))
{
return true;
}
}
}
}
}
}
return false;
}
bool IsDataVisualizerFactoryType(ITypeInfo* propType)
{
return propType->GetDecorator() == ITypeInfo::SharedPtr && propType->GetTypeDescriptor() == description::GetTypeDescriptor<list::IDataVisualizerFactory>();
}
bool IsDataEditorFactoryType(ITypeInfo* propType)
{
return propType->GetDecorator() == ITypeInfo::SharedPtr && propType->GetTypeDescriptor() == description::GetTypeDescriptor<list::IDataEditorFactory>();
}
public:
GuiTemplatePropertyDeserializer()
{
stringType = TypeInfoRetriver<WString>::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<ITypeDescriptor*>& tds,
GuiResourceTextPos tagPosition,
GuiResourceError::List& errors
)
{
List<WString> 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<WfExpression> CreateTemplateFactory(
types::ResolvingResult& resolvingResult,
List<ITypeDescriptor*>& 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<Value>::CreateTypeInfo().Obj());
argViewModel->name.value = L"<viewModel>";
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<ITypeInfo> controlTemplateType;
{
auto elementType = Ptr(new TypeDescriptorTypeInfo(controlTemplateTd, TypeInfoHint::Normal));
auto pointerType = Ptr(new RawPtrTypeInfo(elementType));
controlTemplateType = pointerType;
}
Ptr<WfBlockStatement> returnStatBlock;
if (viewModelType)
{
auto refViewModel = Ptr(new WfReferenceExpression);
refViewModel->name.value = L"<viewModel>";
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"<viewModel>";
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<WfExpression> CreateDataVisualizerFactory(
types::ResolvingResult& resolvingResult,
List<ITypeDescriptor*>& controlTemplateTds,
GuiResourceTextPos tagPosition,
GuiResourceError::List& errors
)
{
auto templateType = TypeInfoRetriver<GuiGridVisualizerTemplate*>::CreateTypeInfo();
Ptr<WfExpression> previousFactory;
for (auto [controlTemplateTd, index] : indexed(controlTemplateTds))
{
List<ITypeDescriptor*> tds;
tds.Add(controlTemplateTd);
auto refFactory = CreateTemplateFactory(resolvingResult, tds, templateType.Obj(), templateType.Obj(), tagPosition, errors);
auto createStyle = Ptr(new WfNewClassExpression);
createStyle->type = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<list::DataVisualizerFactory>>::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<WfExpression> CreateDataEditorFactory(
types::ResolvingResult& resolvingResult,
List<ITypeDescriptor*>& controlTemplateTds,
GuiResourceTextPos tagPosition,
GuiResourceError::List& errors
)
{
auto templateType = TypeInfoRetriver<GuiGridEditorTemplate*>::CreateTypeInfo();
auto refFactory = CreateTemplateFactory(resolvingResult, controlTemplateTds, templateType.Obj(), templateType.Obj(), tagPosition, errors);
auto createStyle = Ptr(new WfNewClassExpression);
createStyle->type = GetTypeFromTypeInfo(TypeInfoRetriver<Ptr<list::DataEditorFactory>>::CreateTypeInfo().Obj());
createStyle->arguments.Add(refFactory);
return createStyle;
}
Ptr<workflow::WfExpression> Deserialize(
GuiResourcePrecompileContext& precompileContext,
types::ResolvingResult& resolvingResult,
const IGuiInstanceLoader::PropertyInfo& propertyInfo,
description::ITypeInfo* typeInfo,
Ptr<workflow::WfExpression> valueExpression,
GuiResourceTextPos tagPosition,
GuiResourceError::List& errors
)override
{
auto stringExpr = valueExpression.Cast<WfStringExpression>();
List<ITypeDescriptor*> 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<GuiControl>()))
{
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<GuiControlTemplate>()))
{
expectedTemplateType = returnType;
}
}
}
}
}
}
return CreateTemplateFactory(resolvingResult, tds, returnTemplateType, expectedTemplateType, tagPosition, errors);
}
}
};
/***********************************************************************
GuiItemPropertyDeserializer
***********************************************************************/
class GuiItemPropertyDeserializer : public Object, public IGuiInstanceDeserializer
{
protected:
Ptr<ITypeInfo> 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<IValueFunctionProxy>())
{
if (genericType->GetGenericArgument(1)->GetTypeDescriptor() == description::GetTypeDescriptor<Value>())
{
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<IValueFunctionProxy>())
{
if (genericType->GetGenericArgument(1)->GetTypeDescriptor() == description::GetTypeDescriptor<Value>()
&& genericType->GetGenericArgument(3)->GetTypeDescriptor() == description::GetTypeDescriptor<bool>())
{
if (IsSameType(genericType->GetGenericArgument(0), genericType->GetGenericArgument(2)))
{
return true;
}
}
}
}
}
return false;
}
public:
GuiItemPropertyDeserializer()
{
stringType = TypeInfoRetriver<WString>::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<workflow::WfExpression> Deserialize(
GuiResourcePrecompileContext& precompileContext,
types::ResolvingResult& resolvingResult,
const IGuiInstanceLoader::PropertyInfo& propertyInfo,
description::ITypeInfo* typeInfo,
Ptr<workflow::WfExpression> valueExpression,
GuiResourceTextPos tagPosition,
GuiResourceError::List& errors
)override
{
auto stringExpr = valueExpression.Cast<WfStringExpression>();
Ptr<WfExpression> 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<WfType> 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<WfReferenceExpression>())
{
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"<item>";
argument->type = GetTypeFromTypeInfo(genericType->GetGenericArgument(1));
funcDecl->arguments.Add(argument);
}
if (isWritableItemProperty)
{
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<value>";
argument->type = GetTypeFromTypeInfo((acceptValueType = genericType->GetGenericArgument(2)));
funcDecl->arguments.Add(argument);
}
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<update>";
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"<item>";
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<WfReturnStatement> 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"<update>";
ifStat->expression = refUpdate;
}
{
auto block = Ptr(new WfBlockStatement);
ifStat->trueBranch = block;
{
auto refValue = Ptr(new WfReferenceExpression);
refValue->name.value = L"<value>";
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<ITypeInfo> stringType;
public:
GuiDataProcessorDeserializer()
{
stringType = TypeInfoRetriver<WString>::CreateTypeInfo();
}
bool CanDeserialize(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override
{
return typeInfo->GetTypeDescriptor() == description::GetTypeDescriptor<IDataFilter>()
|| typeInfo->GetTypeDescriptor() == description::GetTypeDescriptor<IDataSorter>();
}
description::ITypeInfo* DeserializeAs(const IGuiInstanceLoader::PropertyInfo& propertyInfo, description::ITypeInfo* typeInfo)override
{
return stringType.Obj();
}
Ptr<workflow::WfExpression> Deserialize(
GuiResourcePrecompileContext& precompileContext,
types::ResolvingResult& resolvingResult,
const IGuiInstanceLoader::PropertyInfo& propertyInfo,
description::ITypeInfo* typeInfo,
Ptr<workflow::WfExpression> valueExpression,
GuiResourceTextPos tagPosition,
GuiResourceError::List& errors
)override
{
auto stringExpr = valueExpression.Cast<WfStringExpression>();
Ptr<WfExpression> 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<WfType> 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<void>::CreateTypeInfo().Obj());
{
auto argument = Ptr(new WfFunctionArgument);
argument->type = GetTypeFromTypeInfo(TypeInfoRetriver<IDataProcessorCallback*>::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<WString> argumentNames;
if (typeInfo->GetTypeDescriptor() == description::GetTypeDescriptor<IDataFilter>())
{
decl->name.value = L"Filter";
decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<bool>::CreateTypeInfo().Obj());
argumentNames.Add(L"<row>");
}
else
{
decl->name.value = L"Compare";
switch (precompileContext.targetCpuArchitecture)
{
case GuiResourceCpuArchitecture::x86:
decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<vint32_t>::CreateTypeInfo().Obj());
break;
case GuiResourceCpuArchitecture::x64:
decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver<vint64_t>::CreateTypeInfo().Obj());
break;
default:
CHECK_FAIL(L"The target CPU architecture is unspecified.");
}
argumentNames.Add(L"<row1>");
argumentNames.Add(L"<row2>");
}
for (auto name : argumentNames)
{
auto argument = Ptr(new WfFunctionArgument);
argument->type = GetTypeFromTypeInfo(TypeInfoRetriver<Value>::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<types::ScriptPosition> 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<GuiInstanceCompiledWorkflow> Workflow_GetModule(GuiResourcePrecompileContext& context, const WString& path, Nullable<GuiInstanceCompiledWorkflow::AssemblyType> assemblyType)
{
auto compiled = context.targetFolder->GetValueByPath(path).Cast<GuiInstanceCompiledWorkflow>();
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<WfModule> 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<WString> 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<GuiResourceItem> resource, GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override
{
switch (context.passIndex)
{
case Workflow_Collect:
{
if (auto obj = resource->GetContent().Cast<GuiInstanceSharedScript>())
{
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<DescriptableObject> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
if (auto obj = content.Cast<GuiInstanceSharedScript>())
{
return obj->SaveToXml();
}
return nullptr;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<GuiResourcePathResolver> resolver, GuiResourceError::List& errors)override
{
if (auto xml = resource->GetContent().Cast<XmlDocument>())
{
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<GuiResourceItem> resource, GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override
{
switch (context.passIndex)
{
case Workflow_Collect:
{
if (auto obj = resource->GetContent().Cast<GuiInstanceContext>())
{
auto record = context.targetFolder->GetValueByPath(L"ClassNameRecord").Cast<GuiResourceClassNameRecord>();
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<GuiInstanceContext>())
{
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<GuiInstanceLocalized> ls) {return ls->defaultStrings; }))
)
{
if (index > 0)
{
errors.Add(GuiResourceError({ resource }, localized->tagPosition, L"Precompile: Only one <ref.LocalizedStrings> 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"<instance>" + 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<GuiInstanceContext>())
{
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"<constructor>" + obj->className, resolvingResult, errors))
{
if (auto instanceModule = Workflow_GenerateInstanceClass(context, L"<instance>" + 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<DescriptableObject> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
if (auto obj = content.Cast<GuiInstanceContext>())
{
return obj->SaveToXml();
}
return nullptr;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<GuiResourcePathResolver> resolver, GuiResourceError::List& errors)override
{
if (auto xml = resource->GetContent().Cast<XmlDocument>())
{
Ptr<GuiInstanceContext> 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<DescriptableObject> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
if (auto obj = content.Cast<GuiInstanceStyleContext>())
{
return obj->SaveToXml();
}
return nullptr;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<GuiResourcePathResolver> resolver, GuiResourceError::List& errors)override
{
if (auto xml = resource->GetContent().Cast<XmlDocument>())
{
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<GuiResourceItem> 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<GuiInstanceGradientAnimation>())
{
if (auto module = obj->Compile(context, L"<animation>" + 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<DescriptableObject> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
if (auto obj = content.Cast<GuiInstanceGradientAnimation>())
{
return obj->SaveToXml();
}
return nullptr;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<GuiResourcePathResolver> resolver, GuiResourceError::List& errors)override
{
if (auto xml = resource->GetContent().Cast<XmlDocument>())
{
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<GuiResourceItem> resource, GuiResourcePrecompileContext& context, GuiResourceError::List& errors)override
{
switch (context.passIndex)
{
case Workflow_Collect:
{
if (auto obj = resource->GetContent().Cast<GuiInstanceLocalizedStrings>())
{
if (auto module = obj->Compile(context, L"<localized-strings>" + obj->className, errors))
{
Workflow_AddModule(context, Path_Shared, module, GuiInstanceCompiledWorkflow::Shared, obj->tagPosition);
}
}
}
break;
case Instance_CompileInstanceClass:
{
if (auto obj = resource->GetContent().Cast<GuiInstanceLocalizedStringsInjection>())
{
if (auto module = obj->Compile(context, L"<localized-strings-injection>" + 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<DescriptableObject> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
if (auto obj = content.Cast<GuiInstanceLocalizedStrings>())
{
return obj->SaveToXml();
}
if (auto obj = content.Cast<GuiInstanceLocalizedStringsInjection>())
{
return obj->SaveToXml();
}
return nullptr;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<GuiResourcePathResolver> resolver, GuiResourceError::List& errors)override
{
if (auto xml = resource->GetContent().Cast<XmlDocument>())
{
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::Strings> GuiInstanceLocalizedStringsBase::LoadStringsFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlElement> xmlStrings, collections::SortedList<WString>& 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<glr::xml::XmlElement> GuiInstanceLocalizedStringsBase::SaveStringsToXml(Ptr<Strings> 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<GuiInstanceLocalizedStrings::TextDesc> 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<ITypeInfo> 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<DateTime>::CreateTypeInfo();
}
else if (function.Length() >= 5 && (function.Left(5) == L"Date:" || function.Left(5) == L"Time:"))
{
type = TypeInfoRetriver<DateTime>::CreateTypeInfo();
}
else if (function == L"Number" || function == L"Currency")
{
type = TypeInfoRetriver<WString>::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<WString>::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<Strings> 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<Strings> defaultStrings, Ptr<Strings> 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<Strings> defaultStrings, Ptr<Strings> 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<Strings> defaultStrings, collections::List<Ptr<Strings>>& 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<Strings> lss)
{
auto encoded = From(lss->locales)
.Aggregate(
WString::Empty,
[](auto&& a, auto&& b)
{
return a + WString::Unmanaged(L"_") + b;
});
return WString::Unmanaged(L"<ls") + encoded + WString::Unmanaged(L">BuildStrings");
}
Ptr<workflow::WfFunctionDeclaration> GuiInstanceLocalizedStringsBase::GenerateTextDescFunctionHeader(Ptr<TextDesc> 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<WString>::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"<ls>" + itow(i);
argument->type = GetTypeFromTypeInfo(type.key.Obj());
func->arguments.Add(argument);
}
return func;
}
Ptr<workflow::WfExpression> GuiInstanceLocalizedStringsBase::GenerateTextDescArgumentFormatting(Ptr<description::ITypeInfo> type, const WString& function, vint argumentIndex)
{
WString argumentName = L"<ls>" + itow(argumentIndex);
if (function == L"ShortDate" || function == L"LongDate" || function == L"YearMonthDate" || function == L"ShortTime" || function == L"LongTime")
{
auto refLoc = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<Localization>());
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"<ls>locale";
auto callFormats = Ptr(new WfCallExpression);
callFormats->function = refFormats;
callFormats->arguments.Add(refLocale);
auto refFirst = Ptr(new WfChildExpression);
refFirst->parent = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<helper_types::LocalizedStrings>());
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"<ls>locale";
auto refParameter = Ptr(new WfReferenceExpression);
refParameter->name.value = argumentName;
auto refLoc2 = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<Localization>());
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"<ls>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<Localization>());
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"<ls>locale";
auto refParameter = Ptr(new WfReferenceExpression);
refParameter->name.value = argumentName;
auto refLoc2 = GetExpressionFromTypeDescriptor(description::GetTypeDescriptor<Localization>());
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<workflow::WfBlockStatement> GuiInstanceLocalizedStringsBase::GenerateTextDescFunctionBody(Ptr<TextDesc> textDesc)
{
auto appendExpr = [](Ptr<WfExpression> resultExpr, Ptr<WfExpression> strExpr) -> Ptr<WfExpression>
{
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"<ls>_" + 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<WfExpression> 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"<ls>_" + 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<typename TResult, typename TTopQualified, typename TChild>
Ptr<TResult> GenerateFullNameAst(const WString& fullName)
{
Ptr<TResult> refClass;
{
List<WString> 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<workflow::WfExpression> GuiInstanceLocalizedStringsBase::GenerateStringsConstructor(const WString& interfaceFullName, TextDescMap& textDescs, Ptr<Strings> lss)
{
auto lsExpr = Ptr(new WfNewInterfaceExpression);
{
auto refPointer = Ptr(new WfSharedPointerType);
refPointer->element = GenerateFullNameAst<WfType, WfTopQualifiedType, WfChildType>(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<workflow::WfFunctionDeclaration> GuiInstanceLocalizedStringsBase::GenerateBuildStringsFunction(const WString& interfaceFullName, TextDescMap& textDescs, Ptr<Strings> 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<WfType, WfTopQualifiedType, WfChildType>(interfaceFullName);
func->returnType = refPointer;
}
{
auto argument = Ptr(new WfFunctionArgument);
argument->name.value = L"<ls>locale";
argument->type = GetTypeFromTypeInfo(TypeInfoRetriver<Locale>::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<workflow::WfBlockStatement> GuiInstanceLocalizedStringsBase::GenerateStaticInit(const WString& stringsClassWithoutNs, const WString& installClassFullName, collections::List<Ptr<Strings>>& strings)
{
auto block = Ptr(new WfBlockStatement);
for (auto ls : strings)
{
auto cppName = GenerateStringsCppName(ls);
for (auto locale : ls->locales)
{
Ptr<WfExpression> 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<WfExpression, WfTopQualifiedExpression, WfChildExpression>(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> GuiInstanceLocalizedStrings::LoadFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlDocument> 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<WString> 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<glr::xml::XmlElement> 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<workflow::WfFunctionDeclaration> 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"<ls>locale";
argument->type = GetTypeFromTypeInfo(TypeInfoRetriver<Locale>::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"<ls>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"<ls>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"<ls>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"<ls>locale";
callExpr->arguments.Add(refLocale);
}
{
auto refImpl = Ptr(new WfReferenceExpression);
refImpl->name.value = L"<ls>impl";
callExpr->arguments.Add(refImpl);
}
auto exprStat = Ptr(new WfExpressionStatement);
exprStat->expression = callExpr;
block->statements.Add(exprStat);
}
return func;
}
Ptr<workflow::WfFunctionDeclaration> 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"<ls>locale";
argument->type = GetTypeFromTypeInfo(TypeInfoRetriver<Locale>::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"<ls>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"<ls>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<workflow::WfModule> GuiInstanceLocalizedStrings::Compile(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, GuiResourceError::List& errors)
{
vint errorCount = errors.Count();
TextDescMap textDescs;
{
List<Ptr<Strings>> 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<Locale>::CreateTypeInfo().Obj());
mapType->value = ptrType;
auto lsCache = Ptr(new WfVariableDeclaration);
lsCache->type = mapType;
lsCache->expression = Ptr(new WfConstructorExpression);
cacheName = L"<ls>" + 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> GuiInstanceLocalizedStringsInjection::LoadFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlDocument> 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<WString> existingLocales;
for (auto xmlStrings : XmlGetElements(xml->rootElement))
{
if (auto lss = LoadStringsFromXml(resource, xmlStrings, existingLocales, errors))
{
ls->strings.Add(lss);
}
}
return ls;
}
Ptr<glr::xml::XmlElement> 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<Strings> defaultStrings, TextDescMap& textDescs, GuiResourceError::List& errors)
{
auto tdString = description::GetTypeDescriptor<WString>();
auto tdDateTime = description::GetTypeDescriptor<DateTime>();
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<vint>(0, tdMethod->GetParameterCount())
.Select([tdMethod](vint j) -> ParameterPair
{
return { CopyTypeInfo(tdMethod->GetParameter(j)->GetType()),WString::Empty };
})
);
CopyFrom(
textDesc->positions,
Range<vint>(0, tdMethod->GetParameterCount())
);
}
}
else
{
errors.Add(GuiResourceError(tagPosition, L"Precompile: interface \"" + td->GetTypeName() + L"\" has more than one function named \"" + tdMethodGroup->GetName() + L"\"."));
}
}
}
Ptr<workflow::WfModule> 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<Locale>()) 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 <LocalizedStrings/>."));
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<GuiValueRepr> repr)
{
repr->fromStyle = fromStyle;
repr->tagPosition = tagPosition;
}
/***********************************************************************
GuiTextRepr
***********************************************************************/
Ptr<GuiValueRepr> GuiTextRepr::Clone()
{
auto repr = Ptr(new GuiTextRepr);
GuiValueRepr::CloneBody(repr);
repr->text = text;
return repr;
}
void GuiTextRepr::FillXml(Ptr<glr::xml::XmlElement> xml)
{
if (!fromStyle)
{
auto xmlText = Ptr(new XmlText);
xmlText->content.value = text;
xml->subNodes.Add(xmlText);
}
}
/***********************************************************************
GuiAttSetterRepr
***********************************************************************/
void GuiAttSetterRepr::CloneBody(Ptr<GuiAttSetterRepr> 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<GuiValueRepr> GuiAttSetterRepr::Clone()
{
auto repr = Ptr(new GuiAttSetterRepr);
GuiAttSetterRepr::CloneBody(repr);
repr->fromStyle = fromStyle;
return repr;
}
void GuiAttSetterRepr::FillXml(Ptr<glr::xml::XmlElement> 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<GuiValueRepr> value) {return !value->fromStyle; }))
{
bool containsElement = From(value->values)
.Any([](Ptr<GuiValueRepr> value)
{
return !value->fromStyle && !value.Cast<GuiTextRepr>();
});
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<GuiTextRepr>())
{
repr->FillXml(xmlProp);
}
}
xml->subNodes.Add(xmlProp);
}
else
{
for (auto repr : value->values)
{
if (auto textRepr = repr.Cast<GuiTextRepr>())
{
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<GuiValueRepr> 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<glr::xml::XmlElement> 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<GuiResourceItem> resource, GuiAttSetterRepr::ValueList& values, Ptr<glr::xml::XmlElement> xml, GuiResourceError::List& errors)
{
if (auto parser = GetParserManager()->GetParser<ElementName>(L"INSTANCE-ELEMENT-NAME"))
{
// test if there is only one text value in the xml
if (xml->subNodes.Count() == 1)
{
if (Ptr<XmlText> text = xml->subNodes[0].Cast<XmlText>())
{
auto value = Ptr(new GuiTextRepr);
value->text = text->content.value;
value->tagPosition = { {resource},text->content.codeRange.start };
values.Add(value);
}
else if (Ptr<XmlCData> text = xml->subNodes[0].Cast<XmlCData>())
{
auto value = Ptr(new GuiTextRepr);
value->text = text->content.value;
value->tagPosition = { {resource},text->content.codeRange.start };
value->tagPosition.column += 9; // <![CDATA[
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 = 3046; // 28794 bytes before compressing
static const vl::vint dataBlock = 256;
static const vl::vint dataRemain = 230;
static const vl::vint dataSolidRows = 11;
static const vl::vint dataRows = 12;
static const char* compressed[] = {
"\x7A\x70\x00\x00\xDE\x0B\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\xCE\x02\x71\x01\x79\xC3\x40\xFB\x70\xF1\x4E\x75\x42\xAF\x75\x5E\xFA\x40\xF0\xD7\x79\xFD\xFE\xF2\xCA\x44\x70\x69\x97\x35\x2D\x93\x7D\x79\x21\x00\xB7\x2B\x7F\x5D\x33\x7E\x41\x7F\x79\x38\x03\xA4\x31\x26\xF9\x61\x32\x02\xC3\x3D\x2A\x07\x89\x3B\x80\x27\x33\x82\x40\x16\x80\x3D\x08\x89\x86\x7F\x15\x9D\x29\x4C\x7C\x22\x81\x93\x37\x79\x20\xFC\x7C\x48\x01\x86\x25\x7F\xBB\x24\x87\x2E\x31\x27\x84\x00\x29\x84\x25\x17\x8F\x87\x24\x86\x25\x84\x49\x08\x85\x2E\x0D\x81\x26",
"\x86\x0D\x82\x86\x0A\x99\x89\x79\x0E\xA9\x25\x87\x0A\x20\x88\x78\x1C\x87\x3B\x18\xAD\x63\x85\x03\x2D\x84\x69\x32\x84\x87\x90\x0A\x8D\x89\x27\x37\x89\x4C\x23\x82\x88\x92\x0C\x8B\x8B\x59\x9D\x8A\x15\xE2\x8D\x22\x2D\xA0\x8B\x8C\x3A\x88\x8C\x0C\xE1\x89\x8D\x32\xA4\x8C\x23\x66\x87\x8C\x1C\xEF\x8B\x23\x38\xB2\x8F\x1F\x76\x92\x8D\x1E\xE7\x8B\x8E\x30\xBD\x8B\x8B\x7F\x90\x83\x11\xF7\x2E\x86\x00\x39\x87\x2E\x5F\x97\x8D\x1D\xF4\x8F\x1E\x2A\x80\x58\x8A\x02\x32\x89\x72\x01\x96\x85\x32\x54\x93\x87\x65\x45\x93\x21\x80\x8C\x91\x4B\xA1\x26\x91\xE7\x50\x92\x6B\x5D\x2E\x93\x8E\x20\x96\x85\x9D\x89\x95\x1B\xF3\x8B\x95\x45\xAD\x90\x8F\xAA\x8B\x8D\x0D\xB1\x97\x87\x59\xAF\x91\x91\x8A\x98\x97\x1D\x8C\x80\x3C\x27\x83\x91\x39\x0C\x2F\x95\x21\xD5\x8D\x22\x5D\xB2\x8E\x98\x67\x9C\x94\x16\xA4\x22\x87\xC0\x01\x9A\x96\x21\x23\x98\x29\xB4\x97\x82\x36\x90\x9E\x8D\xAF\x85\x94\x2B\xD7\x9B\x9B\x5A\xAA\x8E\x9B\xD8\x9C\x9A\x2B\xE2\x90\x97\x6C\x94\x9D\x97\xD6\x80\x9D\x37\xD5\x98\x92\x8B\x62\x95\x3B\x21\x8F\x94\x0F\x84\x9A\x21\x42\xB1\x20\x99\x60\x8A",
"\x9A\x22\x9B\x22\x87\x3F\x8F\x9A\x9D\x1B\x25\x93\x3F\xC9\x33\x9E\xD2\x05\x96\x9E\x27\x38\x9F\x16\xFA\x9B\x9F\x7E\x9D\x2B\xA0\xE8\x84\x26\x40\xD3\x96\x9D\x8A\xA4\x9A\x9B\xE3\x80\xA1\x39\xE4\x9E\x82\x24\x89\x20\xA1\x5E\x8C\x91\x47\xF4\x9F\xA3\x78\xA4\x9C\xA1\x8A\x8E\xA1\x5D\x10\xAB\x99\x68\x8A\x24\xA5\x82\x9F\x94\x78\x07\xA6\xA4\x8D\xA8\xA7\x8E\x2A\xB7\x2C\x4C\xFB\x93\xA3\xBA\x0A\xA7\x9E\x8C\x97\xA6\x1C\xB9\xA4\x35\x9D\x8A\x95\xA7\x88\x81\xA8\x23\xC4\xA0\x98\x46\x88\xAC\x34\x18\xBB\xA2\x46\xD1\xA4\xAB\x73\xAD\xA1\x9C\x53\xB6\xAB\x3E\xD2\xAC\x9D\x6F\x9D\xA8\xAB\x5F\xAB\x9D\x44\xDE\xA3\xAC\xB0\xA5\xAA\xAC\x57\xA8\xAF\x56\xD5\xA6\xA3\xAC\xB2\x9D\x88\xD7\x34\xA6\x4F\xA2\xA0\xAF\x77\xA0\xA1\x24\x3F\xA7\x26\x50\xE7\x8C\xA8\xF0\x06\xAF\x8E\x4F\xA4\xA1\x5D\xC4\x85\xA5\xB9\xAF\x93\xAF\x60\x9D\xAF\x75\x7F\xA2\x8F\xC0\xA0\x3C\xAD\x17\xBA\xAB\x3E\x90\xBE\xAD\xC8\xAD\xA9\xAC\x1B\x39\x7F\x1F\xF2\xA9\xA9\xB7\x89\x23\xB3\xF5\x95\xA4\x66\xFF\x18\xB1\x2D\x8A\xB1\x26\x8C\xA7\x8E\x63\xFA\x79\x89\x0F\x85\xB5\xB3\x27\xAB\xA9\x6B\xAB",
"\xAE\xA9\x97\xA2\xB7\xAC\x1B\x39\xAC\x49\x25\xBE\x96\x83\x3E\x9D\xB6\x09\x29\xB5\x6E\xCA\xAF\x95\xD3\xA7\x22\xB8\x5B\x8B\xB4\x17\x97\xB8\xB6\xAE\x8D\xBC\xB2\xA3\xB0\xBB\x73\x92\xBA\x90\xE9\xA9\xA9\xA3\xD1\xB4\xBB\x1D\xD1\xAB\x93\xD1\xBA\xB1\x24\xDD\xAD\xB9\x78\xD7\xBF\x1F\xF1\x9B\xAE\xBC\xFB\x88\xBE\x22\xEA\xB7\x8E\xF6\x8D\xB2\xA6\x33\xAA\x23\x7C\x1E\xA6\x21\xF9\xA4\xA5\xBE\xAE\xB8\xBD\x5D\x5C\x00\xBF\x94\x05\xA2\x20\x8A\xA3\xBC\x13\x92\x9D\x7D\xD9\x86\x22\xC0\x0A\x24\xC0\x00\x01\xCA\x21\x01\xE0\x80\xBE\xCA\x9F\x22\x32\xAC\xAF\x22\x0A\xF6\xB4\x7E\x09\xD9\xC3\x6B\x83\x2C\xB3\x81\x0E\xC5\x80\x1A\xC6\x23\x87\xFA\xBC\x84\xF9\xA1\xC3\x20\xF6\xB1\x8A\x42\x76\x38\xC3\x84\x2C\xC5\xC4\x2E\xC7\xC6\x40\x08\xCD\xC5\x03\xCD\xC2\xC6\x01\x34\xC4\x8C\x86\x2D\x3E\x10\xF5\xC3\x20\x3D\xC2\xC4\x8E\x80\x01\xC8\x0F\xC3\xC9\x42\x42\xDF\xC6\x40\x48\xC6\xC8\x25\xC1\x24\xC9\x1B\x83\xCB\x15\xBA\xCA\xC5\xCF\x8A\x24\xCA\x91\x86\xC1\x61\x37\xCE\xC8\x00\x25\x40\xBE\x29\xC3\x93\x1F\xFD\xB0\x00\x28\xC7\x8F\x8A\x02\x10\x7D\xFE\x0A\xC2\x4A\xF8",
"\x97\x8B\x00\x6A\xDC\xCA\x41\x2A\x6E\xCC\xEA\x23\xBB\x62\x75\xC9\x20\x01\x71\xC6\xCB\x84\x18\x59\xCF\x22\xDC\xCE\x41\x32\x8D\x52\x40\xD1\x8A\xD0\xEF\x6A\x22\x97\x06\xD7\x20\x44\xF8\x7B\x4C\xFD\xB7\x88\x02\x0E\xD5\xC1\x84\x16\x54\xCC\x1F\xB4\xD0\x00\x57\x89\x56\x4C\xF5\xBA\xD3\x57\x8A\x5A\xA7\x83\x2B\x00\x4D\xE3\xBB\x5E\xA3\xC2\x20\x03\x26\xDA\x20\x7E\x69\xD7\xC9\x9A\xDA\x09\x7F\x8A\xAF\xD5\x47\xD6\x62\x86\xDC\x3F\x20\xAE\xE2\x3F\x23\x2B\x84\x9D\x63\xA7\x8A\x53\x47\x63\xB3\xCC\xEA\x06\xBD\x37\x9E\x6F\x5B\x94\xD4\x34\x48\x65\xBB\xD5\x37\xE3\xBF\xD6\x75\x1F\x25\x91\x62\xD3\x44\x89\xD2\xCA\x3B\x47\x45\xCB\x2E\xD9\x40\x03\xC4\xC2\xDE\xD8\x77\x0A\xC5\xB4\x32\xDC\x3D\x45\x83\xD4\x3A\x32\xD9\xD4\xCD\x20\x7D\xCA\x73\x2C\xB4\xD5\x7F\x8B\xD9\xDD\x84\x24\x49\x2C\xFD\xB9\x7C\x4B\xCF\xDF\x37\x8F\x08\x55\xDE\x2F\x5F\xBD\x40\x2C\xAF\xC5\x70\xC9\x23\x52\xEE\x85\x71\x98\x81\x27\xAF\xDB\x1F\x27\xD2\x36\xC0\x75\xC1\xAA\xDC\xD8\xEA\x34\x50\xDF\x13\x53\xE1\x40\x5F\xCF\x45\x64\xDC\x3C\xDB\x1B\xF5\xE3\xF2\x10\x41\xB5\x09\x5F\x20\x59",
"\xEF\xD0\x75\xC8\xBE\xCD\xE2\x85\x16\x5E\x62\x7F\xC0\xE3\x40\x41\xD2\x20\x8E\xF3\xE2\xE4\xED\x4B\x5A\xAF\x8D\x2A\x20\x3B\x66\xE2\x21\xF0\x49\xE3\xBD\x68\xD3\x20\x30\x7F\xE1\x21\xA8\xC5\x3A\xB7\xC4\xE2\x20\x2A\x47\xEE\x20\xFA\x42\xE8\xC0\x6E\xD6\x21\x1E\x4F\xEB\x20\xAE\xCA\xE8\xE8\x6D\xC6\x20\xAA\xC6\xE4\x76\xE2\x2E\xEA\x41\x3E\xED\xE5\x84\x06\x64\xE5\x8A\x58\xC9\x40\x62\xE5\xE8\x9C\xC3\x24\xCE\x49\xCF\x45\x21\xCC\x8C\xED\xA6\xEE\xEA\x20\x36\x12\xCE\xA2\x36\xE1\xCB\x84\x34\xDB\x20\x56\xE5\xEE\x41\x4F\x69\xE4\xE5\x46\x26\xE8\x71\xFF\xEB\x40\x66\x68\xE2\x83\x2D\x6D\xF1\x03\x35\xED\xA5\x87\xF3\xB0\x64\xCA\x20\x6F\x90\xFC\x54\xE2\xB7\xE9\x21\xCD\xC2\x22\xE3\xCF\x5F\x21\xDF\x52\xE7\x36\xB2\xC9\xD6\xDE\x0A\x21\xF2\xE2\x82\x2C\x71\xC2\xF3\x73\x20\xA6\xFD\xEE\xE0\x83\x26\x73\xCC\xC1\x22\x09\x70\xBF\xDC\xE7\xE3\xE5\xF3\x7E\xCA\x24\x74\xB6\xEF\x58\xC2\xB2\xE2\x21\xD8\xC1\x20\xF4\xB9\xCA\x23\xEA\x24\xFB\x37\x42\xDA\xEF\x50\x3D\xF7\xED\x40\x2D\x71\xF8\xEE\x2B\x57\xF9\x03\x3A\xF6\x40\x1E\xFE\x59\x8F\x3A\x75\xFA\xE2\x2E\x56",
"\xC5\x5A\xFB\xEC\xE9\xC0\x06\x78\xE0\xFD\x37\xC5\xD8\xF2\x21\xE1\xF0\xF6\xFC\x55\x0B\x59\xA7\xEC\xF1\x20\xF7\xDB\xFE\xFC\xD2\x6C\xFA\x75\x28\xE4\xFE\x00\x36\xFD\xFC\x57\x72\x10\xD4\x3A\x7F\xCA\x12\x6A\xFD\x70\x71\x03\x11\x29\x01\x81\x10\xD6\x34\x80\x44\x28\x80\xED\x76\x7E\xE3\x3A\x67\x0A\x1D\x05\xCB\x2E\x7C\x09\x86\x7E\x5E\x0F\x38\x18\x81\x81\x0B\x80\x00\x5F\x07\x65\x0A\x13\x06\xCB\x27\x7D\xEF\x7F\x81\x64\x0A\x65\xBC\x21\x2D\xC1\x76\x82\xF7\x7F\x81\x67\x0A\x82\xCE\x21\x73\xBB\x73\x10\x2E\x80\x80\xB3\x72\x10\x6A\x02\x83\xCF\x2E\x2E\xC1\x7B\x7E\x27\x89\x83\x01\x1D\x06\xBD\x77\x1B\x49\x75\x83\xB3\x2A\x10\xDC\x71\x7A\x0A\x1F\x06\x45\x8B\x1B\x59\x78\x84\x01\x10\x84\x76\x7F\x81\x71\x0F\x84\xD6\x18\x30\xC1\x73\x7F\x03\x12\x7E\x42\x80\x00\x73\x0C\x83\x28\x3C\x85\x02\x1C\x82\x5F\x86\x07\x43\x6C\x07\xF2\x7E\x72\xE6\x7D\x07\x43\x63\x08\xCB\x2C\x7F\x41\x8B\x7A\x01\x14\x08\x58\x8A\x1C\x15\x34\x7C\x01\x12\x87\x2F\x8F\x85\x86\x07\x87\x1F\x10\x77\x52\x80\x00\x7C\x88\x83\x74\x80\x00\x88\x00\x88\x0A\x1F\x32\xC1\x76\x80\x5D\x86",
"\x7E\x8A\x02\x86\x85\x3E\x88\x65\x86\x7E\x8D\x03\x64\x93\x0B\x2C\x94\x81\x10\x2F\x7F\x85\x94\x03\x64\x9A\x0B\x2C\x66\x83\x10\x54\x8D\x7D\xE2\x62\x1E\x9D\x83\x10\x85\x8C\x84\x23\x7D\x1B\x34\x8D\x2A\xE6\x7B\x09\x8F\x3F\x8A\x01\x13\x8A\xBC\x2F\x11\x9C\x02\x82\x09\x10\x0A\xCB\x24\x8B\x00\x09\x8A\xB7\x8A\x10\xA1\x0A\x8B\x06\x15\x0A\xCB\x2B\x2D\xBC\x7F\x81\xA6\x04\x8C\x8A\x27\x33\xAE\x70\x00\xC8\x8D\x76\x1F\x8A\x0A\xCC\x8C\x2B\x44\x3F\x8C\xD1\x85\x85\x5F\x8E\x0A\xD5\x8E\x2C\x84\x7E\x5B\x40\x71\x7D\x1F\x82\x0B\x92\x8D\x1B\x8C\x70\x8E\x09\x11\x74\x94\x7F\x81\xB5\x05\x8E\xBF\x11\x04\x3C\x8A\x8E\x91\x76\x7E\xB8\x0E\x8E\xB7\x13\x7A\xE8\x86\x10\x47\x82\x10\x3E\x8F\x85\xBB\x06\x8F\x1D\x3B\x8F\x01\x17\x76\x5F\x8E\x0B\x43\x64\x0C\xCB\x22\x90\x00\x0A\x85\x5F\x85\x0C\x43\x6B\x0C\xCB\x21\x75\xC9\x8F\x85\xCC\x00\x90\xD6\x11\x39\xCF\x82\x91\xD2\x8F\x85\xCF\x06\x91\xCA\x18\x7B\x19\x9A\x10\x92\x7C\x8A\x06\x12\x0D\x1E\x9F\x11\xA6\x3F\x8C\x51\x8C\x8F\xE6\x75\x0D\x27\x94\x1D\x2B\x93\x90\xE6\x78\x0D\x43\x6E\x0D\xCB\x21\x93\x0B\x96\x7E",
"\xDF\x03\x64\xE5\x0B\x2C\x04\x93\x10\xF2\x81\x8C\xAD\x8F\x1B\x0C\x93\x10\x1A\x92\x94\x60\x7D\x1B\x78\x69\x73\x1F\x86\x0E\x8F\x3B\x94\x03\x1F\x93\x48\x93\x10\xE7\x0D\x8D\x00\x0B\x0E\xCB\x20\x95\x02\x15\x94\x53\x92\x10\xEC\x06\x95\xF0\x0B\x2C\x79\x83\x87\x5D\x91\x10\xF1\x0A\x77\xBC\x20\x05\x56\x93\x96\x7D\x87\x88\xF6\x08\x96\xCE\x28\x3C\x14\x89\x10\x6C\x96\x88\x65\x90\x00\xFB\x00\x97\xCF\x2D\x80\x11\x73\x67\x0A\x19\x31\x1F\x83\x43\xE9\x70\x30\x2C\x30\x5F\xB9\x6B\x45\xB5\x69\x98\xF0\x53\x52\xFD\x7E\x5F\x2A\x14\x16\xD9\x6F\x0F\x8C\x97\x7A\x8D\x92\x70\x28\x44\x1F\x82\x96\x31\x0B\x64\x16\xFC\x6F\x49\x70\x5B\x99\xC1\x70\x9A\x7A\x83\x79\x32\x5D\x4C\xBA\x68\x99\x34\x7D\x6D\x80\x11\x48\x3B\x7C\x83\x11\x47\x45\x29\x1E\x5E\x25\x12\x9B\x1C\x13\x5E\xCD\x46\x9B\xC3\x68\x99\xD1\x69\x9B\xA1\x9B\x9B\x56\x99\x12\xB4\x6F\x53\xD8\x6F\x11\xC3\x9A\x97\xCD\x4C\x44\xC7\x98\x99\xC8\x94\x9C\x64\x6A\x60\x34\x1E\x9C\x31\x1A\x60\x98\x60",
};
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(L"element");
WriteToken(node->element);
EndField();
BeginField(L"keyField");
WriteToken(node->keyField);
EndField();
}
void AstVisitor::PrintFields(GuiRpArrayType* node)
{
BeginField(L"element");
Print(node->element.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpAttribute* node)
{
BeginField(L"cppType");
WriteToken(node->cppType);
EndField();
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void AstVisitor::PrintFields(GuiRpDeclaration* node)
{
BeginField(L"attributes");
BeginArray();
for (auto&& listItem : node->attributes)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void AstVisitor::PrintFields(GuiRpEnumDecl* node)
{
BeginField(L"members");
BeginArray();
for (auto&& listItem : node->members)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
}
void AstVisitor::PrintFields(GuiRpEnumMember* node)
{
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void AstVisitor::PrintFields(GuiRpEventDecl* node)
{
BeginField(L"request");
Print(node->request.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpEventRequest* node)
{
BeginField(L"type");
Print(node->type.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpMapType* node)
{
BeginField(L"element");
Print(node->element.Obj());
EndField();
BeginField(L"keyType");
Print(node->keyType.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpMessageDecl* node)
{
BeginField(L"request");
Print(node->request.Obj());
EndField();
BeginField(L"response");
Print(node->response.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpMessageRequest* node)
{
BeginField(L"type");
Print(node->type.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpMessageResponse* node)
{
BeginField(L"type");
Print(node->type.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpOptionalType* node)
{
BeginField(L"element");
Print(node->element.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpPrimitiveType* node)
{
BeginField(L"type");
switch (node->type)
{
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Binary:
WriteString(L"Binary");
break;
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Boolean:
WriteString(L"Boolean");
break;
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Char:
WriteString(L"Char");
break;
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Color:
WriteString(L"Color");
break;
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Double:
WriteString(L"Double");
break;
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Float:
WriteString(L"Float");
break;
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Integer:
WriteString(L"Integer");
break;
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::Key:
WriteString(L"Key");
break;
case vl::presentation::remoteprotocol::GuiRpPrimitiveTypes::String:
WriteString(L"String");
break;
default:
WriteNull();
}
EndField();
}
void AstVisitor::PrintFields(GuiRpReferenceType* node)
{
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void AstVisitor::PrintFields(GuiRpSchema* node)
{
BeginField(L"declarations");
BeginArray();
for (auto&& listItem : node->declarations)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
}
void AstVisitor::PrintFields(GuiRpStructDecl* node)
{
BeginField(L"members");
BeginArray();
for (auto&& listItem : node->members)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
BeginField(L"type");
switch (node->type)
{
case vl::presentation::remoteprotocol::GuiRpStructType::Class:
WriteString(L"Class");
break;
case vl::presentation::remoteprotocol::GuiRpStructType::Struct:
WriteString(L"Struct");
break;
default:
WriteNull();
}
EndField();
}
void AstVisitor::PrintFields(GuiRpStructMember* node)
{
BeginField(L"name");
WriteToken(node->name);
EndField();
BeginField(L"type");
Print(node->type.Obj());
EndField();
}
void AstVisitor::PrintFields(GuiRpType* node)
{
}
void AstVisitor::PrintFields(GuiRpUnionDecl* node)
{
BeginField(L"members");
BeginArray();
for (auto&& listItem : node->members)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
}
void AstVisitor::PrintFields(GuiRpUnionMember* node)
{
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void AstVisitor::Visit(GuiRpPrimitiveType* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(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(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(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(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(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(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(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(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(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(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(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(L"Attribute", node);
PrintFields(static_cast<GuiRpAttribute*>(node));
EndObject();
}
void AstVisitor::Print(GuiRpEnumMember* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"EnumMember", node);
PrintFields(static_cast<GuiRpEnumMember*>(node));
EndObject();
}
void AstVisitor::Print(GuiRpUnionMember* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"UnionMember", node);
PrintFields(static_cast<GuiRpUnionMember*>(node));
EndObject();
}
void AstVisitor::Print(GuiRpStructMember* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"StructMember", node);
PrintFields(static_cast<GuiRpStructMember*>(node));
EndObject();
}
void AstVisitor::Print(GuiRpMessageRequest* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"MessageRequest", node);
PrintFields(static_cast<GuiRpMessageRequest*>(node));
EndObject();
}
void AstVisitor::Print(GuiRpMessageResponse* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"MessageResponse", node);
PrintFields(static_cast<GuiRpMessageResponse*>(node));
EndObject();
}
void AstVisitor::Print(GuiRpEventRequest* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"EventRequest", node);
PrintFields(static_cast<GuiRpEventRequest*>(node));
EndObject();
}
void AstVisitor::Print(GuiRpSchema* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(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 = 8193; // 113198 bytes before compressing
static const vl::vint dataBlock = 256;
static const vl::vint dataRemain = 1;
static const vl::vint dataSolidRows = 32;
static const vl::vint dataRows = 33;
static const char* compressed[] = {
"\x2E\xBA\x01\x00\xF9\x1F\x00\x00\x21\x00\x01\x82\x80\x02\x0B\x82\x81\x82\x06\x89\x82\x9A\x0A\x85\x0E\x85\x12\x0A\xA9\x0A\x90\x1A\x84\x1A\x85\x1D\x0A\xC2\x0A\x88\x2A\x86\x26\x84\x2A\x0A\xDA\x0A\x82\x3A\x80\x36\x85\x37\x0A\xF6\x0A\x9A\x3A\x82\x1D\x09\x84\xFF\x31\xB2\x91\x9A\x80\x03\x99\x99\x35\xB7\xB2\x99\x9A\x9F\x7C\x9E\x9D\x3F\xB7\x81\xB8\x9A\x85\x9E\x9F\xA2\x3D\xC3\xBB\x88\xA0\xA5\x9A\x85\x00\x4F\xD1\x89\x82\x02\xAE\x83\x01\xAA\x03\x84\x18\xA2\x85\x03\xAD\x80\x03\x5E\x80\x07\x01\xB8\x01\xB2\xA2\xA5\x34\x8A\x89\x0A\x84\xA8\x99\xA4\xA6\x42\xF0\x84\xAE\xBD\xA4\xB9\xB8\xBB\x73\x86\xA7\xB2\xBB\xA0\xBD\xBE\xBD\x6F\xFE\xA9\xA2\xC7\xA4\xC0\xB5\xC2\x80\xF5\x89\xD7\xBB\xC1\xBF\x81\xBD\x86\xFC\x83\xCD\xCF\xBF\xC5\xC0\xCA\x93\x96\xCA\xDA\xCC\xC4\xCE\xC6\x81\x90\x98\xC8\xDE\xC5\xC8\xD3\xCA\xD2\x99\xA6\xDB\xCA\xDD\xCC\xD7\xCF\x80\xA1\xA8\xE3\xCE\xD5\xD0\xDB\xD2\xDA\xA9\xB6\xEB\xDA\xDD\xD4\xDF\xD6\x9B\xB7\xBE\xF5\xC0\xEB\xDC\xE1\xDE\xE3\xBF\x8B\x21\xAC\x0A\x87\xA9\xC9\xE7\xA2\x87\xD2\xF2\xC3\xDA\xE1\xDC\xE4\xC3\xB1\xF8\xD5",
"\xE8\xEF\xEA\xEC\xEB\xDC\xDF\xDD\xE1\xF1\xE3\xF3\xE8\xE8\xB2\xE7\xD1\xF4\xEA\xF1\xF4\xF7\xF7\xE8\xDB\xED\xF2\xF0\xFB\xF5\x85\x07\x61\x90\x0D\xF5\xFE\xF1\xF8\xF1\xF9\xFF\x7C\x74\x7E\x7F\xE6\x42\x81\x80\x81\xE2\x49\x85\x7A\x82\xC5\x4C\x87\x72\x83\xBF\x50\x89\x77\x82\x14\x8D\x85\x87\x83\x17\x91\x89\x87\x70\x13\x21\x54\x07\x7E\x08\x9B\x8E\x76\x88\xE4\x56\x86\x88\x86\x27\x9A\x89\x8B\x84\x2B\xA3\x8D\x89\x89\x28\xB1\x8A\x8A\x8C\x2C\xB4\x8E\x8A\x8D\x30\xB3\x8A\x8D\x8D\x3B\xB7\x8D\x8D\x8E\xC3\x57\x01\x58\x06\x20\xB6\x76\x91\x7F\x47\x83\x89\x93\x81\x4B\x85\x81\x8B\x8B\x00\x8E\x9D\x92\x84\x3E\xBC\x86\x95\x95\x58\x80\x99\x95\x94\x54\x9A\x9E\x94\x97\x24\x91\x9B\x05\x58\x1C\x05\x98\x93\x99\x4A\xA8\x9C\x92\x9A\x52\xAC\x9D\x94\x98\x50\x86\x8D\x99\x9A\x74\xAB\x95\x9F\x9C\x76\xB9\x98\x9F\x9E\x6F\xB2\x9D\x9F\x93\x38\x91\x9F\x05\x58\x20\x26\x97\x9F\x9F\x53\xA1\x9E\x9E\xA2\x80\xBF\x80\x9D\xA0\x8B\xB1\x9D\xA3\x95\x5F\x91\xA0\xA7\xA4\x5B\x96\xAE\xA2\xA6\xC3\x63\x01\x58\x09\x86\xBA\x98\xA2\x9B\x8C\x89\xA2\xA6\xA9\x97\xA8\xAB\xA4\xA6",
"\x95\xAC\xAF\xA3\xAA\xAA\x94\xAF\xAA\xAC\x9C\x99\xA4\x83\x09\x61\x68\x01\xA8\x9F\xA5\xA4\xA7\xAA\xAF\xA9\x80\xB0\xAE\xB0\xB4\xAE\xA5\xAD\xAB\xB1\xB6\xA9\xB0\xB2\xC4\x8A\xBD\xB0\xB3\x77\xAB\x01\x58\x0B\xBB\xA3\xA7\xA1\xAF\xD7\xBF\xA9\xB5\xB0\xDB\x83\xBD\xB5\xB1\xCB\xB3\xAE\xB3\xB7\xE3\xA2\xA8\xB6\xB9\xDA\xA8\xBC\xB6\xBA\xDE\xAC\xB0\xBB\xB3\xE2\x90\xBE\xB9\xB9\xBC\xA9\xB5\xBF\xBA\x7B\xAF\x06\x5B\xB9\xF7\xAD\xBD\xBF\xBB\xE4\xB2\xBB\x9C\x45\x09\x50\x59\x41\x0C\xD5\xBC\xB6\xB7\xBC\x02\xCB\xCF\xBC\xBD\x0E\xD1\xCA\xC3\xC4\xF6\x92\xC5\xC4\xC5\xF8\x96\xC9\xC4\xC6\xFE\x9A\xCD\xC4\xC7\x00\xCC\xC1\xBF\xC8\xC7\xA4\xC6\xB0\x81\x16\x45\xC5\xCB\xCA\x27\xE1\xBC\xCA\xCB\x2D\xF0\xBF\xCA\xCC\x31\xC1\xC6\xC8\xCC\x38\xF4\xC9\xCE\xCD\x33\xFC\xC9\x41\x0D\xFB\x97\xC2\xD3\xC6\x43\xDF\xC5\xD1\xC8\x0F\xCD\xC0\xC8\xC4\x4B\xCA\xD6\xBE\x0D\x41\xC4\xD2\xD6\xD1\x53\xC3\x77\x0D\x58\x38\x09\xC7\xD0\xD3\x5B\xCE\xD5\xD4\xD7\x5F\xDE\xD4\xD7\xD8\x48\xDE\xC5\xD9\xD3\x37\xFA\xC3\x40\x46\x2A\xC9\x4C\x0E\xD6\x61\xE9\xDE\xCF\xCE\x22\xFD\xC5\xDD\xCD\x77",
"\xF4\xD9\xD2\xDC\x79\xEA\xD3\xDE\xDF\x01\x7F\x01\x58\x10\x70\xE4\xD0\xDA\xE1\x62\xE7\xDD\xD4\xDF\x7B\xF6\xDD\xE0\xDE\x8F\xFA\xD6\xDB\xE1\x8A\xF1\xDE\xE3\xE4\x89\xD4\xEA\xE5\xE6\x9C\xCC\xE8\xE6\xE7\xE5\x43\x11\xD4\xE2\xA0\xCB\xE7\xE4\xDA\xA7\xE6\xE4\x80\x11\x61\x45\x11\x5A\x11\x61\x47\x11\x58\x47\x6D\xC6\x49\x11\x58\x4A\x21\x5B\x11\x58\x4C\x23\xE8\xD1\x13\x6C\x69\xE6\xE4\xE4\x9F\xCE\xEF\x11\x58\x50\x05\xE5\xE4\xE9\xC2\xCC\xF4\xF0\xEA\xCF\xEA\xE2\xE4\xF4\xD3\xD2\xF0\xE1\xE4\xD7\xC5\xF1\xF7\xF0\xD5\xDC\xF9\xF4\xF5\xDF\xD6\xF2\x43\x14\xBE\xDB\xE5\xEA\xF7\x7F\xE9\xFD\xDE\xFA\xD8\xEC\xFA\xF5\xF7\xCE\xF0\xFB\xF3\xFC\xE6\xCD\xF8\xD0\x48\xB5\xE1\xF8\xFB\xFA\xFC\xED\xFD\xFF\xFB\xFA\x71\x7D\x00\xF4\x7C\x3B\x2A\x25\x7D\x73\xF6\x75\x7F\xF6\x02\x8E\x7C\xF0\x4D\x82\x7C\xFF\x6E\x81\x04\x90\x8B\x4E\x2B\x07\x87\x7C\x0C\x93\x83\xFE\x7E\x7C\x82\x00\x8F\x83\x83\x1E\x9A\x83\x6F\x57\x07\x83\x04\x88\x83\x81\x04\x98\x81\x0A\xA6\x8A\x84\x05\xB2\x7E\x85\x03\x90\x87\x07\x99\x8D\x82\x09\xB5\x84\x82\x58\x05\x84\x0A\xB2\x82\x85\x15\xBB\x87",
"\x84\x2F\x80\x89\x0C\xC2\x83\x86\x1F\x81\x8D\x85\x44\x9D\x84\x0F\xB7\x80\x84\x1B\xA1\x84\x89\xFE\x59\x0A\x0E\xC7\x8C\x85\x2A\xBF\x80\x89\x58\x96\x88\x15\xD7\x8A\x8B\x21\x99\x8C\x8B\x60\x9B\x8A\x18\xDE\x8D\x8B\x22\x8B\x8F\x89\x0E\x62\x25\xFE\x66\x89\x88\x28\x86\x8C\x8C\x61\x90\x8F\x18\xEC\x8F\x8B\x39\x8A\x8D\x8D\x4F\x9B\x09\x58\x5C\x03\x8A\x39\xBE\x8C\x8E\x65\x97\x8D\x1D\xFF\x82\x90\xC7\x5D\x0D\x8F\x80\x91\x8D\x22\xF6\x8E\x8D\x33\x8E\x8F\x91\x14\x88\x8C\x24\xCD\x81\x93\xF2\x1E\x08\x91\x85\x8A\x92\x9E\x5F\x08\x93\x46\xB8\x8B\x92\x34\x92\x91\x25\xA3\x94\x93\x52\xA1\x90\x94\x6F\x8B\x90\x21\x9E\x93\x90\x55\xAE\x91\x93\x8C\x8E\x60\x18\x1D\x92\x94\x53\xA9\x90\x96\xAB\x95\x97\x29\xA4\x94\x87\x30\x34\x90\x95\x8E\x9C\x97\x2D\xAC\x91\x90\x62\x9A\x96\x98\xB1\x80\x9B\x27\xC2\x91\x98\x5B\x97\x3C\x24\x6B\x98\x97\x2B\xC8\x99\x96\x65\xAD\x92\x9A\xD8\x94\x9B\x34\xBA\x93\x98\x6E\x8D\x9B\x97\xCE\x8B\x99\x38\xD7\x9A\x9B\x6C\xA3\x0F\x97\xCC\x82\x60\x19\x68\x93\x9D\x62\x9E\x9A\x9C\xE0\x91\x9D\x37\xD6\x9E\x9C\x7A\x87\x9F\x9D\xE4\x98",
"\x9D\x3D\xE9\x99\x9E\x7B\x89\x9C\x9F\xFB\x8D\x9F\x3D\xFE\x95\x9A\x7B\x65\x0C\x9D\xF2\x9F\x9B\x3C\x80\xA3\xA0\x86\xBF\x9A\xA0\x0F\xB4\x86\x19\x1D\x97\x0C\x84\x8B\xA0\xA2\x05\xB8\xA3\x36\x84\xAB\xA2\x87\xAB\x96\x24\xD1\x9B\x4D\x1A\x16\xAA\xA1\x92\xAD\x8A\x0D\x24\xB0\x9F\x45\x89\xAA\xA4\x93\xBD\x9E\xA3\x1D\xBA\xA1\x36\xFA\x9D\xA0\x99\xA5\x9F\xA6\x34\xBA\x6F\x1A\x29\xAF\xA4\x9B\xB9\xA1\xA3\x2C\xBD\xA5\x50\x81\xA4\x86\x36\x3C\xA4\xA8\x2B\xA9\xAA\x4B\xC8\xAB\xA9\x9A\x83\xAE\xA9\x4A\xAD\xA6\x54\xC2\xA8\x69\x36\x07\xA8\xAA\x4D\xB1\xA1\x54\xD4\xA9\xAA\xA0\x9B\xAC\xA9\x53\xA0\xAC\x57\xE1\xA8\xAA\xB2\x9A\xAD\xAB\xD3\x8E\x0F\x55\xE7\xA2\x60\x94\x21\xA7\xA7\x31\xAF\xA8\x5B\xE3\xA4\xAE\xB1\xB6\xAD\xAC\x75\xB8\xAF\x5D\xF3\xAB\xAE\xAF\xA8\xAB\xA6\x1C\xA0\xB0\x4C\x82\xBE\xA7\xC0\x80\x00\x0E\x6B\xBE\xAE\x59\x8A\xB9\xAE\xBE\xBA\xAF\xB1\x8E\xAD\x49\x1C\x1D\x92\x0F\xC4\xB1\xAF\xAB\x90\xAC\xB1\x5F\x97\xBF\xAE\x9C\xA5\x3B\x0E\x9D\x94\x0E\x65\x84\xB2\xAE\x36\x75\x0B\xB4\x9E\xA3\xB1\x6A\x85\xBA\xB4\xB8\xA4\xB0\xB3\x91\xBA\xB1\x66\x9C",
"\xBB\xB0\xDA\xA4\x9A\x25\x6F\xA6\xB2\x6B\xAB\xBE\x5F\x3B\x28\xB3\xB7\xC0\xBA\xB6\x70\xAD\xB3\xB8\xD6\x86\xBD\xB4\xB6\xBB\xB3\x6B\x9D\xB1\xB8\xE2\x8E\xBF\xB8\xB0\xB2\xB5\x6C\xC9\xB3\xB7\x80\x38\x0F\xB7\xC5\xA8\xBB\x72\xB5\xBB\xBA\xC6\x79\x09\x2C\x2C\x21\xA7\x1E\x61\x2C\x0F\xB0\x3D\x09\x2C\x7E\x01\x2F\x1F\x61\x20\x11\xB0\x01\x10\xB5\x82\x01\x79\x75\xBC\xB1\xBB\x3B\x44\x10\xBB\xCF\xBA\xB8\x7D\xCC\xB9\xBB\xFA\x9D\xBA\xB9\xFB\xBC\xB9\x80\x8D\xB2\xBB\x02\xD4\xBB\xBA\x01\x25\x10\x7E\xD0\xBC\xBF\xFC\xBE\xBB\xC0\x00\xCD\xBB\x06\x86\x1B\xC0\xFD\x92\xC6\xC2\xFD\xAD\xC0\x83\xDC\x37\x11\x0A\xCF\xC7\xC2\x1F\xD9\xC2\x80\xA0\xCA\xC2\x0C\xCE\xC5\xC4\x21\xD4\x80\x22\x1E\xC8\xC5\x16\xE3\xC2\xC4\x8C\x69\x10\x8B\xAF\xC7\xC4\x81\x4A\x13\xC6\x04\xC7\xC2\x81\xFF\xB0\x73\x45\x38\xC1\xC2\x36\x8C\x13\x8F\xF3\xB4\xC4\x1A\xDB\xC1\xC7\x3C\xC8\xC0\x84\xC4\xC0\xC6\x20\xF5\xC4\x9C\x8D\x03\xCA\x92\xC5\xC8\xC8\x00\x0E\x11\x2C\x8F\x12\xCB\x8E\xCB\xC3\xCB\x26\xCC\xCF\xC9\x4E\xC7\xC9\x98\xA6\xC2\xCD\x2F\xE5\xCC\x91\x90\x1A\xCA\x8E\xEB\xC9\xC9\x2D",
"\xD4\xCB\xCC\x29\xC7\xCE\x9B\xDE\xCD\xCA\x30\xC4\x41\x12\x6A\xCD\xCC\x9B\xFB\x42\x13\x3C\xDC\xCB\xCE\x76\xD5\xCE\x9C\xFB\xCF\xCC\x33\xE4\xCF\xD0\x71\xC8\xD0\xBD\x13\x1E\xCF\x42\xC2\xD2\xD1\x02\xD4\x11\xA3\xF4\xC0\xD1\x41\xFA\xCF\xD2\x7F\xC4\xD0\xA5\x9A\xD1\xD1\x4A\xD0\xD5\xCA\x8E\xDE\xD3\x30\x95\x11\x2C\x4B\x21\x2F\x12\x61\x38\x11\x58\x19\x11\x2C\x4D\x21\x2B\x13\x61\x3C\x11\x58\x1D\x18\xB4\x4F\x32\xBF\xD1\x89\xCF\xC0\x28\x13\xDD\xD2\x4E\xD6\xD1\xD3\x98\xC1\xD6\xAF\x9F\xD0\xCE\x17\xE0\xD3\xD3\xC1\xD6\x85\x28\x3C\xDF\xD6\x61\xC9\xDD\xD7\xCF\xCD\xD8\xBF\x22\x1C\xD8\x62\xC6\xD0\x69\xA3\x15\xD9\xAE\xC6\xD5\xD8\x23\xD6\xD8\xD7\xDC\xD7\xD9\xB8\xE0\xDE\xDB\x6D\xE5\xDB\xDC\xA2\xCB\x88\x29\x61\x25\x15\xB0\x26\x11\x2C\xA7\x01\x2C\x2A\x61\x29\x15\xB0\x2A\x11\x2C\xAB\x01\x2C\x2B\x28\xBD\x15\x5B\xE9\xDF\xDC\x02\xCF\x16\xB6\xE8\xD3\xD8\x73\xC7\xD8\xDA\xC0\xC9\xE2\xB3\x8A\xE8\xD8\x86\xC8\xE3\xE1\x0E\x70\x17\xC0\x80\xE7\xE0\x69\xCF\xE5\xE1\x10\xE5\x3D\x2C\x13\xE5\xE2\xFD\xB2\x14\xE3\xDD\xDD\xE2\xC1\xA1\xE4\xE4\x71\xD4\xE5\xE4",
"\xE4\xC2\xE4\xC1\xD1\xDF\xDB\x7F\xEA\xE7\xE4\x26\xF5\x27\x2C\x20\xE1\xE6\x94\xEE\xE2\x4E\xB4\x01\x2D\x2D\x34\xE9\xE4\x9B\xC2\x26\x16\x3C\xF7\xE5\xCD\xC3\xE6\x21\x5B\x01\xED\xE0\x2B\xFB\x4C\x2E\x47\xEC\xE5\x91\xC4\xEA\xE8\x3D\xEF\xEB\x9D\x39\x1C\xE8\x87\xF8\x5A\x17\x55\xF9\xE3\xC5\xDB\xE6\xE3\xAE\xED\xE0\xE9\x30\xF1\xEA\xD8\xDB\xCB\x17\xAC\xD8\xE7\xEC\x08\xFC\x16\xD9\xDC\xEF\xEB\xA6\xC9\xEA\xEB\x5E\xEE\xEB\xD8\xE0\xEF\xE5\xBA\xFE\xE6\xED\x61\xE3\x21\x2F\x61\x2E\x17\xB0\x3F\x11\x2C\xC0\x01\x2D\x30\x61\x22\x19\xB0\x03\x19\x2C\xC4\x01\x2D\x31\x28\xB6\x18\x7F\xF4\xEF\xEE\x1C\x88\x1B\xDA\xF1\xEF\xEC\xB4\xD4\xF1\xEF\x8F\xF2\xE8\xDE\xF6\xEA\xF2\xAB\xED\xEB\x4F\xC9\x13\xF3\xE7\xF0\xE3\xF4\xCB\xE5\xF2\xB5\xCA\x02\xF6\xDC\xD0\xEC\x4D\x65\x2A\xF5\xF2\x6C\xEB\xF5\xE6\xF3\xEB\xF2\xC8\xE4\xF2\xF6\xB5\xFD\xF3\xED\xB0\xF7\xF2\xCE\xCD\x4C\x19\xAF\xF8\xF1\xEE\xB4\xFB\x4F\x66\x01\xFE\xF7\xAC\xE2\x22\x33\x47\xF6\xF6\xD3\xF8\xF6\xF3\xCF\xEB\xE3\x33\x4C\xFD\xF2\x68\x14\xFC\xF8\xBB\xE2\xF8\xF4\xBC\xF7\xF5\xDE\xCD\xF9\xF6\xDC\xE8\x69",
"\x34\x57\xF9\xF8\x4C\xD2\x19\x2C\xD3\x01\x2C\x35\x61\x25\x1B\xB0\x16\x18\xB5\xD7\x04\xFF\xEC\xE5\xFB\xFA\xED\xD9\xF8\xF9\xF3\xF9\xFF\xF0\xF4\xFB\xB6\x6C\x32\xFB\xFF\xFA\x75\x7F\xF8\x70\x80\x98\x69\x0D\xFF\x72\x80\xDF\x7E\x7D\xBA\x7E\x7C\x4B\x4A\x0D\x07\x87\x7F\x09\x8D\x7D\x12\x81\x7D\x36\x4B\x0D\x0F\x8C\x80\xF6\x78\x81\x03\x88\x80\xC7\x4C\x0D\x17\x80\x7E\x19\x80\x82\x1B\x80\x81\x9D\x7D\x0D\x61\x1E\x0D\x61\x1F\x0D\x61\x10\x0E\x61\x11\x0E\xA8\x52\x0E\x1F\x8A\x80\x8C\x43\x0E\x31\x83\x81\xE1\x77\x83\x21\x82\x83\xFC\x7A\x81\x90\x74\x0E\x61\x15\x0E\x61\x16\x0E\x61\x17\x0E\x61\x18\x0E\xA8\x59\x0E\x35\x84\x81\xAA\x5A\x0E\x49\x8D\x59\xEB\x0D\x84\x39\x86\x83\x51\x8A\x84\x3A\x81\x80\xE2\x1C\x0E\x61\x1D\x0E\x61\x1E\x0E\x61\x1F\x0E\x61\x10\x0F\xA8\x51\x0F\x50\x83\x82\x36\x42\x0F\x63\x81\x81\x54\x82\x85\x64\x82\x82\x68\x88\x83\x35\x13\x0F\xA8\x54\x0F\x61\x15\x0F\x61\x16\x0F\x61\x17\x0F\x61\x18\x0F\xA8\x59\x0F\x67\x8B\x80\x14\x4A\x0F\x7D\x8C\x48\xFB\x08\x5A\xFC\x01\x16\xFD\x01\x16\xFE\x06\x16\x61\x10\x00\x06\x33\x10\x8D\x87",
"\x3D\x01\x0F\x88\x01\x12\x89\x04\x8C\x81\x4A\x62\x00\x94\x84\x89\x96\x8B\x65\x67\x0D\x16\x03\x1E\x89\x03\x1D\x00\xD4\x10\x8A\x02\x12\x8A\x84\x14\x8A\x01\x16\x8A\xA2\x18\x8A\x00\x0A\x8A\xB2\x1C\x8A\xAE\x8B\x1D\xB0\x83\x8A\x0A\x11\x8B\xE0\x13\x8B\xA7\x85\x8B\xB4\x8E\x14\xCB\x26\x14\x6B\x1C\x8B\xAF\x8A\x10\x0E\x07\x2C\xBE\x8A\x10\x1D\x24\x18\x9A\x85\x16\x84\x1F\x8B\x06\x18\x10\xA2\x1D\x15\x84\x16\x14\xC9\x84\x1D\xCC\x83\x10\xCE\x82\x1B\xD0\x82\x1A\x46\x13\x16\xD1\x8D\x13\xAC\x8C\x1C\x84\x1A\x8C\xDA\x8D\x13\xD5\x82\x10\x2F\x18\x8C\x0A\x12\x8E\xB2\x15\x8E\x01\x17\x8D\xDB\x19\x8D\xB2\x1B\x8D\xD4\x16\x14\xAC\x8A\x89\x46\x1A\x8E\xDB\x15\x8C\x53\x14\x1D\xD3\x8B\x8C\x0A\x1E\x8E\xE0\x10\x8F\xF9\x8D\x13\xDC\x83\x8E\x3A\x1C\x8A\xF8\x80\x1E\x09\x93\x1E\xFA\x86\x10\xCA\x18\x8E\xC0\x8B\x1D\xEC\x84\x10\xD4\x12\x90\xE0\x12\x8D\x11\x92\x91\xFF\x85\x91\xF3\x84\x90\x1D\x97\x90\x0A\x10\x8E\xA2\x1B\x90\x46\x1D\x90\x03\x17\x8E\xA2\x1A\x89\x87\x13\x91\x00\x93\x1E\x16\x9C\x90\x1E\x9D\x8D\x20\x99\x5B\x3A\x14\x92\x25\x9A\x13\x13\x9C\x8A",
"\x18\x99\x91\xE3\x1C\x92\x1C\x92\x93\x37\x15\x90\xF1\x8E\x8D\xE9\x84\x1D\x36\x97\x93\x33\x13\x91\x0F\x99\x92\x0A\x1F\x92\x26\x97\x10\x3F\x96\x90\x37\x1A\x89\x4E\x94\x8E\x1B\x94\x18\x55\x98\x94\x32\x12\x94\x03\x93\x93\x06\x12\x92\xB2\x17\x94\x5A\x9F\x0F\x13\x98\x92\xB2\x14\x95\xD4\x87\x95\xCF\x8F\x91\x41\x9C\x96\x33\x15\x8F\x46\x9E\x96\x32\x19\x93\xFC\x8D\x94\x69\x99\x10\x2D\x96\x14\x59\x93\x96\x5C\x97\x91\x44\x99\x10\x62\x93\x13\x81\x98\x94\x4A\x95\x97\x09\x1D\x97\x3D\x9A\x96\xD8\x82\x97\x31\x1A\x89\x88\x9F\x94\xED\x81\x95\x43\x9A\x13\x8F\x93\x96\x31\x1F\x8D\x71\x90\x94\x49\x9A\x10\x66\x9B\x1D\x8E\x97\x97\xCD\x82\x99\x5D\x9D\x96\x9A\x92\x13\x70\x91\x8E\x8C\x94\x96\x8E\x70\x1E\x9F\x9E\x8F\x78\x92\x9A\x7E\x94\x99\xA9\x98\x90\x99\x92\x95\x9B\x99\x10\x4B\x97\x96\xCA\x31\x13\x3E\x98\x95\xA9\x9A\x89\xCE\x12\x1A\xBD\x9B\x96\xA5\x91\x13\x95\x96\x99\x98\x98\x9A\xC5\x9A\x9A\x09\x1D\x99\xAC\x9B\x9B\xCC\x91\x9A\xBE\x9B\x9C\xC7\x93\x96\xA7\x93\x92\xA9\x94\x97\x10\x96\x15\xA0\x96\x8D\xB0\x90\x93\xB2\x9B\x9C\xB4\x9A\x9C\xB6",
"\x93\x97\x0A\x19\x9B\x9E\x9B\x9A\x89\x9F\x9A\xD3\x95\x9E\x8D\x9A\x9E\x90\x94\x91\xED\x93\x99\xA4\x9E\x9E\xFF\x09\x9C\xD8\x9B\x9C\x65\x96\x98\x06\x1A\x93\x56\x9C\x9E\xC4\x96\x9F\xD5\x9A\x95\xD7\x91\x96\xD9\x90\x9F\x3D\x1A\x89\xFE\x98\x93\x8A\x9F\x8E\xA9\x93\xA0\x48\x93\x9E\xF9\x96\x9F\x85\x9B\x9D\x8E\x8D\x9D\x50\x93\x9F\xA3\x93\x13\x9A\x86\x8F\xFF\x92\x9D\x01\xA4\x9F\x33\x10\xA1\x37\x98\x9F\x06\xAA\x9F\x9C\x9C\x9F\x17\xAE\x9A\x20\xAB\x98\xD4\x93\x9B\x07\x43\x98\x37\x9A\x9D\x4C\x94\x93\x37\x13\x9C\x2E\xA2\xA0\x30\xA0\x98\xB5\x92\xA2\xE6\x98\x9B\x2A\xA2\x10\x60\x1C\xA2\xDE\x9A\xA1\xB1\x93\x95\x0A\x13\xA4\xC2\x9D\xA0\x01\x9F\xA0\x3B\xAF\x95\x3D\xAB\xA1\x3F\xA6\x10\xCE\x93\x1E\x9A\x8A\xA4\xEB\x8C\xA4\x2E\x9E\xA4\xE2\x91\xA3\x07\xAB\x8F\x16\xA2\xA4\x18\xA1\x99\x46\xA0\x9E\xF5\x9E\xA3\x97\x95\x94\xE4\x98\xA6\xD1\x93\x10\xE8\x9F\x9C\x09\x1A\x15\x44\xA9\xA1\x21\xA2\xA5\xEF\x91\xA7\x63\xA2\x9F\x75\xA7\xA4\x23\xAF\xA4\x03\x10\x96\xDB\x12\xA3\x25\x9B\x9F\x61\xA1\x10\x72\xAB\xA4\x00\xA9\xA3\x6C\xA4\xA2\x25\x95\xA0\x81\xAF",
"\xA5\xFD\x91\xA4\x86\xA9\xA7\x79\x9D\x13\x7B\x9A\x95\x8C\xA4\x8F\x6A\xA3\xA1\x6C\xA5\xA1\xBD\x8F\xA1\x2B\xAB\xA7\x66\xA3\x13\x97\xA8\x94\x99\xAF\x97\x50\xAB\xA6\x76\xAD\xA6\xE6\x8F\x9D\x96\x96\x9C\x7E\xA2\x10\x1E\xA5\x93\x90\xAF\x89\xAE\xAF\xAA\xA7\xAE\x95\x03\x12\xA8\x82\xA1\x9F\x6F\xAB\xA5\xCB\x95\xAA\x37\x99\xAB\x37\x16\xA2\x8F\xA8\xA2\xCD\x97\xAB\x96\x94\xAC\x6F\x9E\xA5\xC8\xA1\xA9\x65\xAF\xAA\xFF\x0C\xAC\xA6\x9B\xA9\x27\xA4\xA1\xE7\x9A\xAC\x63\x92\xAC\x25\x94\xAD\x69\xA9\x10\x80\xAA\x90\xB5\xAD\xAA\xD1\xA8\xAB\xB1\xA3\x89\x51\xAC\xA7\x53\xA6\xAB\xE5\xAB\xAC\xE7\xA0\x00\xBC\xA3\xAE\x01\x1F\xAB\x7A\x99\x9A\xDC\xA2\x8F\x5D\xA0\xAE\xE9\xA3\xAA\xEB\xA4\xAE\xA2\xA2\xAD\xDE\xA7\x9F\xCE\xA8\xAD\x60\xAF\xAF\xE6\xA9\xAF\x06\x11\xAF\xCF\xAE\xA6\xBB\x86\x10\xB6\x83\x1E\xB8\x8B\x8A\xBA\x89\x8B\x09\x1F\xB0\x9A\xA5\xB1\x0D\xB1\x8A\x19\xB5\x8A\x1B\xB9\x8A\x1D\xBD\x8A\x1F\xB1\x2F\xF1\x97\x18\xAC\x83\x8C\xAC\x21\x9F\xC7\x86\xB0\x96\x97\xAF\x31\x96\x9F\xC6\xA2\xAE\x0B\xBE\xAF\x8A\xAB\xAA\x01\xBE\xA8\x30\xB4\xB0\xD0\xAA\xB2",
"\x7C\x9F\xAE\x0A\xB8\xB3\x0C\xB7\xB2\xA0\xA2\x10\xC1\x91\x8C\x05\xBF\x2C\xF1\x97\xA8\x46\xB1\xB4\x01\x13\xB4\x0E\xA8\xB0\x03\x1C\xAD\x87\x11\x9F\x82\xAC\xB2\xBA\xA2\x10\x48\xB1\x30\xF1\x98\xA5\xB2\x86\x97\x40\xBC\xA0\x3C\xA4\xB1\x06\x10\xB5\xF2\xA0\xAF\xDA\xA4\xA0\x0A\x1F\x21\x5D\xB7\xA3\x0A\x1C\x10\xED\xA6\x9D\xC6\x84\x8C\x4A\xB0\x00\x5A\xB7\x8B\x67\xB0\xB7\x5E\xB6\x10\x6C\xB2\xB1\x09\x18\xB6\x9F\xA7\xB7\x03\x19\xB7\x33\xBA\xAE\xDF\xA4\xA5\x76\xBA\xB6\x09\x12\x24\x60\xBA\xB1\x89\xBC\xB1\x8B\xBE\xB1\x8D\xB0\xB2\x8F\xB6\xB1\xA8\xAA\xB8\x7A\xBE\xB0\x1F\xB2\xB9\x55\xBE\xB8\x95\xB1\x91\x5D\x23\xB2\x1F\xB6\xB2\x7D\xB6\xB8\x06\x19\xB2\x81\xBC\xAF\x83\xB3\x10\xFA\x19\xB6\xB7\x96\x10\x73\xB0\xB1\x29\xAF\xB8\x55\xA5\xAF\xCB\x9C\xB4\x82\xBF\x0F\xB4\xB6\xBA\xFF\x0D\xA1\x79\xA6\x01\x65\xB1\xA1\x0A\x19\xBA\xA1\xBB\xBA\x03\x1D\xBA\x3B\x99\x91\xF1\x9C\xBB\x6D\xB6\xB6\x09\x10\xBC\x49\xBE\xB7\x62\xAF\xB8\x0A\x07\xB9\xD2\xB1\xB9\xD3\xBB\xB9\x8C\xB6\xBD\x9A\xB4\xB4\x96\xB4\xBD\xDC\xB8\xBD\x4E\x1D\xB9\x71\xB4\xB2\xC2\x85\xB8\xC2",
"\xB2\x10\xA4\xBD\xB4\x2E\xB9\xAD\xDD\xBA\xBD\x94\xBC\xBE\xD7\xBE\xBE\xD9\xBB\xB5\x18\xBB\xBE\xF2\xBB\xBD\xDE\xB8\xB9\xC5\xA3\xB1\xDE\xB2\xB2\xE1\xBF\xB9\xE4\xBD\xAF\x01\x17\xBE\x4D\xAE\xB4\x02\x13\x91\xE0\xBE\xBC\x5F\x1F\xB1\xD1\xBF\xB8\xF4\xA3\xB9\x02\x1D\xC0\x3A\x14\xB5\xF9\xB7\x98\xD5\xB0\xBF\x90\xB7\xBF\x15\xC5\xBF\xED\xBA\xC1\xEF\xBC\xC1\xF1\xB4\xB7\xF3\xB8\xC1\x8F\xBC\xBF\x08\xCF\xBD\x0E\xC1\x10\xA0\xBD\xBC\xA2\xB3\x10\x02\xC0\xAC\xE9\xB9\x10\xC4\xB4\x22\x59\xBF\xB1\x8C\xA2\xC1\x33\x17\xBB\xD2\xAC\x8A\x57\xB0\x1E\x38\xCF\xAA\xAC\x8D\xC2\x46\x1D\xC3\x96\x92\xC4\x63\x94\xC4\x5A\x96\xC4\x48\x98\xC4\x25\xAA\x16\xD4\x1A\xC4\x8D\xA9\xA4\xD4\x1B\xC3\xB8\xB6\xC3\x32\x12\xC5\xD2\xA4\xC5\x31\x16\xC5\xAF\xA8\xC5\xFF\x0A\xC5\x2B\xB9\x9A\x5E\xCB\xAD\xA9\x9E\xC4\x41\xCF\xAE\x61\xC7\xC3\x63\xCF\xAE\x40\xCD\x13\x64\xCC\xC6\x69\xC3\xBB\x6F\xC6\x9F\x6D\xCA\x13\x73\xC7\x13\x75\xCD\xAC\x09\x16\xC0\x6E\xC0\xC7\x04\xC9\xC0\x84\x17\xC7\xD5\xA5\xB4\xDB\x10\xC8\xA7\xB6\xB5\x4D\xCA\xC6\x87\xCC\xC7\x72\xC1\xC7\x6C\xA4\xC8\x02\xB9",
"\xC7\x89\xCF\xC2\xAC\xBF\xB1\x0B\xA7\x13\x5C\xCC\x8A\xF8\x1F\xC7\x8C\xCB\xAA\x3A\xCF\xB1\x99\xC2\x1A\x8E\xCE\xC8\x3F\xCE\xC9\x91\xCD\xC8\x9B\xC5\xBB\x98\xC5\xCA\xAB\xA1\xCA\xEF\xAF\xC9\xB2\x1C\xCA\x7D\xC0\x00\x7A\xC9\xB9\x00\x0E\xCA\x83\xC7\xCA\xB8\xBC\x8A\x31\xC4\xCB\xB6\xCC\xC3\xEF\xA5\xC9\xA4\xA8\xCB\xD2\xA2\xCA\x0A\x17\xC6\x32\x10\xCB\x92\xCC\xC2\xAA\xC5\xBB\xC8\xC6\xCA\x8A\xCE\xCC\x8B\xCF\xCC\x9C\xCC\xC4\x9A\xC2\xCD\xA8\xC0\xC5\xD5\xC9\xCC\x02\x10\xCC\x32\x1C\xC5\xCD\xC3\xCD\x78\xA9\xCD\xD0\xCC\xA6\xA3\xC2\xCE\xAB\xC2\xCC\xAF\xAF\xCD\xCC\xC8\xCE\x43\xCF\xAE\xB3\xC6\xC7\xEC\xCE\xB6\x30\xCB\xCC\xB9\xC8\xA0\x25\xC1\xAE\xEB\x96\x10\x8C\xA3\x91\xFB\xCA\x10\x19\x09\xA7\xFF\xC3\xA7\x01\x14\x24\x02\xD0\x00\x15\x09\xA7\x07\xD4\x18\xC6\xC7\x93\x0B\xD3\xA8\x0A\x1D\xCB\xF9\xC8\xBA\x79\xA8\xBF\xE5\xB8\xC2\x79\xA9\xC2\x1A\x99\x10\x0B\xC8\xA8\x06\x1F\xCE\x33\x1D\xD0\xF1\x9C\xAD\x20\xD1\xB7\xDC\xA3\x91\x7C\xB9\xA5\x7B\xB9\xA7\x27\xDB\x1D\xBB\x6C\x93\x2E\xDF\xD2\x30\xD1\xD3\x3C\x9A\xA0\xBB\x22\xC5\x2F\x9D\xBA\x38\xD8\xCD",
"\x93\xC3\xCF\x3C\xDB\xD3\x3E\xD3\xBC\x3A\xD3\x10\x88\x9B\x90\x13\x9B\xD1\x3F\xBE\x90\xEA\xB8\xD4\x40\xAB\xD4\x4A\xDD\xD4\x47\xDF\xD4\x0F\xC1\x92\x52\xDA\xAF\x54\xD9\xAA\x56\xDF\xA7\x53\xD7\xD5\x02\x18\xCF\xF8\xCF\xB0\x18\xD1\x10\x10\xDC\xBC\x02\x12\xD6\x01\x14\xD6\x00\x06\xD6\x68\xDF\xBB\x6A\xDB\xBC\x6B\xD6\x10\x66\xD5\xA5\x2D\x9D\xC2\x2B\xD1\x10\x73\xD6\xD0\x0A\x18\xBC\x06\x18\xB8\x2D\xA2\x10\x7A\xDA\xCC\x87\xB5\xB7\x7F\xD9\xD2\x81\xD6\x10\x09\xD9\xD7\x77\xDA\x10\x04\xD6\x10\x01\xDB\xD7\x01\x1B\xD8\x7E\xDA\xD8\x80\xD0\xD9\x82\xD2\xD9\x84\xDE\xCF\x87\xD9\x10\x80\xB2\x10\x63\x23\xD8\x45\xA6\x10\x9B\xD6\xD8\x09\x1D\xC2\x9F\xD3\x10\x7D\xD2\x10\x75\xD3\xDA\x7C\xD1\xD9\x03\x18\xDA\x01\x15\xDA\x01\x15\xD8\xAB\xDA\x10\xAE\xD0\x00\x78\xD1\xDB\x09\x19\xD8\x03\x15\x26\x9C\xD4\xA7\xB9\xD2\xDB\x6F\xB9\x10\xBA\xD0\xDA\x06\x15\xD7\xC1\xD4\xDA\xAA\xD2\x10\xC5\xD9\xDA\x09\x10\xDB\xC8\xDE\xDB\x09\x15\xDB\xCD\xD7\xDB\x0D\x1E\xDC\x8C\xD0\x00\x0E\x1B\xDB\x01\xC3\xDD\xD8\xD0\x00\x75\xD7\xDD\xC2\xD3\x10\xDD\xD4\xDD\x03\x1C\xDC\x01",
"\x1E\xDD\xC6\xDF\xDC\xDA\xD6\x10\xB8\xD2\x10\x1E\x0E\xD2\xD0\xD1\xD3\x4F\x08\x8A\xBA\xB9\x10\xA0\x23\xD3\x72\x27\xBB\x2D\x02\xD3\x03\x10\x05\xF2\xDB\x2B\xF9\xDA\xDF\x01\x11\x05\xFD\xD9\x10\x2F\x99\x35\x00\xE0\x00\x52\x03\xE0\x61\xBA\x10\x06\xE0\xE0\x53\x0A\xE0\x11\x94\x38\x07\xE4\x05\x10\xE2\x10\x88\x9E\x3A\x07\xE5\x05\x15\xE1\x10\x17\xE7\xE0\x00\x06\x05\x1B\xE4\xB6\x09\x19\x3B\x3C\x97\xBB\x57\x01\xE2\x0B\x9D\x3B\x25\xEA\x10\x58\x01\xE2\x35\x12\x05\x1E\xE9\x05\x2E\xEC\xE2\x1E\xEA\x05\x21\xE6\xD4\x02\x17\x49\x07\xEB\x05\x21\xEF\xAB\x9C\x47\xE0\x5C\x0D\xE3\x0A\x1F\xE3\x00\xED\x05\x33\xE9\x10\x13\x57\xE0\x5E\x01\xE2\x0F\xB6\x54\x07\xEF\x05\x21\xE2\xC5\x93\x5B\xE2\x04\x2D\xBA\xA7\x54\xE5\x4D\x23\x91\xA2\x58\xE5\x6C\x28\xCF\xA0\x5C\xE5\x77\x2F\xD5\x00\x05\x59\x60\xEA\x27\x10\xDF\x5D\x65\xE0\x00\x60\x01\xE2\xAC\x87\x5D\x07\xE1\x06\x21\xE7\xE6\x2E\xD7\xBB\x62\x0C\xE6\x0A\x1E\xE6\x00\xE3\x06\x21\xE6\xD6\xE5\x57\xE0\x64\x0B\xE7\x0A\x17\x5E\x07\xE5\x06\x80\xE9\x10\x82\xE0\xE0\x66\x01\xE2\x03\x0A\x92\x09\x1E\xC4\x1E\xEC",
"\x88\x8E\x35\x13\x82\xAF\xD2\xF3\xDA\x37\x35\x1C\xA8\x2F\xD6\xB3\x1C\x45\x13\xBB\xC7\x1C\x35\x17\xBB\xB3\xA8\x2F\x35\x18\xE3\x7A\x25\x13\x52\xC1\xEA\xFE\x26\xEA\x72\x25\x13\x2F\x98\xEA\x48\x35\x13\x1E\xD3\x1C\x9C\xE8\x5A\xAC\xEB\xEA\x0A\x18\x98\xAE\xE4\x2F\x35\x1C\xCD\xD7\x12\xE9\xB4\xEF\xD0\xB6\xE0\xC9\x21\x54\xEA\x00\x0C\xEB\xDC\x15\x13\x66\xD2\x1E\x35\x18\xCF\x9A\x8F\xB0\xC6\xEB\xEB\x9D\x45\x13\x10\xDE\xE8\x72\x2C\x8A\xB3\xDA\xEC\x5A\xAD\xBA\xEB\xD8\xAE\x04\x2C\x8A\xDB\xEB\x27\x35\x1E\xD8\xCF\xB6\x10\x83\x26\xA3\xBF\x1C\x8A\xE2\xE5\xEA\x0A\x15\x28\x3D\xD3\x10\x26\x0D\x49\xA0\xE1\xEC\x06\x18\x2B\x8D\xEE\x38\xB7\xB7\xED\xE5\x15\x13\x2A\x01\xD4\x02\x14\x30\x06\x19\xEB\xDC\x17\xBB\xDF\xE8\xED\x07\x3C\xEF\x01\x17\x35\xE6\xE3\x1C\xB7\xB9\xEE\xE0\xEC\xE0\x06\xF0\x00\x3E\x0D\x49\xA7\xE2\xEF\x03\x12\x38\xF5\xE0\x39\x52\xC8\xEF\xC5\x15\x13\x1A\x1D\xEE\x02\x14\x3B\xFF\xE2\x27\x52\xC3\xF0\xF9\xEA\x10\xB7\x3E\xF1\x01\x17\x3C\x09\xF7\x1D\x52\xCC\xF0\x04\xF6\x10\xC9\x38\xF2\x1F\xED\x49\xAD\xE4\xF1\x02\x14\x42\x17\xFA\x37",
"\x2F\x9A\xF1\x9E\xE1\x12\x0F\xF3\x4B\x2B\xFC\x1D\x2F\x94\xF2\x1B\xFA\x10\xBE\x42\xF3\x15\x51\xF4\xB5\xE9\x10\x2E\xF5\xF2\x09\x10\x52\x3F\xD2\x10\x6A\x5A\xF4\x0F\xF0\xF0\x2F\xDE\x56\xDC\x90\x39\xAD\xBC\xF3\xBF\x15\x13\x64\xE1\xF5\xD6\x5D\x49\xDA\xE6\xF3\x01\x18\xE6\x60\xF0\x00\xEB\x54\xF5\x32\xFD\xF4\x45\xF9\x10\xED\x52\xF3\x14\x6A\xF6\xFA\xC1\xED\x0A\x1D\x61\x39\xF7\x3D\x88\x9C\xF5\xB2\xEA\x10\x37\x62\xF3\x69\x62\xF7\x42\xD8\xD8\x64\xF0\x00\x78\x62\xF3\xA8\x60\xF8\x16\xE6\xD9\x04\x25\x13\xAA\x62\xF3\xB6\x68\xF8\x01\x1B\x90\x56\xFE\xD2\x9F\x00\x9D\x51\x2B\x90\x7A\xFD\xEB\x0A\x14\x6D\x32\xF3\x6F\x90\xF2\xE2\xEA\xD3\xF8\xF5\x62\xF3\x02\x7F\xF9\x0B\x9C\xF6\x3D\xF9\x10\x12\x72\xF3\x40\x7F\xF9\x13\x93\xF9\x3C\x96\x74\x77\xFC\x3E\x13\x99\xF9\xC7\xEA\x10\x58\x72\xF3\x81\x7E\xFA\x82\xFB\xF8\x0A\x13\x78\x32\xF7\x0C\x9D\x43\x91\xA8\xFD\xF5\x0A\x12\x79\x32\xFB\x7C\x9F\xF4\xEC\xB0\xF9\x91\xD3\x73\xFB\xFD\x34\xEC\xB6\xFF\xD2\xE7\x72\xF3\xFE\x7B\xFC\xBD\xFD\x24\x35\x16\x80\x32\xFA\x82\xD8\xFC\xF4\x83\xFC\x82\x32\xF2\x84\x9F",
"\xFF\xAB\x14\xDB\xF7\x04\x24\x84\x82\xCA\x27\xCC\xE3\xF8\x48\x8F\xF9\xE2\x18\xCF\xD3\xFE\xD2\x4C\x81\xCE\x06\x1C\x85\x9F\xF8\xCF\x44\xF9\xFA\x06\x1E\x85\xF6\xF3\x10\x70\x41\xFF\x4A\x7C\xED\x7A\x10\x72\x43\xFF\x62\x08\x7A\x47\xF3\x4F\x58\x7C\x6F\xF2\x2B\x26\x98\x70\x60\xFC\x7B\x95\x10\x68\x31\x7D\x00\xD3\x26\x59\x6D\x7E\x11\x4C\x0F\x70\x7F\xF2\x06\xD6\x73\x7C\x4F\x40\x44\x07\x81\x20\x09\x45\xCF\x76\xD6\x7B\x7E\xF1\x70\x09\xC5\x65\x39\x19\x44\x39\x16\xD6\x45\x7C\xFA\x66\x08\x04\x04\x12\x52\x62\x04\x0B\x02\x84\x11\x95\x58\x80\xC0\x41\x01\x35\x80\xBD\x15\xA5\x1E\x81\x46\x4A\x00\x32\x82\x18\x7B\x80\x36\x15\xA5\x26\x83\x0B\x83\x08\x0F\x01\x08\xA1\x6D\x21\x87\x27\x55\x52\x0B\x9A\x7C\x7B\x5A\x09\xAA\x6E\x26\x8A\x27\x2D\x48\x0E\x9C\x45\x19\x04\x0A\x9C\x21\x96\x4E\x03\x91\x4A\x06\x12\x82\x03\x0E\x03\x1A\x82\xF1\x0D\x92\x46\x80\x14\x84\x77\x60\x82\x20\x23\x01\x31\x85\x1E\x2D\x4B\x13\x97\x7D\xF4\x69\x0D\x81\x08\x14\x0C\x06\xC5\x0D\x0B\x75\x54\x6D\x7C\x91\x35\x6A\x6A\x7C\x93\x29\x01\x1D\x91\x80\xB2\x57\xB8\x51\x7D\xC1\x7A",
"\x02\x7F\x83\x6F\x15\x74\xE0\x6F\xD6\x43\x7D\x15\x06\x08\xC3\x0E\xA6\x75\x6B\x9D\x77\x04\x86\x08\x16\x0D\x08\xD7\x0D\xBC\x73\x6C\x03\x0C\xD8\x55\x81\x80\x0D\x02\x15\x84\x77\x13\x78\x98\x86\x90\x7E\x7D\x84\x0E\x02\x1E\x87\xD2\x61\x79\xA1\x81\x20\x31\x75\x33\x83\x10\x2F\x02\x29\x95\x7A\x82\x80\x00\x22\x5A\x9E\x40\x03\x2F\x84\x05\x61\x29\x75\x6F\xD9\x6E\x69\x18\x06\x0B\x89\x5A\x87\x00\x76\xA3\x86\x20\x32\x00\x2D\x83\x03\x14\x44\x2B\x4F\x7D\xB1\x81\xD9\x4E\x7A\x83\x05\x03\x5A\x82\x0D\x06\x86\x0A\x0C\xF9\x4A\x08\xF2\x60\xE9\x41\x87\x40\x18\x01\xBD\x84\x4D\x14\x87\x2E\x80\x8C\x39\x02\x1C\x80\x00\x3D\x01\x1B\x82\x08\x6A\x86\x06\xF0\x82\x41\x1E\x01\xDF\x82\x08\x22\x87\xD7\x63\x00\xEC\x11\x4D\x03\x02\xDF\x87\x08\x2B\x86\xDA\x63\x0D\x83\x7F\x13\x33\x6D\xB1\x5B\x19\xAB\x25\x6F\x7B\xC6\x79\x83\x2A\x2C\x78\x75\x6B\x13\xB7\x29\xCC\x61\x10\x49\x6E\xBA\x64\x10\x48\x00\x1A\x84\x10\x83\x80\x00\x2C\x6D\xC3\x67\x26\xE6\x6A\x20\x25\x76\x02\x83\xE2\x73\x86\x78\x13\x88\x03\x0C\xDD\x54\x89\x26\x1B\x04\x0A\x89\x93\x1A\x88\x03\x0E\x53",
"\x16\x87\x69\x20\x12\x82\x08\x40\x03\x89\xD9\x27\x24\x86\x08\x86\x82\x10\xE2\x0D\x13\x1E\x88\x50\x6C\xDB\x46\x08\x11\x0A\x10\x22\x8B\x46\x8B\x25\x36\x89\x0C\x83\x7D\x27\x06\x11\xE5\x0D\x7D\x73\x89\xF6\x86\x86\x10\x09\x84\x0A\x2B\x28\x88\x00\x10\x02\x5A\x81\x0A\x30\x89\x3B\x14\xEF\x06\x0B\xBB\x66\x8A\x53\x05\x27\x85\x0F\xA2\x83\xEF\x41\x88\x05\x32\x08\x09\x0A\x5A\x06\x8A\x2A\x02\x15\xC7\x0E\x56\x86\x08\xFA\x16\x28\xA2\x0F\x2A\x0B\x14\xFA\x10\xB5\x04\x8A\x83\x7F\x0A\x1A\x82\x2C\x05\x16\x80\x01\xFB\x69\x08\x67\x8E\x20\x2E\x00\xAB\x8B\x41\x7F\x6E\x41\x14\x8A\xEE\x81\x24\x1A\x83\x2D\x0D\x16\x8F\x5A\x26\x56\x8B\x03\x0B\x2E\xA2\x8A\x1B\x22\x18\x86\x0B\xBE\x66\x8A\x5D\x05\x2B\xBF\x0D\xB0\x83\x09\xF4\x88\x0D\x3E\x77\x03\x0B\x06\x03\x7C\x2F\x0A\x05\xDF\x01\x5B\x82\x0F\x32\x02\x21\x08\x18\xA3\x81\x06\x0A\x8F\x70\x12\x8C\x09\x09\x33\x83\x8C\x0A\x29\x32\x06\x08\xD4\x06\x8A\x62\x06\x33\x97\x0F\xD3\x86\x10\x3A\x02\x63\x83\x0E\x63\x07\x32\xA5\x0E\x84\x76\x10\x20\x8F\x4D\x82\x08\x65\x02\x0B\xA6\x03\xB6\x82\xE6\x1A\x44\x6D\x83",
"\x08\x39\x07\x35\x8B\x23\x06\x71\x19\x83\x7C\x1A\x1A\x82\x69\x05\x2D\x90\x68\x4D\x44\x1C\x82\x09\x70\x83\x8D\x1B\x27\x39\x8C\x87\xC1\x7B\x06\x2A\x8C\x77\x0E\x8D\x09\x0F\x37\xB7\x12\x72\x2C\x36\x06\x09\x0F\x03\x7C\x6C\x06\x3A\xB5\x09\xEF\x89\x10\x41\x02\x70\x9C\x0E\x6D\x02\x36\x85\x0F\x88\x70\xFD\x0F\x8A\x41\x0F\x03\xF3\x87\x02\x8A\x08\xF6\x8E\x0B\xC6\x88\x1C\x13\x87\x37\x83\x3E\x8A\x84\xA3\x81\x07\x73\x86\x15\x9A\x8F\x32\x7A\x20\xB2\x03\x79\x8D\xC2\x1A\x44\x7D\x99\x84\x83\x7B\x0E\x33\x87\xBA\x66\x20\xA9\x82\x51\x94\x03\xF3\x84\x1A\x8D\x90\x61\x77\x1B\x81\x09\x1D\x13\x87\xEF\x6D\x1A\xA7\x86\xAE\x55\x21\x80\x02\x1D\x13\x87\xB3\x6B\x42\xB9\x59\xBC\x89\x10\x77\x03\x3C\x9F\x76\x22\x90\x09\x83\x7C\x3C\x0A\x05\xF9\x01\x5B\x8C\x78\x29\x93\xAC\x43\x7D\x3D\x0A\x05\xFC\x01\x5B\x84\x88\x1A\x95\xE2\x4A\x09\xB7\x16\x14\xFE\x02\x78\x8A\x08\x12\x76\x20\x16\x79\x0E\x9F\x44\x66\x8D\x42\x07\x90\xDB\x8D\x98\x1D\x78\x83\x02\x3B\x46\x8B\x1F\x1A\x82\x80\x02\x3D\x87\x0E\xD6\x19\x10\x64\x8D\x87\x82\x04\xF3\x86\x21\x9A\x44\x2A\x96\x10",
"\x30\x1C\x74\x94\x21\x18\x76\x3B\x83\x7D\x41\x03\x0F\x8C\x8A\x26\x41\x93\x03\x0E\x4B\x84\x92\x1B\x2A\x26\x83\x0A\xE8\x06\x8A\x84\x07\x47\x89\x09\x26\x96\x10\x5C\x90\x89\x8C\x24\x20\x7B\x20\x00\x1E\xA3\x85\x08\x72\x92\x41\x19\x93\x02\x0B\x77\x06\x8A\x43\x0E\x27\x83\x08\x89\x76\x1D\x83\x7F\x10\x14\x44\x3E\x8C\x11\x8A\x08\x9D\x97\x93\x03\x0A\x11\x1A\x83\x45\x0D\x16\x91\x8A\x4C\x83\x08\x2A\x70\x51\x86\x8B\x46\x0B\x28\x8E\x1F\x9E\x8C\x92\x83\x78\x12\x1A\x83\x48\x0D\x16\xED\x6D\x48\x3E\x08\x09\x0C\x7C\x06\x8B\x49\x05\x28\x82\x09\xCC\x79\x7A\x1D\x94\x12\x33\x86\x8C\x81\x08\x89\x0B\xAB\x9B\x55\x83\x7D\x12\x33\x87\x92\x87\x29\xAE\x97\x7E\x9D\x90\x96\x03\x1E\xAA\x89\x50\x5B\xDF\x0F\x7A\x40\x97\x04\xF3\x84\x26\xA1\x29\x5B\x92\x10\x1A\x86\x3E\x82\x08\x98\x03\x1E\xB9\x89\x5A\x90\xF3\x0E\x91\x87\x99\x04\xF3\x87\x27\x84\x96\x5F\x94\x21\x90\x96\x40\x1A\x04\xF3\x83\x28\xA8\x85\x6A\x94\xE0\x03\x7F\x26\x13\x87\x4F\x8B\x5C\x85\x97\xF5\x7E\x1E\x83\x08\x27\x13\x87\x4D\x8B\x5B\x81\x08\x66\x90\xD6\x03\x7D\x27\x1A\x82\x9E\x05\x2D\xB8",
"\x8A\x6A\x9B\x2E\xEE\x6B\xE0\x60\x05\x5A\x81\x14\x2D\x8A\xAC\x8A\x2E\x82\x09\x14\x0A\x08\x2A\x7D\x43\xA3\x05\x56\x91\x10\x30\x71\x42\x07\x98\x5F\x93\x98\x2A\x94\x72\x9B\x26\x94\x20\xFE\x06\x08\x52\x26\x28\xA4\x04\x86\x93\xF3\x6D\x8E\x40\x85\x05\xF3\x87\x30\x85\x99\x80\x06\x41\x5F\x59\x87\x86\x05\xF3\x87\x2B\xB2\x97\x8E\x93\xF7\x46\x8B\x29\x13\x87\x71\x8B\x65\xA5\x99\xB3\x72\x10\xA8\x07\x3C\x80\x8C\xFC\x92\x20\x33\x98\x04\x96\x14\xA9\x07\x3C\x85\x8C\x32\x9E\x5A\x9E\x97\x80\x0A\x0A\x73\x84\x63\x81\x9A\xDD\x91\x49\x89\x09\x55\x03\x0F\x90\x8D\xCE\x84\x99\x1C\x93\x68\x80\x00\x56\x03\x0F\x9B\x8F\xC8\x8C\x99\xEC\x55\x43\xAD\x05\x79\x82\x1A\xD7\x9B\xCE\x82\x08\x10\x6A\x20\xAE\x04\x2D\x8F\x0A\x6D\x8A\x6D\x88\x9A\xFE\x96\x28\xB1\x04\x2D\x82\x0B\x6D\x89\x69\x8B\x99\x38\x7E\x20\x06\x20\xA3\x84\x0B\x1C\x99\x0E\x29\x08\x71\x9A\x6A\x8F\x23\x8C\x96\x10\x5F\x9B\x41\x8C\x24\x6A\x26\x20\x3C\x22\xA3\x85\x0B\x1C\x9B\xE0\x86\x08\x47\x7D\x62\x87\x0E\x5B\x02\x25\xBF\x0F\x21\x29\x95\x83\x78\x17\x33\x86\xA0\x11\x52\x0F\x9C\xC6\x83\x7C",
"\xB9\x03\x1E\xAC\x8D\x95\x96\x39\x83\x08\xD0\x6A\x9C\x34\x22\xC7\x57\x9C\xA3\x8A\x0B\x73\x86\x76\x9D\x95\x01\x0A\x74\x9E\x9D\xF3\x8C\x38\x44\x73\xEA\x91\x98\x4B\x27\x73\x83\x08\x3D\x26\x14\xBB\x04\xC7\x89\x9C\x03\x0D\x73\x8A\x9A\x46\x20\x4D\x06\x09\xD2\x7D\x90\xBC\x04\x63\xAB\x26\x8F\x9F\x2C\x81\x09\x2F\x13\x87\xCD\x88\x75\x80\x01\xE1\x95\x1F\x9D\x92\x2F\x13\x87\xD2\x8B\x65\x8C\x9F\xC0\x76\x14\xBF\x07\x3C\x98\x8E\x57\x9B\x7A\xA3\x76\xA9\x90\x0C\x73\x85\x77\x92\x9E\xD1\x83\xF0\x41\x07\x79\x8C\x23\xD9\x9E\xD0\x9B\x9D\x03\x0A\x18\x33\x86\x2B\x90\x3E\xC9\x9B\xDF\x83\x08\xC3\x03\x1E\x88\x92\xE5\x9A\x3D\x81\x0B\x2C\x99\x48\xC4\x03\x1E\x83\x93\xF6\x93\x22\xE8\x9E\x40\x05\x06\xF3\x81\x48\xBC\x9E\x15\x96\x14\xC6\x06\x16\x87\x06\x6D\x8E\x48\xA6\x9E\xB6\x66\x14\xC9\x06\x16\x8A\x06\x6D\x8B\x49\xAB\x99\x83\x29\x10\x67\x26\x51\x8C\x06\x1C\x99\xC9\x46\x08\x0A\xA0\x3A\xC3\x27\xEF\x83\x08\xF5\x9D\x5D\x93\x26\xA8\x73\x10\x28\x2A\x51\x8D\x06\x1C\x9E\x84\x86\x09\xA9\x7D\x41\xD7\x0E\x33\x0D\x9C\xC3\x0B\xA7\x09\x09\x0F\xAE\x3F\x81",
"\x08\x34\x13\x87\x6F\x97\x6A\xB2\xA0\x83\x06\x55\x30\x9D\x1B\x2E\x72\x3C\xA4\x75\x8E\x1D\x1E\xA6\x10\x23\x2A\x51\x91\x06\x1C\x9C\x85\x83\x09\x1D\xAA\x37\xB6\x20\xD6\x63\x08\x2A\x9D\x86\x80\x00\x69\x00\x43\xD7\x0E\x9D\x8F\x9A\x00\x07\x89\x82\x09\xCD\x92\x45\xD4\x05\x15\xBC\x0E\x68\x90\x8B\x9A\xA3\x80\x0F\x29\xD2\x9A\x35\x1F\xA2\x35\x0D\x4D\xA2\xA2\x85\x02\x28\x9D\x90\x36\x08\xA3\x8E\x91\x2C\x23\xA2\x00\x07\x38\xD2\x9A\x36\x10\xA3\x09\x08\x50\x8A\x9F\x39\xAA\x42\xD2\x98\x37\x18\xA3\x9A\x97\x6A\x93\x72\x83\x08\x58\x46\x8A\x37\x00\xA4\x6C\x17\xEB\x43\x09\x42\xAD\x21\xE0\x04\x22\xB7\x13\x5F\x74\x90\x83\x7C\x71\x0F\x48\xFA\x13\x96\x72\xA4\x46\x8C\x1C\x15\xA5\x3D\x17\xE5\x18\xA5\x87\x86\x07\x9B\xA2\x3C\x38\x2C\x83\x01\x45\xEF\x9E\x40\x08\x07\x9D\x94\x40\x07\x95\xAC\x93\x10\x23\xA7\x40\x1C\xA2\xA6\xA1\x20\x2B\x07\x54\xAD\x24\x19\x94\x2B\xA2\x08\xAE\xA2\x20\x25\xA2\x29\xAE\x0E\x34\xA4\x9B\x08\x95\xFD\x99\x20\x39\xA5\x80\x0D\x46\xD2\x99\x3C\x1E\xA5\x77\x14\x5E\x85\x77\x94\x0A\x10\x75\xA2\x14\xB4\x07\xC8\xA2\x4F\x0E\x99",
"\x60\xAE\x21\x8A\x09\x1F\xB2\xA2\xF7\x01\x9A\xBB\x13\x8B\x97\x4B\xC2\xA6\x42\x14\x95\xB1\xA0\x00\x3A\x07\x4D\xAE\x37\xB9\x92\x40\x18\x73\x50\xA3\xF0\x7C\x07\x4D\xA9\x37\xDB\x67\x9D\x6A\x08\xB0\xA2\x84\xA2\x81\x4D\xAC\x37\xDD\xA4\x00\x08\xA7\xBA\xA3\xF0\x4B\xA6\x6A\xA2\x1E\x34\x9C\x35\xB8\xA7\xC4\xA3\xF0\x42\x00\x54\x4A\x0B\x89\x0A\xEE\x81\x08\x6D\x75\x99\x83\x7C\x02\x04\x50\xF2\x12\xEB\x8E\xA7\x09\x08\xA0\x80\x01\x6B\xA1\x4E\x86\x01\x43\xA4\x10\xB8\x98\xA2\x86\x08\x89\xA0\x4E\xF2\xA4\xBC\x41\x71\xE2\x0E\x82\x97\x9A\xB3\x73\x10\x3E\x2E\x51\x89\x00\x20\xAC\x5F\x21\x2E\x52\xA3\xF8\x0A\x00\x2A\x4D\x68\x35\x09\x84\xB7\x5D\x95\xAF\x4A\x83\x7E\x03\x0F\xA9\x72\x14\x86\x8B\x5B\x95\x0A\x10\x3B\xA5\x38\xB2\x00\x38\xAC\x40\x14\xA8\x00\x03\x53\xEC\xA3\xE0\x76\x00\x41\xAD\x49\x04\xA3\x81\x05\x54\x89\x0A\x33\xA1\xA7\x1A\x01\xA9\xAC\x12\x46\xAC\x54\xBC\xA9\x42\x03\xAA\x02\x8E\x03\x12\xAA\x48\xAB\x2B\x34\xAA\x44\x83\x7C\x22\x00\x15\x4C\x95\x56\xAA\x9E\x7D\x72\x41\x03\x2F\x46\x8D\x04\x29\xA8\x7B\x16\x56\xE9\xA6\x51\x86\x01\x62",
"\xAA\x4E\x12\xA9\xDB\x5D\x56\xDB\xA3\xE0\x69\x01\x71\xAC\x40\x28\xAA\x58\x93\x10\x75\xA8\x19\xA3\x7C\x2C\x01\xAF\x8D\x13\xF4\x2D\x1E\xFE\xA8\x00\x05\xA6\x52\xA7\x05\x02\xAC\x36\x1F\x5E\x05\xAE\x42\xA6\x8A\x32\x03\xB1\xB6\x2F\x5D\x16\x58\xD8\xA9\xF1\x80\x00\x35\x02\xB2\xBA\x12\xBB\x7C\x57\x82\x0A\x61\xBD\xA8\x02\x88\x07\x17\xA9\x26\x1D\xF7\x54\xA7\xA1\x63\x08\x7B\xAA\x6A\xBA\x01\xB5\xA8\x2F\x27\xAE\x40\x05\xA5\x1E\xAB\x07\x1A\xAD\x3D\x12\x64\x6D\x8E\x6B\xA1\x08\xF1\xA2\x20\xBE\x01\xD9\xA2\x1E\x59\x32\x6D\xBD\xA9\x83\x79\x08\x3C\xAD\xF2\x0D\x67\x3F\xAD\x42\x08\xAC\xE1\xA4\x08\x03\xAF\xE2\x04\x6A\x46\xAE\xE0\x83\x7C\x47\x03\xB9\x87\x0F\xC6\x7D\x59\x81\x0B\x6D\xB3\xA8\x83\x7A\x09\x12\xAF\xDF\x00\x6B\x4E\xAF\x40\x00\xAD\x97\xAD\x09\x23\xAC\x36\x1F\xF8\x54\xA4\x61\xA6\x5E\xF9\x75\x24\x7E\x75\x47\x77\x0A\x99\x48\x62\x4E\x0A\xB7\x5E\x29\x2C\x44\xA7\x0C\xE8\x0F\x7A\x53\x12\x62\x4E\x0C\xD8\x79\xAF\x97\x6A\x5F\xA3\x74\x7F\xAF\x69\x13\x4E\x29\x3F\x54\xA7\x08\xCF\x04\xB3\x4B\x6F\x58\x4E\x08\xC1\xB5\x08\x05\xB9\xD4\x19\x49",
"\x81\xAB\xB0\x35\x0E\xEA\x40\x79\xDC\x59\xE9\x6C\x0E\xB1\x6F\x64\x3C\x4B\xBE\x90\x76\x97\x6A\x61\xEA\x4E\x7C\xAF\x69\x8E\x74\x8C\x71\xAF\x4F\x7F\xD2\x30\xA8\x48\x78\xAF\xAA\x76\xA5\x68\xB1\xF3\x90\x8C\x2B\xB1\xB9\x86\x0C\xF7\x57\x25\x4E\x0A\x19\xB3\xEB\x06\x0D\x24\x93\x09\xAD\x5E\x29\x39\xB1\x1A\xBC\x93\x3B\xB2\x7D\xB7\x74\xEC\x09\x53\x6F\xAE\x20\xBE\xD2\x43\xB3\xAF\x8E\xAF\x2F\x6B\xD2\x7D\x55\x85\x4E\x14\x4C\xB3\x7A\xBC\x49\x4E\xB4\x9A\x51\x0F\x55\x8C\x9B\x0B\x44\x32\x92\xB2\x19\x49\xC0\xBE\xAE\xC3\x0E\x2C\xBD\x09\x7F\xA1\x9F\x2E\x6F\xCB\x9A\x69\x97\x60\x01\xB8\x09\x99\xB3\x09\x03\xB5\x26\x29\xB3\x06\xB1\x91\x6B\xB1\x55\x69\x0F\x0C\x86\x28\x0F\xB1\xAC\x6E\x60\xAF\x6B\x9C\xAF\xB3\x11\x4F\xCE\xB6\x5F\xF4\x07\xFE\x32\x08\x83\xA1\x61\x19\x4F\xCF\xBB\xB3\x88\x44\x01\xC9\x09\xA1\xBD\x09\x62\x76\x29\x09\xB5\x9A\x0B\x68\xE3\x5E\x4B\x6D\xB4\xF7\x0C\x3D\x21\x9A\xA3\x00\xD1\x4E\x08\x44\x78\xAF\xD3\x72\xDA\x5E\xB1\xE5\x88\xEC\x6C\x0E\x32\x9D\x09\x66\x6E\x29\x21\xB5\x9A\x09\x0F\xC0\x09\xA9\xBA\x09\x55\x56\x29\x29\xB5\x97",
"\x60",
};
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]< NAME @ \"[\" \".\" NAME \"]\" >",
L"[16][RType]< NAME @ >",
L"[17][RType]< RType \"?\" @ >",
L"[18][RType]< RType \"[\" \"]\" @ >",
L"[19][RType]< RType \"[\" @ \"]\" >",
L"[20][RType]< RType \"[\" @ RType \"]\" >",
L"[21][RType]< RType \"[\" RType \"]\" @ >",
L"[22][RType]< RType \"[\" RType @ \"]\" >",
L"[23][RType]< RType @ \"?\" >",
L"[24][RType]< RType @ \"[\" \"]\" >",
L"[25][RType]< RType @ \"[\" RType \"]\" >",
L"[26][RAttributeParameter] BEGIN ",
L"[27][RAttributeParameter] END [ENDING]",
L"[28][RAttributeParameter]CPP_NAME @",
L"[29][RAttribute] BEGIN ",
L"[30][RAttribute] END [ENDING]",
L"[31][RAttribute]< \"[\" @ ATT_NAME [ \"(\" RAttributeParameter \")\" ] \"]\" >",
L"[32][RAttribute]< \"[\" ATT_NAME @ [ \"(\" RAttributeParameter \")\" ] \"]\" >",
L"[33][RAttribute]< \"[\" ATT_NAME [ \"(\" @ RAttributeParameter \")\" ] \"]\" >",
L"[34][RAttribute]< \"[\" ATT_NAME [ \"(\" RAttributeParameter \")\" @ ] \"]\" >",
L"[35][RAttribute]< \"[\" ATT_NAME [ \"(\" RAttributeParameter \")\" ] \"]\" @ >",
L"[36][RAttribute]< \"[\" ATT_NAME [ \"(\" RAttributeParameter @ \")\" ] \"]\" >",
L"[37][REnumMember] BEGIN ",
L"[38][REnumMember] END [ENDING]",
L"[39][REnumMember]< NAME \",\" @ >",
L"[40][REnumMember]< NAME @ \",\" >",
L"[41][REnum] BEGIN ",
L"[42][REnum] END [ENDING]",
L"[43][REnum]< \"enum\" @ NAME \"{\" { REnumMember } \"}\" >",
L"[44][REnum]< \"enum\" NAME \"{\" @ { REnumMember } \"}\" >",
L"[45][REnum]< \"enum\" NAME \"{\" { REnumMember @ } \"}\" >",
L"[46][REnum]< \"enum\" NAME \"{\" { REnumMember } \"}\" @ >",
L"[47][REnum]< \"enum\" NAME @ \"{\" { REnumMember } \"}\" >",
L"[48][RUnionMember] BEGIN ",
L"[49][RUnionMember] END [ENDING]",
L"[50][RUnionMember]< NAME \",\" @ >",
L"[51][RUnionMember]< NAME @ \",\" >",
L"[52][RUnion] BEGIN ",
L"[53][RUnion] END [ENDING]",
L"[54][RUnion]< \"union\" @ NAME \"{\" { RUnionMember } \"}\" >",
L"[55][RUnion]< \"union\" NAME \"{\" @ { RUnionMember } \"}\" >",
L"[56][RUnion]< \"union\" NAME \"{\" { RUnionMember @ } \"}\" >",
L"[57][RUnion]< \"union\" NAME \"{\" { RUnionMember } \"}\" @ >",
L"[58][RUnion]< \"union\" NAME @ \"{\" { RUnionMember } \"}\" >",
L"[59][RStructMember] BEGIN ",
L"[60][RStructMember] END [ENDING]",
L"[61][RStructMember]< \"var\" @ NAME \":\" RType \";\" >",
L"[62][RStructMember]< \"var\" NAME \":\" @ RType \";\" >",
L"[63][RStructMember]< \"var\" NAME \":\" RType \";\" @ >",
L"[64][RStructMember]< \"var\" NAME \":\" RType @ \";\" >",
L"[65][RStructMember]< \"var\" NAME @ \":\" RType \";\" >",
L"[66][RStructBody] BEGIN ",
L"[67][RStructBody] END [ENDING]",
L"[68][RStructBody]< NAME \"{\" @ { RStructMember } \"}\" >",
L"[69][RStructBody]< NAME \"{\" { RStructMember @ } \"}\" >",
L"[70][RStructBody]< NAME \"{\" { RStructMember } \"}\" @ >",
L"[71][RStructBody]< NAME @ \"{\" { RStructMember } \"}\" >",
L"[72][RStruct] BEGIN ",
L"[73][RStruct] END [ENDING]",
L"[74][RStruct]<< \"class\" !RStructBody @ >>",
L"[75][RStruct]<< \"class\" @ !RStructBody >>",
L"[76][RStruct]<< \"struct\" !RStructBody @ >>",
L"[77][RStruct]<< \"struct\" @ !RStructBody >>",
L"[78][RMessageRequest] BEGIN ",
L"[79][RMessageRequest] END [ENDING]",
L"[80][RMessageRequest]< \"request\" \":\" @ RType \";\" >",
L"[81][RMessageRequest]< \"request\" \":\" RType \";\" @ >",
L"[82][RMessageRequest]< \"request\" \":\" RType @ \";\" >",
L"[83][RMessageRequest]< \"request\" @ \":\" RType \";\" >",
L"[84][RMessageResponse] BEGIN ",
L"[85][RMessageResponse] END [ENDING]",
L"[86][RMessageResponse]< \"response\" \":\" @ RType \";\" >",
L"[87][RMessageResponse]< \"response\" \":\" RType \";\" @ >",
L"[88][RMessageResponse]< \"response\" \":\" RType @ \";\" >",
L"[89][RMessageResponse]< \"response\" @ \":\" RType \";\" >",
L"[90][RMessage] BEGIN ",
L"[91][RMessage] END [ENDING]",
L"[92][RMessage]< \"message\" @ NAME \"{\" [ RMessageRequest ] [ RMessageResponse ] \"}\" >",
L"[93][RMessage]< \"message\" NAME \"{\" @ [ RMessageRequest ] [ RMessageResponse ] \"}\" >",
L"[94][RMessage]< \"message\" NAME \"{\" [ RMessageRequest @ ] [ RMessageResponse ] \"}\" >",
L"[95][RMessage]< \"message\" NAME \"{\" [ RMessageRequest ] [ RMessageResponse @ ] \"}\" >",
L"[96][RMessage]< \"message\" NAME \"{\" [ RMessageRequest ] [ RMessageResponse ] \"}\" @ >",
L"[97][RMessage]< \"message\" NAME @ \"{\" [ RMessageRequest ] [ RMessageResponse ] \"}\" >",
L"[98][REventRequest] BEGIN ",
L"[99][REventRequest] END [ENDING]",
L"[100][REventRequest]< \"request\" \":\" @ RType \";\" >",
L"[101][REventRequest]< \"request\" \":\" RType \";\" @ >",
L"[102][REventRequest]< \"request\" \":\" RType @ \";\" >",
L"[103][REventRequest]< \"request\" @ \":\" RType \";\" >",
L"[104][REvent] BEGIN ",
L"[105][REvent] END [ENDING]",
L"[106][REvent]< \"event\" @ NAME \"{\" [ REventRequest ] \"}\" >",
L"[107][REvent]< \"event\" NAME \"{\" @ [ REventRequest ] \"}\" >",
L"[108][REvent]< \"event\" NAME \"{\" [ REventRequest @ ] \"}\" >",
L"[109][REvent]< \"event\" NAME \"{\" [ REventRequest ] \"}\" @ >",
L"[110][REvent]< \"event\" NAME @ \"{\" [ REventRequest ] \"}\" >",
L"[111][RDeclDetail] BEGIN ",
L"[112][RDeclDetail] END [ENDING]",
L"[113][RDeclDetail]<< !REnum @ >>",
L"[114][RDeclDetail]<< !REvent @ >>",
L"[115][RDeclDetail]<< !RMessage @ >>",
L"[116][RDeclDetail]<< !RStruct @ >>",
L"[117][RDeclDetail]<< !RUnion @ >>",
L"[118][RDecl] BEGIN ",
L"[119][RDecl] END [ENDING]",
L"[120][RDecl]<< { RAttribute @ } !RDeclDetail >>",
L"[121][RDecl]<< { RAttribute } !RDeclDetail @ >>",
L"[122][Schema] BEGIN ",
L"[123][Schema] END [ENDING]",
L"[124][Schema]< RDecl @ { RDecl } >",
L"[125][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);
}
}
}