Implement XCUI markup import loader support
This commit is contained in:
167
engine/src/Resources/UI/UIDocumentLoaders.cpp
Normal file
167
engine/src/Resources/UI/UIDocumentLoaders.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
#include <XCEngine/Resources/UI/UIDocumentLoaders.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
|
||||
namespace {
|
||||
|
||||
Containers::String GetPathExtension(const Containers::String& path) {
|
||||
const std::filesystem::path fsPath(path.CStr());
|
||||
const std::string extension = fsPath.has_extension()
|
||||
? fsPath.extension().generic_string()
|
||||
: std::string();
|
||||
if (!extension.empty() && extension.front() == '.') {
|
||||
return Containers::String(extension.substr(1).c_str());
|
||||
}
|
||||
return Containers::String(extension.c_str());
|
||||
}
|
||||
|
||||
Containers::Array<Containers::String> BuildSingleExtensionList(
|
||||
const char* sourceExtension,
|
||||
const char* artifactExtension) {
|
||||
Containers::Array<Containers::String> extensions;
|
||||
extensions.PushBack(sourceExtension);
|
||||
extensions.PushBack(artifactExtension);
|
||||
return extensions;
|
||||
}
|
||||
|
||||
bool MatchesAnyExtension(
|
||||
const Containers::String& path,
|
||||
const char* sourceExtension,
|
||||
const char* artifactExtension) {
|
||||
const Containers::String extension = GetPathExtension(path).ToLower();
|
||||
return extension == sourceExtension || extension == artifactExtension;
|
||||
}
|
||||
|
||||
Containers::String BuildDocumentDisplayName(
|
||||
const Containers::String& path,
|
||||
const UIDocumentModel& document) {
|
||||
if (!document.displayName.Empty()) {
|
||||
return document.displayName;
|
||||
}
|
||||
|
||||
const std::filesystem::path fsPath(path.CStr());
|
||||
const std::string stem = fsPath.stem().generic_string();
|
||||
return stem.empty() ? path : Containers::String(stem.c_str());
|
||||
}
|
||||
|
||||
template <typename TDocumentResource>
|
||||
LoadResult BuildDocumentLoadResult(
|
||||
const Containers::String& path,
|
||||
UIDocumentCompileResult& compileResult) {
|
||||
if (!compileResult.succeeded || !compileResult.document.valid) {
|
||||
return LoadResult(compileResult.errorMessage);
|
||||
}
|
||||
|
||||
auto* resource = new TDocumentResource();
|
||||
IResource::ConstructParams params = {};
|
||||
params.name = BuildDocumentDisplayName(path, compileResult.document);
|
||||
params.path = compileResult.document.sourcePath.Empty() ? path : compileResult.document.sourcePath;
|
||||
params.guid = ResourceGUID::Generate(params.path);
|
||||
resource->Initialize(params);
|
||||
resource->SetDocumentModel(std::move(compileResult.document));
|
||||
return LoadResult(resource);
|
||||
}
|
||||
|
||||
bool LoadDocumentWithKind(
|
||||
const Containers::String& path,
|
||||
UIDocumentKind kind,
|
||||
const char* artifactExtension,
|
||||
UIDocumentCompileResult& compileResult) {
|
||||
const Containers::String extension = GetPathExtension(path).ToLower();
|
||||
if (extension == artifactExtension) {
|
||||
if (!LoadUIDocumentArtifact(path, kind, compileResult)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CompileUIDocument(
|
||||
UIDocumentCompileRequest{kind, path, GetUIDocumentDefaultRootTag(kind)},
|
||||
compileResult)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Containers::Array<Containers::String> UIViewLoader::GetSupportedExtensions() const {
|
||||
return BuildSingleExtensionList("xcui", "xcuiasset");
|
||||
}
|
||||
|
||||
bool UIViewLoader::CanLoad(const Containers::String& path) const {
|
||||
return MatchesAnyExtension(path, "xcui", "xcuiasset");
|
||||
}
|
||||
|
||||
bool UIViewLoader::CompileDocument(const Containers::String& path, UIDocumentCompileResult& outResult) const {
|
||||
return CompileUIDocument(
|
||||
UIDocumentCompileRequest{UIDocumentKind::View, path, GetUIDocumentDefaultRootTag(UIDocumentKind::View)},
|
||||
outResult);
|
||||
}
|
||||
|
||||
LoadResult UIViewLoader::Load(const Containers::String& path, const ImportSettings* settings) {
|
||||
(void)settings;
|
||||
|
||||
UIDocumentCompileResult compileResult = {};
|
||||
if (!LoadDocumentWithKind(path, UIDocumentKind::View, "xcuiasset", compileResult)) {
|
||||
return LoadResult(compileResult.errorMessage);
|
||||
}
|
||||
|
||||
return BuildDocumentLoadResult<UIView>(path, compileResult);
|
||||
}
|
||||
|
||||
Containers::Array<Containers::String> UIThemeLoader::GetSupportedExtensions() const {
|
||||
return BuildSingleExtensionList("xctheme", "xcthemeasset");
|
||||
}
|
||||
|
||||
bool UIThemeLoader::CanLoad(const Containers::String& path) const {
|
||||
return MatchesAnyExtension(path, "xctheme", "xcthemeasset");
|
||||
}
|
||||
|
||||
bool UIThemeLoader::CompileDocument(const Containers::String& path, UIDocumentCompileResult& outResult) const {
|
||||
return CompileUIDocument(
|
||||
UIDocumentCompileRequest{UIDocumentKind::Theme, path, GetUIDocumentDefaultRootTag(UIDocumentKind::Theme)},
|
||||
outResult);
|
||||
}
|
||||
|
||||
LoadResult UIThemeLoader::Load(const Containers::String& path, const ImportSettings* settings) {
|
||||
(void)settings;
|
||||
|
||||
UIDocumentCompileResult compileResult = {};
|
||||
if (!LoadDocumentWithKind(path, UIDocumentKind::Theme, "xcthemeasset", compileResult)) {
|
||||
return LoadResult(compileResult.errorMessage);
|
||||
}
|
||||
|
||||
return BuildDocumentLoadResult<UITheme>(path, compileResult);
|
||||
}
|
||||
|
||||
Containers::Array<Containers::String> UISchemaLoader::GetSupportedExtensions() const {
|
||||
return BuildSingleExtensionList("xcschema", "xcschemaasset");
|
||||
}
|
||||
|
||||
bool UISchemaLoader::CanLoad(const Containers::String& path) const {
|
||||
return MatchesAnyExtension(path, "xcschema", "xcschemaasset");
|
||||
}
|
||||
|
||||
bool UISchemaLoader::CompileDocument(const Containers::String& path, UIDocumentCompileResult& outResult) const {
|
||||
return CompileUIDocument(
|
||||
UIDocumentCompileRequest{UIDocumentKind::Schema, path, GetUIDocumentDefaultRootTag(UIDocumentKind::Schema)},
|
||||
outResult);
|
||||
}
|
||||
|
||||
LoadResult UISchemaLoader::Load(const Containers::String& path, const ImportSettings* settings) {
|
||||
(void)settings;
|
||||
|
||||
UIDocumentCompileResult compileResult = {};
|
||||
if (!LoadDocumentWithKind(path, UIDocumentKind::Schema, "xcschemaasset", compileResult)) {
|
||||
return LoadResult(compileResult.errorMessage);
|
||||
}
|
||||
|
||||
return BuildDocumentLoadResult<UISchema>(path, compileResult);
|
||||
}
|
||||
|
||||
} // namespace Resources
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user