From 14ec85881d16eb6e41cf3abff2f05d11763a5eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=85=E6=88=8E=E6=B0=8F?= Date: Wed, 6 Sep 2017 23:45:09 +0800 Subject: [PATCH] feat(config): references to optional config resources, ending with "?" --- data/test/config_compiler_test.yaml | 8 ++++++++ src/rime/config/config_compiler.cc | 26 +++++++++++++++++--------- src/rime/config/config_compiler.h | 1 + test/config_compiler_test.cc | 9 ++++++++- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/data/test/config_compiler_test.yaml b/data/test/config_compiler_test.yaml index 408f67224..d28fe029c 100644 --- a/data/test/config_compiler_test.yaml +++ b/data/test/config_compiler_test.yaml @@ -52,6 +52,14 @@ dependency_priorities: player: bisu __include: /starcraft/protoss +optional_reference: + __include: nonexistent.yaml:/? + __patch: + - local/nonexistent_patch? + - config_test:/nonexistent_patch? + - nonexistent:/patch? + untouched: true + local: patch: battlefields/@next: match point diff --git a/src/rime/config/config_compiler.cc b/src/rime/config/config_compiler.cc index 7da6df19d..7dce33783 100644 --- a/src/rime/config/config_compiler.cc +++ b/src/rime/config/config_compiler.cc @@ -46,7 +46,7 @@ struct PendingChild : Dependency { }; string Reference::repr() const { - return resource_id + ":" + local_path; + return resource_id + ":" + local_path + (optional ? " " : ""); } template @@ -131,7 +131,7 @@ bool IncludeReference::Resolve(ConfigCompiler* compiler) { DLOG(INFO) << "IncludeReference::Resolve(reference = " << reference << ")"; auto item = ResolveReference(compiler, reference); if (!item) { - return false; + return reference.optional; } *target = item; return true; @@ -141,7 +141,7 @@ bool PatchReference::Resolve(ConfigCompiler* compiler) { DLOG(INFO) << "PatchReference::Resolve(reference = " << reference << ")"; auto item = ResolveReference(compiler, reference); if (!item) { - return false; + return reference.optional; } if (!Is(item)) { LOG(ERROR) << "invalid patch at " << reference; @@ -227,14 +227,18 @@ ConfigCompiler::~ConfigCompiler() { } Reference ConfigCompiler::CreateReference(const string& qualified_path) { + auto end = qualified_path.find_last_of("?"); + bool optional = end != string::npos; auto separator = qualified_path.find_first_of(":"); string resource_id = resource_resolver_->ToResourceId( (separator == string::npos || separator == 0) ? - graph_->current_resource_id() : qualified_path.substr(0, separator)); + graph_->current_resource_id() : + qualified_path.substr(0, separator)); string local_path = (separator == string::npos) ? - qualified_path : - qualified_path.substr(separator + 1); - return Reference{resource_id, local_path}; + qualified_path.substr(0, end) : + qualified_path.substr(separator + 1, + optional ? end - separator - 1 : end); + return Reference{resource_id, local_path, optional}; } void ConfigCompiler::AddDependency(an dependency) { @@ -354,10 +358,14 @@ static an ResolveReference(ConfigCompiler* compiler, const Reference& reference) { auto resource = compiler->GetCompiledResource(reference.resource_id); if (!resource) { - LOG(INFO) << "resource not loaded, compiling: " << reference.resource_id; + DLOG(INFO) << "resource not loaded, compiling: " << reference.resource_id; resource = compiler->Compile(reference.resource_id); if (!resource->loaded) { - LOG(ERROR) << "resource could not be loaded: " << reference.resource_id; + if (reference.optional) { + LOG(INFO) << "optional resource not loaded: " << reference.resource_id; + } else { + LOG(ERROR) << "resource could not be loaded: " << reference.resource_id; + } return nullptr; } } diff --git a/src/rime/config/config_compiler.h b/src/rime/config/config_compiler.h index 9e92ea296..efeb0fe9e 100644 --- a/src/rime/config/config_compiler.h +++ b/src/rime/config/config_compiler.h @@ -30,6 +30,7 @@ struct ConfigResource : ConfigItemRef { struct Reference { string resource_id; string local_path; + bool optional; string repr() const; }; diff --git a/test/config_compiler_test.cc b/test/config_compiler_test.cc index 69990ddbd..533d53b1b 100644 --- a/test/config_compiler_test.cc +++ b/test/config_compiler_test.cc @@ -129,4 +129,11 @@ TEST_F(RimeConfigCompilerTest, DependencyPriorities) { EXPECT_EQ("bisu", player); } -// TODO: test failure cases +TEST_F(RimeConfigCompilerTest, OptionalReference) { + const string& prefix = "optional_reference/"; + EXPECT_TRUE(config_->IsNull(prefix + "__include")); + EXPECT_TRUE(config_->IsNull(prefix + "__patch")); + bool untouched; + EXPECT_TRUE(config_->GetBool(prefix + "untouched", &untouched)); + EXPECT_TRUE(untouched); +}