Skip to content

Commit 9e9493b

Browse files
committed
feat(config): separate out config_builder and user_config components
1 parent 45a7337 commit 9e9493b

10 files changed

+122
-49
lines changed

src/rime/config/config_component.cc

+40-22
Original file line numberDiff line numberDiff line change
@@ -143,25 +143,51 @@ void Config::SetItem(an<ConfigItem> item) {
143143
set_modified();
144144
}
145145

146-
static const ResourceType kConfigResourceType = {
146+
const ResourceType ConfigComponentBase::kConfigResourceType = {
147147
"config",
148148
"",
149149
".yaml",
150150
};
151151

152-
ConfigComponent::ConfigComponent()
152+
ConfigComponentBase::ConfigComponentBase(const ResourceType& resource_type)
153153
: resource_resolver_(
154-
Service::instance().CreateResourceResolver(kConfigResourceType)) {
154+
Service::instance().CreateResourceResolver(resource_type)) {
155155
}
156156

157-
ConfigComponent::~ConfigComponent() {
157+
ConfigComponentBase::~ConfigComponentBase() {
158158
}
159159

160-
Config* ConfigComponent::Create(const string& file_name) {
160+
Config* ConfigComponentBase::Create(const string& file_name) {
161161
return new Config(GetConfigData(file_name));
162162
}
163163

164-
void ConfigComponent::InstallPlugin(ConfigCompilerPlugin* plugin) {
164+
an<ConfigData> ConfigComponentBase::GetConfigData(const string& file_name) {
165+
auto config_id = resource_resolver_->ToResourceId(file_name);
166+
// keep a weak reference to the shared config data in the component
167+
weak<ConfigData>& wp(cache_[config_id]);
168+
if (wp.expired()) { // create a new copy and load it
169+
auto data = LoadConfig(config_id);
170+
wp = data;
171+
return data;
172+
}
173+
// obtain the shared copy
174+
return wp.lock();
175+
}
176+
177+
an<ConfigData> ConfigLoader::LoadConfig(ResourceResolver* resource_resolver,
178+
const string& config_id) {
179+
auto data = New<ConfigData>();
180+
data->LoadFromFile(
181+
resource_resolver->ResolvePath(config_id).string(), nullptr);
182+
data->set_auto_save(auto_save_);
183+
return data;
184+
}
185+
186+
ConfigBuilder::ConfigBuilder() {}
187+
188+
ConfigBuilder::~ConfigBuilder() {}
189+
190+
void ConfigBuilder::InstallPlugin(ConfigCompilerPlugin* plugin) {
165191
plugins_.push_back(the<ConfigCompilerPlugin>(plugin));
166192
}
167193

@@ -182,7 +208,6 @@ struct MultiplePlugins : ConfigCompilerPlugin {
182208
return ReviewedByAll(&ConfigCompilerPlugin::ReviewLinkOutput,
183209
compiler, resource);
184210
}
185-
186211
typedef bool (ConfigCompilerPlugin::*Reviewer)(ConfigCompiler* compiler,
187212
an<ConfigResource> resource);
188213
bool ReviewedByAll(Reviewer reviewer,
@@ -201,22 +226,15 @@ bool MultiplePlugins<Container>::ReviewedByAll(Reviewer reviewer,
201226
return true;
202227
}
203228

204-
an<ConfigData> ConfigComponent::GetConfigData(const string& file_name) {
205-
auto config_id = resource_resolver_->ToResourceId(file_name);
206-
// keep a weak reference to the shared config data in the component
207-
weak<ConfigData>& wp(cache_[config_id]);
208-
if (wp.expired()) { // create a new copy and load it
209-
MultiplePlugins<decltype(plugins_)> multiple_plugins(plugins_);
210-
ConfigCompiler compiler(resource_resolver_.get(), &multiple_plugins);
211-
auto resource = compiler.Compile(file_name);
212-
if (resource->loaded && !compiler.Link(resource)) {
213-
LOG(ERROR) << "error loading config from: " << file_name;
214-
}
215-
wp = resource->data;
216-
return resource->data;
229+
an<ConfigData> ConfigBuilder::LoadConfig(ResourceResolver* resource_resolver,
230+
const string& config_id) {
231+
MultiplePlugins<decltype(plugins_)> multiple_plugins(plugins_);
232+
ConfigCompiler compiler(resource_resolver, &multiple_plugins);
233+
auto resource = compiler.Compile(config_id);
234+
if (resource->loaded && !compiler.Link(resource)) {
235+
LOG(ERROR) << "error building config: " << config_id;
217236
}
218-
// obtain the shared copy
219-
return wp.lock();
237+
return resource->data;
220238
}
221239

222240
} // namespace rime

src/rime/config/config_component.h

+47-9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <rime/common.h>
1313
#include <rime/component.h>
1414
#include <rime/config/config_types.h>
15+
#include <rime/resource.h>
1516

1617
namespace rime {
1718

@@ -65,21 +66,58 @@ class Config : public Class<Config, const string&>, public ConfigItemRef {
6566

6667
class ConfigCompiler;
6768
class ConfigCompilerPlugin;
68-
class ResourceResolver;
6969
struct ConfigResource;
7070

71-
class ConfigComponent : public Config::Component {
71+
class ConfigComponentBase : public Config::Component {
7272
public:
73-
RIME_API ConfigComponent();
74-
~ConfigComponent();
75-
Config* Create(const string& file_name);
76-
void InstallPlugin(ConfigCompilerPlugin *plugin);
77-
bool ApplyPlugins(ConfigCompiler* compiler, an<ConfigResource> resource);
73+
RIME_API static const ResourceType kConfigResourceType;
74+
RIME_API ConfigComponentBase(const ResourceType& resource_type);
75+
RIME_API ~ConfigComponentBase();
76+
RIME_API Config* Create(const string& file_name);
77+
78+
protected:
79+
virtual an<ConfigData> LoadConfig(const string& config_id) = 0;
80+
the<ResourceResolver> resource_resolver_;
7881

79-
private:
82+
private:
8083
an<ConfigData> GetConfigData(const string& file_name);
8184
map<string, weak<ConfigData>> cache_;
82-
the<ResourceResolver> resource_resolver_;
85+
};
86+
87+
template <class Loader>
88+
class ConfigComponent : public ConfigComponentBase {
89+
public:
90+
ConfigComponent(const ResourceType& resource_type = kConfigResourceType)
91+
: ConfigComponentBase(resource_type) {}
92+
ConfigComponent(function<void (Loader* loader)> setup)
93+
: ConfigComponentBase(kConfigResourceType) {
94+
setup(&loader_);
95+
}
96+
private:
97+
an<ConfigData> LoadConfig(const string& config_id) override {
98+
return loader_.LoadConfig(resource_resolver_.get(), config_id);
99+
}
100+
Loader loader_;
101+
};
102+
103+
class ConfigLoader {
104+
public:
105+
RIME_API an<ConfigData> LoadConfig(ResourceResolver* resource_resolver,
106+
const string& config_id);
107+
void set_auto_save(bool auto_save) { auto_save_ = auto_save; }
108+
private:
109+
bool auto_save_ = false;
110+
};
111+
112+
class ConfigBuilder {
113+
public:
114+
RIME_API ConfigBuilder();
115+
RIME_API virtual ~ConfigBuilder();
116+
RIME_API an<ConfigData> LoadConfig(ResourceResolver* resource_resolver,
117+
const string& config_id);
118+
void InstallPlugin(ConfigCompilerPlugin *plugin);
119+
bool ApplyPlugins(ConfigCompiler* compiler, an<ConfigResource> resource);
120+
private:
83121
vector<the<ConfigCompilerPlugin>> plugins_;
84122
};
85123

src/rime/config/config_data.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
namespace rime {
1717

1818
ConfigData::~ConfigData() {
19-
if (modified_ && !file_name_.empty())
19+
if (auto_save_ && modified_ && !file_name_.empty())
2020
SaveToFile(file_name_);
2121
}
2222

src/rime/config/config_data.h

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ConfigData {
3737
const string& file_name() const { return file_name_; }
3838
bool modified() const { return modified_; }
3939
void set_modified() { modified_ = true; }
40+
void set_auto_save(bool auto_save) { auto_save_ = auto_save; }
4041

4142
an<ConfigItem> root;
4243

@@ -51,6 +52,7 @@ class ConfigData {
5152

5253
string file_name_;
5354
bool modified_ = false;
55+
bool auto_save_ = false;
5456
};
5557

5658
} // namespace rime

src/rime/core_module.cc

+20-8
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,26 @@ static void rime_core_initialize() {
2020
LOG(INFO) << "registering core components.";
2121
Registry& r = Registry::instance();
2222

23-
auto config = new ConfigComponent;
24-
config->InstallPlugin(new AutoPatchConfigPlugin);
25-
config->InstallPlugin(new DefaultConfigPlugin);
26-
config->InstallPlugin(new LegacyPresetConfigPlugin);
27-
config->InstallPlugin(new LegacyDictionaryConfigPlugin);
28-
config->InstallPlugin(new BuildInfoPlugin);
29-
r.Register("config", config);
30-
r.Register("schema", new SchemaComponent(config));
23+
auto config_builder = new ConfigComponent<ConfigBuilder>(
24+
[](ConfigBuilder* builder) {
25+
builder->InstallPlugin(new AutoPatchConfigPlugin);
26+
builder->InstallPlugin(new DefaultConfigPlugin);
27+
builder->InstallPlugin(new LegacyPresetConfigPlugin);
28+
builder->InstallPlugin(new LegacyDictionaryConfigPlugin);
29+
builder->InstallPlugin(new BuildInfoPlugin);
30+
});
31+
r.Register("config_builder", config_builder);
32+
33+
//auto config_loader =
34+
// new ConfigComponent<ConfigLoader>({"config", "build/", ".yaml"});
35+
r.Register("config", config_builder);
36+
r.Register("schema", new SchemaComponent(config_builder));
37+
38+
auto user_config = new ConfigComponent<ConfigLoader>(
39+
[](ConfigLoader* loader) {
40+
loader->set_auto_save(true);
41+
});
42+
r.Register("user_config", user_config);
3143
}
3244

3345
static void rime_core_finalize() {

src/rime/lever/deployment_tasks.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ bool DetectModifications::Run(Deployer* deployer) {
6666
// TODO: store as 64-bit number to avoid the year 2038 problem
6767
int last_build_time = 0;
6868
{
69-
the<Config> user_config(Config::Require("config")->Create("user"));
69+
the<Config> user_config(Config::Require("user_config")->Create("user"));
7070
user_config->GetInt("var/last_build_time", &last_build_time);
7171
}
7272
if (last_modified > (time_t)last_build_time) {
@@ -235,7 +235,7 @@ bool WorkspaceUpdate::Run(Deployer* deployer) {
235235
LOG(INFO) << "finished updating schemas: "
236236
<< success << " success, " << failure << " failure.";
237237

238-
the<Config> user_config(Config::Require("config")->Create("user"));
238+
the<Config> user_config(Config::Require("user_config")->Create("user"));
239239
// TODO: store as 64-bit number to avoid the year 2038 problem
240240
user_config->SetInt("var/last_build_time", (int)time(NULL));
241241

src/rime/schema.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ class Schema {
4242

4343
class SchemaComponent : public Config::Component {
4444
public:
45-
SchemaComponent(ConfigComponent* config_component)
45+
SchemaComponent(Config::Component* config_component)
4646
: config_component_(config_component) {
4747
}
4848
// NOTE: creates `Config` for the schema
4949
Config* Create(const string& schema_id) override;
5050
private:
51-
// we do not own the ConfigComponent, do not try to deallocate it
51+
// we do not own the config component, do not try to deallocate it
5252
// also be careful that there is no guarantee it will outlive us
53-
ConfigComponent* config_component_;
53+
Config::Component* config_component_;
5454
};
5555

5656
} // namespace rime

src/rime/switcher.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Switcher::Switcher(const Ticket& ticket) : Processor(ticket) {
2727
context_->select_notifier().connect(
2828
[this](Context* ctx) { OnSelect(ctx); });
2929

30-
user_config_.reset(Config::Require("config")->Create("user"));
30+
user_config_.reset(Config::Require("user_config")->Create("user"));
3131
InitializeComponents();
3232
LoadSettings();
3333
RestoreSavedOptions();

test/config_compiler_test.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class RimeConfigCompilerTestBase : public ::testing::Test {
1717
virtual string test_config_id() const = 0;
1818

1919
virtual void SetUp() {
20-
component_.reset(new ConfigComponent);
20+
component_.reset(new ConfigComponent<ConfigBuilder>);
2121
config_.reset(component_->Create(test_config_id()));
2222
}
2323

test/config_test.cc

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class RimeConfigTest : public ::testing::Test {
1616
RimeConfigTest() = default;
1717

1818
virtual void SetUp() {
19-
component_.reset(new ConfigComponent);
19+
component_.reset(new ConfigComponent<ConfigLoader>);
2020
config_.reset(component_->Create("config_test"));
2121
}
2222

@@ -30,7 +30,10 @@ class RimeConfigTest : public ::testing::Test {
3030
TEST(RimeConfigComponentTest, RoundTrip) {
3131
// registration
3232
Registry& r = Registry::instance();
33-
r.Register("test_config", new ConfigComponent);
33+
r.Register("test_config", new ConfigComponent<ConfigLoader>(
34+
[](ConfigLoader* loader) {
35+
loader->set_auto_save(true);
36+
}));
3437
// find component
3538
Config::Component* cc = Config::Require("test_config");
3639
ASSERT_TRUE(cc != NULL);

0 commit comments

Comments
 (0)