diff --git a/cmd/protoc-gen-cpp-tableau-loader/embed/load.pc.cc b/cmd/protoc-gen-cpp-tableau-loader/embed/load.pc.cc index 0454b53c..74467101 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/embed/load.pc.cc +++ b/cmd/protoc-gen-cpp-tableau-loader/embed/load.pc.cc @@ -163,7 +163,7 @@ bool PatchMessage(google::protobuf::Message& dst, const google::protobuf::Messag } bool LoadMessageWithPatch(google::protobuf::Message& msg, const std::string& path, Format fmt, tableau::Patch patch, - const LoadOptions* options /* = nullptr*/) { + std::shared_ptr options /* = nullptr*/) { if (options == nullptr) { return LoadMessageByPath(msg, path, fmt, nullptr); } @@ -244,7 +244,7 @@ bool LoadMessageWithPatch(google::protobuf::Message& msg, const std::string& pat } bool LoadMessageByPath(google::protobuf::Message& msg, const std::string& path, Format fmt, - const LoadOptions* options /* = nullptr*/) { + std::shared_ptr options /* = nullptr*/) { std::string content; ReadFunc read_func = util::ReadFile; if (options != nullptr && options->read_func) { @@ -272,7 +272,7 @@ bool LoadMessageByPath(google::protobuf::Message& msg, const std::string& path, } bool LoadMessage(google::protobuf::Message& msg, const std::string& dir, Format fmt, - const LoadOptions* options /* = nullptr*/) { + std::shared_ptr options /* = nullptr*/) { std::string name = util::GetProtoName(msg); std::string path; if (options) { diff --git a/cmd/protoc-gen-cpp-tableau-loader/embed/load.pc.h b/cmd/protoc-gen-cpp-tableau-loader/embed/load.pc.h index 8f725973..b64ca32b 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/embed/load.pc.h +++ b/cmd/protoc-gen-cpp-tableau-loader/embed/load.pc.h @@ -37,7 +37,7 @@ struct LoadOptions { }; bool LoadMessageByPath(google::protobuf::Message& msg, const std::string& path, Format fmt = Format::kJSON, - const LoadOptions* options = nullptr); + std::shared_ptr options = nullptr); bool LoadMessage(google::protobuf::Message& msg, const std::string& dir, Format fmt = Format::kJSON, - const LoadOptions* options = nullptr); + std::shared_ptr options = nullptr); } // namespace tableau \ No newline at end of file diff --git a/cmd/protoc-gen-cpp-tableau-loader/embed/messager.pc.h b/cmd/protoc-gen-cpp-tableau-loader/embed/messager.pc.h index 3949b256..7d5bda88 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/embed/messager.pc.h +++ b/cmd/protoc-gen-cpp-tableau-loader/embed/messager.pc.h @@ -22,7 +22,7 @@ class Messager { static const std::string& Name() { return kEmpty; } const Stats& GetStats() { return stats_; } // Load fills message from file in the specified directory and format. - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) = 0; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) = 0; // Message returns the inner message data. virtual const google::protobuf::Message* Message() const { return nullptr; } // callback after all messagers loaded. diff --git a/cmd/protoc-gen-cpp-tableau-loader/embed/util.pc.cc b/cmd/protoc-gen-cpp-tableau-loader/embed/util.pc.cc index e6ec6c69..5ecd56e3 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/embed/util.pc.cc +++ b/cmd/protoc-gen-cpp-tableau-loader/embed/util.pc.cc @@ -133,7 +133,8 @@ const std::string& Format2Ext(Format fmt) { } } -bool JSON2Message(const std::string& json, google::protobuf::Message& msg, const LoadOptions* options /* = nullptr */) { +bool JSON2Message(const std::string& json, google::protobuf::Message& msg, + std::shared_ptr options /* = nullptr */) { google::protobuf::util::Status status; if (options != nullptr) { google::protobuf::util::JsonParseOptions parse_options; diff --git a/cmd/protoc-gen-cpp-tableau-loader/embed/util.pc.h b/cmd/protoc-gen-cpp-tableau-loader/embed/util.pc.h index 7e21f23b..60debed4 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/embed/util.pc.h +++ b/cmd/protoc-gen-cpp-tableau-loader/embed/util.pc.h @@ -82,7 +82,8 @@ Format Ext2Format(const std::string& ext); // and the error message can be obtained by GetErrMsg(). const std::string& Format2Ext(Format fmt); -bool JSON2Message(const std::string& json, google::protobuf::Message& msg, const LoadOptions* options = nullptr); +bool JSON2Message(const std::string& json, google::protobuf::Message& msg, + std::shared_ptr options = nullptr); bool Text2Message(const std::string& text, google::protobuf::Message& msg); bool Bin2Message(const std::string& bin, google::protobuf::Message& msg); diff --git a/cmd/protoc-gen-cpp-tableau-loader/hub.go b/cmd/protoc-gen-cpp-tableau-loader/hub.go index 00cd1b90..5e0e468e 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/hub.go +++ b/cmd/protoc-gen-cpp-tableau-loader/hub.go @@ -59,9 +59,9 @@ func generateHub(gen *protogen.Plugin) { helper.GenerateCommonHeader(gen, g1, version) g1.P() g1.P(hubHpp) - generateHubHppTplSpec(gen, g1, protofiles, fileMessagers) + generateHubHppTplSpec(g1, protofiles, fileMessagers) g1.P(msgContainerHpp) - generateHubHppMsgContainerMembers(gen, g1, protofiles, fileMessagers) + generateHubHppMsgContainerMembers(g1, protofiles, fileMessagers) g1.P(registryHpp) g1.P(bottomHpp) @@ -70,13 +70,13 @@ func generateHub(gen *protogen.Plugin) { helper.GenerateCommonHeader(gen, g2, version) g2.P() g2.P(hubCppHeader) - generateHubCppHeader(gen, g2, protofiles, fileMessagers) + generateHubCppHeader(g2, protofiles) g2.P(hubCpp) - generateHubCppTplSpec(gen, g2, protofiles, fileMessagers) + generateHubCppTplSpec(g2, protofiles, fileMessagers) g2.P(msgContainerCpp) - generateHubCppMsgContainerCtor(gen, g2, protofiles, fileMessagers) + generateHubCppMsgContainerCtor(g2, protofiles, fileMessagers) g2.P(registryCpp) - generateHubCppRegistry(gen, g2, protofiles, fileMessagers) + generateHubCppRegistry(g2, protofiles, fileMessagers) g2.P(bottomCpp) } else { // sharding @@ -84,7 +84,7 @@ func generateHub(gen *protogen.Plugin) { } } -func generateHubHppTplSpec(gen *protogen.Plugin, g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { +func generateHubHppTplSpec(g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { for _, proto := range protofiles { for _, messager := range fileMessagers[proto] { g.P("class ", messager, ";") @@ -95,7 +95,7 @@ func generateHubHppTplSpec(gen *protogen.Plugin, g *protogen.GeneratedFile, prot } } -func generateHubHppMsgContainerMembers(gen *protogen.Plugin, g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { +func generateHubHppMsgContainerMembers(g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { for _, proto := range protofiles { for _, messager := range fileMessagers[proto] { g.P(helper.Indent(1), "std::shared_ptr<", messager, "> ", strcase.ToSnake(messager), "_;") @@ -103,14 +103,14 @@ func generateHubHppMsgContainerMembers(gen *protogen.Plugin, g *protogen.Generat } } -func generateHubCppHeader(gen *protogen.Plugin, g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { +func generateHubCppHeader(g *protogen.GeneratedFile, protofiles []string) { for _, proto := range protofiles { g.P(`#include "`, proto, ".", pcExt, `.h"`) } g.P() } -func generateHubCppTplSpec(gen *protogen.Plugin, g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { +func generateHubCppTplSpec(g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { for _, proto := range protofiles { for _, messager := range fileMessagers[proto] { g.P("template <>") @@ -122,18 +122,18 @@ func generateHubCppTplSpec(gen *protogen.Plugin, g *protogen.GeneratedFile, prot } } -func generateHubCppMsgContainerCtor(gen *protogen.Plugin, g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { +func generateHubCppMsgContainerCtor(g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { for _, proto := range protofiles { for _, messager := range fileMessagers[proto] { - g.P(helper.Indent(1), strcase.ToSnake(messager), "_ = std::dynamic_pointer_cast<", messager, `>((*msger_map_)["`, messager, `"]);`) + g.P(helper.Indent(1), strcase.ToSnake(messager), "_ = std::dynamic_pointer_cast<", messager, `>(GetMessager("`, messager, `"));`) } } } -func generateHubCppRegistry(gen *protogen.Plugin, g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { +func generateHubCppRegistry(g *protogen.GeneratedFile, protofiles []string, fileMessagers map[string][]string) { for _, proto := range protofiles { for _, messager := range fileMessagers[proto] { - g.P(helper.Indent(1), "Register<", messager, ">();") + g.P(helper.Indent(2), "Register<", messager, ">();") } } } @@ -157,7 +157,10 @@ using MessagerMap = std::unordered_map>; // FilterFunc filter in messagers if returned value is true. // NOTE: name is the protobuf message name, e.g.: "message ItemConf{...}". using Filter = std::function; -using MessagerContainerProvider = std::function()>; +// MessagerContainerProvider provides a custom MessagerContainer for hub. +// If not specified, the hub's default MessagerContainer will be used. +// NOTE: This func must return non-nil MessagerContainer. +using MessagerContainerProvider = std::function(const Hub&)>; struct HubOptions { // Filter can only filter in certain specific messagers based on the @@ -170,16 +173,20 @@ struct HubOptions { class Hub { public: - Hub(const HubOptions* options = nullptr) - : msger_container_(std::make_shared()), options_(options ? *options : HubOptions{}) {} + Hub(); + + // InitOnce inits the hub only once, and the subsequent calls will not take effect. + void InitOnce(std::shared_ptr options); + /***** Synchronous Loading *****/ // Load fills messages (in MessagerContainer) from files in the specified directory and format. - bool Load(const std::string& dir, Format fmt = Format::kJSON, const LoadOptions* options = nullptr); + bool Load(const std::string& dir, Format fmt = Format::kJSON, std::shared_ptr options = nullptr); /***** Asynchronous Loading *****/ // Load configs into temp MessagerContainer, and you should call LoopOnce() in you app's main loop, // in order to take the temp MessagerContainer into effect. - bool AsyncLoad(const std::string& dir, Format fmt = Format::kJSON, const LoadOptions* options = nullptr); + bool AsyncLoad(const std::string& dir, Format fmt = Format::kJSON, + std::shared_ptr options = nullptr); int LoopOnce(); // You'd better initialize the scheduler in the main thread. void InitScheduler(); @@ -190,12 +197,7 @@ class Hub { /***** MessagerContainer *****/ // This function is exposed only for use in MessagerContainerProvider. - std::shared_ptr GetMessagerContainer() const { - if (options_.provider != nullptr) { - return options_.provider(); - } - return msger_container_; - } + std::shared_ptr GetMessagerContainer() const { return msger_container_; } /***** Access APIs *****/ template @@ -212,8 +214,9 @@ class Hub { private: std::shared_ptr InternalLoad(const std::string& dir, Format fmt = Format::kJSON, - const LoadOptions* options = nullptr) const; + std::shared_ptr options = nullptr) const; std::shared_ptr NewMessagerMap() const; + std::shared_ptr GetMessagerContainerWithProvider() const; const std::shared_ptr GetMessager(const std::string& name) const; bool Postprocess(std::shared_ptr msger_map); @@ -225,8 +228,10 @@ class Hub { std::shared_ptr msger_container_; // Loading scheduler. internal::Scheduler* sched_ = nullptr; + // Init once + std::once_flag init_once_; // Hub options - const HubOptions options_; + std::shared_ptr options_; }; template @@ -258,7 +263,8 @@ const msgContainerHpp = `class MessagerContainer { std::shared_ptr msger_map_; std::time_t last_loaded_time_; - private:` + private: + const std::shared_ptr GetMessager(const std::string& name) const;` const registryHpp = `}; @@ -276,7 +282,8 @@ class Registry { private:` -const bottomHpp = ` static Registrar registrar; +const bottomHpp = ` static std::once_flag once; + static Registrar registrar; }; template @@ -293,9 +300,17 @@ const hubCppHeader = `#include "hub.pc.h" const hubCpp = ` namespace tableau { -Registrar Registry::registrar = Registrar(); +std::once_flag Registry::once; +Registrar Registry::registrar; -bool Hub::Load(const std::string& dir, Format fmt /* = Format::kJSON */, const LoadOptions* options /* = nullptr */) { +Hub::Hub() { tableau::Registry::Init(); } + +void Hub::InitOnce(std::shared_ptr options) { + std::call_once(init_once_, [&]() { options_ = options; }); +} + +bool Hub::Load(const std::string& dir, Format fmt /* = Format::kJSON */, + std::shared_ptr options /* = nullptr */) { auto msger_map = InternalLoad(dir, fmt, options); if (!msger_map) { return false; @@ -309,7 +324,7 @@ bool Hub::Load(const std::string& dir, Format fmt /* = Format::kJSON */, const L } bool Hub::AsyncLoad(const std::string& dir, Format fmt /* = Format::kJSON */, - const LoadOptions* options /* = nullptr */) { + std::shared_ptr options /* = nullptr */) { auto msger_map = InternalLoad(dir, fmt, options); if (!msger_map) { return false; @@ -330,7 +345,7 @@ void Hub::InitScheduler() { } std::shared_ptr Hub::InternalLoad(const std::string& dir, Format fmt /* = Format::kJSON */, - const LoadOptions* options /* = nullptr */) const { + std::shared_ptr options /* = nullptr */) const { // intercept protobuf error logs auto old_handler = google::protobuf::SetLogHandler(util::ProtobufLogHandler); auto msger_map = NewMessagerMap(); @@ -355,14 +370,14 @@ std::shared_ptr Hub::InternalLoad(const std::string& dir, Format fm std::shared_ptr Hub::NewMessagerMap() const { std::shared_ptr msger_map = std::make_shared(); for (auto&& it : Registry::registrar) { - if (!options_.filter || options_.filter(it.first)) { + if (options_ == nullptr || options_->filter == nullptr || options_->filter(it.first)) { (*msger_map)[it.first] = it.second(); } } return msger_map; } -std::shared_ptr Hub::GetMessagerMap() const { return GetMessagerContainer()->msger_map_; } +std::shared_ptr Hub::GetMessagerMap() const { return GetMessagerContainerWithProvider()->msger_map_; } void Hub::SetMessagerMap(std::shared_ptr msger_map) { // replace with thread-safe guarantee. @@ -371,14 +386,14 @@ void Hub::SetMessagerMap(std::shared_ptr msger_map) { } const std::shared_ptr Hub::GetMessager(const std::string& name) const { - auto msger_map = GetMessagerMap(); - if (msger_map) { - auto it = msger_map->find(name); - if (it != msger_map->end()) { - return it->second; - } + return GetMessagerContainerWithProvider()->GetMessager(name); +} + +std::shared_ptr Hub::GetMessagerContainerWithProvider() const { + if (options_ != nullptr && options_->provider != nullptr) { + return options_->provider(*this); } - return nullptr; + return msger_container_; } bool Hub::Postprocess(std::shared_ptr msger_map) { @@ -398,7 +413,7 @@ bool Hub::Postprocess(std::shared_ptr msger_map) { return true; } -std::time_t Hub::GetLastLoadedTime() const { return GetMessagerContainer()->last_loaded_time_; }` +std::time_t Hub::GetLastLoadedTime() const { return GetMessagerContainerWithProvider()->last_loaded_time_; }` const msgContainerCpp = ` MessagerContainer::MessagerContainer(std::shared_ptr msger_map /* = nullptr*/) @@ -407,7 +422,19 @@ MessagerContainer::MessagerContainer(std::shared_ptr msger_map /* = const registryCpp = `} -void Registry::Init() {` +const std::shared_ptr MessagerContainer::GetMessager(const std::string& name) const { + if (msger_map_) { + auto it = msger_map_->find(name); + if (it != msger_map_->end()) { + return it->second; + } + } + return nullptr; +} + +void Registry::Init() { + std::call_once(once, []() {` -const bottomCpp = `} +const bottomCpp = ` }); +} } // namespace tableau` diff --git a/cmd/protoc-gen-cpp-tableau-loader/messager.go b/cmd/protoc-gen-cpp-tableau-loader/messager.go index 9533901f..fef3c3a3 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/messager.go +++ b/cmd/protoc-gen-cpp-tableau-loader/messager.go @@ -26,7 +26,7 @@ func generateHppFile(gen *protogen.Plugin, file *protogen.File) *protogen.Genera g := gen.NewGeneratedFile(filename, "") helper.GenerateFileHeader(gen, file, g, version) g.P() - generateHppFileContent(gen, file, g) + generateHppFileContent(file, g) return g } @@ -36,12 +36,12 @@ func generateCppFile(gen *protogen.Plugin, file *protogen.File) *protogen.Genera g := gen.NewGeneratedFile(filename, "") helper.GenerateFileHeader(gen, file, g, version) g.P() - generateCppFileContent(gen, file, g) + generateCppFileContent(file, g) return g } // generateHppFileContent generates type definitions. -func generateHppFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile) { +func generateHppFileContent(file *protogen.File, g *protogen.GeneratedFile) { g.P("#pragma once") g.P("#include ") g.P() @@ -56,7 +56,7 @@ func generateHppFileContent(gen *protogen.Plugin, file *protogen.File, g *protog opts := message.Desc.Options().(*descriptorpb.MessageOptions) worksheet := proto.GetExtension(opts, tableaupb.E_Worksheet).(*tableaupb.WorksheetOptions) if worksheet != nil { - genHppMessage(gen, file, g, message) + genHppMessage(file, g, message) messagerName := string(message.Desc.Name()) fileMessagers = append(fileMessagers, messagerName) } @@ -76,7 +76,7 @@ func generateHppFileContent(gen *protogen.Plugin, file *protogen.File, g *protog } // genHppMessage generates a message definition. -func genHppMessage(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, message *protogen.Message) { +func genHppMessage(file *protogen.File, g *protogen.GeneratedFile, message *protogen.Message) { pkg := string(file.Desc.Package()) cppFullName := strings.ReplaceAll(pkg, ".", "::") + "::" + string(message.Desc.Name()) messagerFullName := string(message.Desc.FullName()) @@ -85,7 +85,7 @@ func genHppMessage(gen *protogen.Plugin, file *protogen.File, g *protogen.Genera g.P("class ", message.Desc.Name(), " : public Messager {") g.P(" public:") g.P(helper.Indent(1), "static const std::string& Name() { return kProtoName; }") - g.P(helper.Indent(1), "virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override;") + g.P(helper.Indent(1), "virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override;") g.P(helper.Indent(1), "const ", cppFullName, "& Data() const { return data_; }") g.P(helper.Indent(1), "const google::protobuf::Message* Message() const override { return &data_; }") g.P() @@ -132,7 +132,7 @@ func genHppMapGetters(depth int, keys []helper.MapKey, g *protogen.GeneratedFile } // generateCppFileContent generates type implementations. -func generateCppFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile) { +func generateCppFileContent(file *protogen.File, g *protogen.GeneratedFile) { g.P(`#include "`, file.GeneratedFilenamePrefix, ".", pcExt, `.h"`) g.P() g.P(`#include "hub.pc.h"`) @@ -144,21 +144,21 @@ func generateCppFileContent(gen *protogen.Plugin, file *protogen.File, g *protog opts := message.Desc.Options().(*descriptorpb.MessageOptions) worksheet := proto.GetExtension(opts, tableaupb.E_Worksheet).(*tableaupb.WorksheetOptions) if worksheet != nil { - genCppMessage(gen, g, message) + genCppMessage(g, message) } } g.P("} // namespace ", *namespace) } // genCppMessage generates a message implementation. -func genCppMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protogen.Message) { +func genCppMessage(g *protogen.GeneratedFile, message *protogen.Message) { messagerName := string(message.Desc.Name()) messagerFullName := string(message.Desc.FullName()) indexDescriptor := index.ParseIndexDescriptor(message.Desc) g.P("const std::string ", messagerName, "::kProtoName = ", `"`, messagerName, `";`) g.P() - g.P("bool ", messagerName, "::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) {") + g.P("bool ", messagerName, "::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) {") g.P(helper.Indent(1), "tableau::util::TimeProfiler profiler;") g.P(helper.Indent(1), "bool loaded = LoadMessage(data_, dir, fmt, options);") g.P(helper.Indent(1), "bool ok = loaded ? ProcessAfterLoad() : false;") diff --git a/cmd/protoc-gen-cpp-tableau-loader/shard.go b/cmd/protoc-gen-cpp-tableau-loader/shard.go index 1289490f..b1e0aeb7 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/shard.go +++ b/cmd/protoc-gen-cpp-tableau-loader/shard.go @@ -25,12 +25,12 @@ func generateShardedHub(gen *protogen.Plugin) { helper.GenerateCommonHeader(gen, g1, version) g1.P() g1.P(hubHpp) - generateHubHppTplSpec(gen, g1, protofiles, fileMessagers) + generateHubHppTplSpec(g1, protofiles, fileMessagers) g1.P(msgContainerHpp) - generateShardedHubHppMsgContainerShards(gen, g1, realShardNum) - generateHubHppMsgContainerMembers(gen, g1, protofiles, fileMessagers) + generateShardedHubHppMsgContainerShards(g1, realShardNum) + generateHubHppMsgContainerMembers(g1, protofiles, fileMessagers) g1.P(registryHpp) - generateShardedHubHppRegistryShards(gen, g1, realShardNum) + generateShardedHubHppRegistryShards(g1, realShardNum) g1.P(bottomHpp) cppFilename := "hub." + pcExt + ".cc" @@ -40,9 +40,9 @@ func generateShardedHub(gen *protogen.Plugin) { g2.P(hubCppHeader) g2.P(hubCpp) g2.P(msgContainerCpp) - generateShardedHubCppMsgContainerShards(gen, g2, realShardNum) + generateShardedHubCppMsgContainerShards(g2, realShardNum) g2.P(registryCpp) - generateShardedHubCppRegistryShards(gen, g2, realShardNum) + generateShardedHubCppRegistryShards(g2, realShardNum) g2.P(bottomCpp) for i := 0; i < realShardNum; i++ { @@ -55,11 +55,11 @@ func generateShardedHub(gen *protogen.Plugin) { helper.GenerateCommonHeader(gen, g, version) g.P() shardedProtofiles := protofiles[i*shardSize : cursor] - generateShardedHubCppFileContent(gen, g, i, shardedProtofiles, fileMessagers) + generateShardedHubCppFileContent(g, i, shardedProtofiles, fileMessagers) } } -func generateShardedHubHppMsgContainerShards(gen *protogen.Plugin, g *protogen.GeneratedFile, shardNum int) { +func generateShardedHubHppMsgContainerShards(g *protogen.GeneratedFile, shardNum int) { for i := 0; i < shardNum; i++ { g.P(helper.Indent(1), "void InitShard", i, "();") } @@ -67,7 +67,7 @@ func generateShardedHubHppMsgContainerShards(gen *protogen.Plugin, g *protogen.G g.P(" private:") } -func generateShardedHubHppRegistryShards(gen *protogen.Plugin, g *protogen.GeneratedFile, shardNum int) { +func generateShardedHubHppRegistryShards(g *protogen.GeneratedFile, shardNum int) { for i := 0; i < shardNum; i++ { g.P(helper.Indent(1), "static void InitShard", i, "();") } @@ -75,19 +75,19 @@ func generateShardedHubHppRegistryShards(gen *protogen.Plugin, g *protogen.Gener g.P(" private:") } -func generateShardedHubCppMsgContainerShards(gen *protogen.Plugin, g *protogen.GeneratedFile, shardNum int) { +func generateShardedHubCppMsgContainerShards(g *protogen.GeneratedFile, shardNum int) { for i := 0; i < shardNum; i++ { g.P(helper.Indent(1), "InitShard", i, "();") } } -func generateShardedHubCppRegistryShards(gen *protogen.Plugin, g *protogen.GeneratedFile, shardNum int) { +func generateShardedHubCppRegistryShards(g *protogen.GeneratedFile, shardNum int) { for i := 0; i < shardNum; i++ { - g.P(helper.Indent(1), "InitShard", i, "();") + g.P(helper.Indent(2), "InitShard", i, "();") } } -func generateShardedHubCppFileContent(gen *protogen.Plugin, g *protogen.GeneratedFile, shardIndex int, protofiles []string, fileMessagers map[string][]string) { +func generateShardedHubCppFileContent(g *protogen.GeneratedFile, shardIndex int, protofiles []string, fileMessagers map[string][]string) { g.P(`#include "`, "hub.", pcExt, `.h"`) g.P() for _, proto := range protofiles { @@ -100,7 +100,7 @@ func generateShardedHubCppFileContent(gen *protogen.Plugin, g *protogen.Generate for _, messager := range fileMessagers[proto] { g.P("template <>") g.P("const std::shared_ptr<" + messager + "> Hub::Get<" + messager + ">() const {") - g.P(helper.Indent(1), "return GetMessagerContainer()->", strcase.ToSnake(messager), "_;") + g.P(helper.Indent(1), "return GetMessagerContainerWithProvider()->", strcase.ToSnake(messager), "_;") g.P("}") g.P() } @@ -109,7 +109,7 @@ func generateShardedHubCppFileContent(gen *protogen.Plugin, g *protogen.Generate g.P("void MessagerContainer::InitShard", shardIndex, "() {") for _, proto := range protofiles { for _, messager := range fileMessagers[proto] { - g.P(helper.Indent(1), strcase.ToSnake(messager), "_ = std::dynamic_pointer_cast<", messager, `>((*msger_map_)["`, messager, `"]);`) + g.P(helper.Indent(1), strcase.ToSnake(messager), "_ = std::dynamic_pointer_cast<", messager, `>(GetMessager("`, messager, `"));`) } } g.P("}") diff --git a/test/cpp-tableau-loader/src/hub/custom/item/custom_item_conf.h b/test/cpp-tableau-loader/src/hub/custom/item/custom_item_conf.h index 6dc2826a..5ebb6820 100644 --- a/test/cpp-tableau-loader/src/hub/custom/item/custom_item_conf.h +++ b/test/cpp-tableau-loader/src/hub/custom/item/custom_item_conf.h @@ -5,7 +5,7 @@ class CustomItemConf : public tableau::Messager { public: static const std::string& Name() { return kCustomName; }; virtual bool Load(const std::string& dir, tableau::Format fmt, - const tableau::LoadOptions* options = nullptr) override { + std::shared_ptr options = nullptr) override { return true; } virtual bool ProcessAfterLoadAll(const tableau::Hub& hub) override; diff --git a/test/cpp-tableau-loader/src/hub/hub.cpp b/test/cpp-tableau-loader/src/hub/hub.cpp index 4c973299..1df497f7 100644 --- a/test/cpp-tableau-loader/src/hub/hub.cpp +++ b/test/cpp-tableau-loader/src/hub/hub.cpp @@ -1,6 +1,5 @@ #include "hub/hub.h" -#include "hub.h" #include "hub/custom/item/custom_item_conf.h" #include "protoconf/logger.pc.h" @@ -18,10 +17,25 @@ void LogWrite(std::ostream* os, const tableau::log::SourceLocation& loc, const t // clang-format on } -void Hub::Init() { +bool DefaultFilter(const std::string& name) { + // all messagers except TaskConf + return name != "TaskConf"; +} + +std::shared_ptr DefaultMessagerContainerProvider(const tableau::Hub& hub) { + // default messager container + return hub.GetMessagerContainer(); +} + +void Hub::InitOnce() { // custom log tableau::log::DefaultLogger()->SetWriter(LogWrite); - tableau::Registry::Init(); + // call base hub's InitOnce + auto options = std::make_shared(); + options->filter = DefaultFilter; + options->provider = DefaultMessagerContainerProvider; + tableau::Hub::InitOnce(options); + // register custom messagers InitCustomMessager(); } diff --git a/test/cpp-tableau-loader/src/hub/hub.h b/test/cpp-tableau-loader/src/hub/hub.h index b6a79a58..e7ce98f7 100644 --- a/test/cpp-tableau-loader/src/hub/hub.h +++ b/test/cpp-tableau-loader/src/hub/hub.h @@ -29,16 +29,8 @@ class Singleton { class Hub : public tableau::Hub, public Singleton { public: - Hub() : tableau::Hub(GetOptions()) {} - void Init(); + void InitOnce(); private: void InitCustomMessager(); - bool Filter(const std::string& name) { return true; } - - private: - const tableau::HubOptions* GetOptions() { - static const tableau::HubOptions options{std::bind(&Hub::Filter, this, std::placeholders::_1)}; - return &options; - } }; diff --git a/test/cpp-tableau-loader/src/main.cpp b/test/cpp-tableau-loader/src/main.cpp index 53fde80a..71c3d5e8 100644 --- a/test/cpp-tableau-loader/src/main.cpp +++ b/test/cpp-tableau-loader/src/main.cpp @@ -13,8 +13,8 @@ #include "protoconf/patch_conf.pc.h" #include "protoconf/test_conf.pc.h" -bool LoadWithPatch(tableau::LoadOptions options) { - return Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, &options); +bool LoadWithPatch(std::shared_ptr options) { + return Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, options); } bool CustomReadFile(const std::string& filename, std::string& content) { @@ -30,13 +30,13 @@ bool CustomReadFile(const std::string& filename, std::string& content) { } bool TestPatch() { - tableau::LoadOptions options; - options.read_func = CustomReadFile; + auto options = std::make_shared(); + options->read_func = CustomReadFile; // patchconf std::cout << "-----TestPatch patchconf" << std::endl; - options.patch_dirs = {"../../testdata/patchconf/"}; - bool ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, &options); + options->patch_dirs = {"../../testdata/patchconf/"}; + bool ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, options); if (!ok) { std::cout << "failed to load with patchconf" << std::endl; return false; @@ -63,8 +63,8 @@ bool TestPatch() { // patchconf2 std::cout << "-----TestPatch patchconf2" << std::endl; - options.patch_dirs = {"../../testdata/patchconf2/"}; - ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, &options); + options->patch_dirs = {"../../testdata/patchconf2/"}; + ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, options); if (!ok) { std::cout << "failed to load with patchconf2" << std::endl; return false; @@ -72,9 +72,9 @@ bool TestPatch() { // patchconf2 different format std::cout << "-----TestPatch patchconf2 different format" << std::endl; - options.patch_dirs = {"../../testdata/patchconf2/"}; - options.patch_paths["PatchMergeConf"] = {"../../testdata/patchconf2/PatchMergeConf.txt"}; - ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, &options); + options->patch_dirs = {"../../testdata/patchconf2/"}; + options->patch_paths["PatchMergeConf"] = {"../../testdata/patchconf2/PatchMergeConf.txt"}; + ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, options); if (!ok) { std::cout << "failed to load with patchconf2" << std::endl; return false; @@ -82,9 +82,9 @@ bool TestPatch() { // multiple patch files std::cout << "-----TestPatch multiple patch files" << std::endl; - options.patch_paths["PatchMergeConf"] = {"../../testdata/patchconf/PatchMergeConf.json", - "../../testdata/patchconf2/PatchMergeConf.json"}; - ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, &options); + options->patch_paths["PatchMergeConf"] = {"../../testdata/patchconf/PatchMergeConf.json", + "../../testdata/patchconf2/PatchMergeConf.json"}; + ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, options); if (!ok) { std::cout << "failed to load with multiple patch files" << std::endl; return false; @@ -92,10 +92,10 @@ bool TestPatch() { // mode only main std::cout << "-----TestPatch ModeOnlyMain" << std::endl; - options.patch_paths["PatchMergeConf"] = {"../../testdata/patchconf/PatchMergeConf.json", - "../../testdata/patchconf2/PatchMergeConf.json"}; - options.mode = tableau::LoadMode::kModeOnlyMain; - ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, &options); + options->patch_paths["PatchMergeConf"] = {"../../testdata/patchconf/PatchMergeConf.json", + "../../testdata/patchconf2/PatchMergeConf.json"}; + options->mode = tableau::LoadMode::kModeOnlyMain; + ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, options); if (!ok) { std::cout << "failed to load with mode only main" << std::endl; return false; @@ -109,10 +109,10 @@ bool TestPatch() { // mode only patch std::cout << "-----TestPatch ModeOnlyPatch" << std::endl; - options.patch_paths["PatchMergeConf"] = {"../../testdata/patchconf/PatchMergeConf.json", - "../../testdata/patchconf2/PatchMergeConf.json"}; - options.mode = tableau::LoadMode::kModeOnlyPatch; - ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, &options); + options->patch_paths["PatchMergeConf"] = {"../../testdata/patchconf/PatchMergeConf.json", + "../../testdata/patchconf2/PatchMergeConf.json"}; + options->mode = tableau::LoadMode::kModeOnlyPatch; + ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, options); if (!ok) { std::cout << "failed to load with mode only patch" << std::endl; return false; @@ -121,13 +121,13 @@ bool TestPatch() { } int main() { - Hub::Instance().Init(); - tableau::LoadOptions options; - options.ignore_unknown_fields = true; - options.patch_dirs = {"../../testdata/patchconf/"}; - options.paths["ItemConf"] = "../../testdata/conf/ItemConf.json"; + Hub::Instance().InitOnce(); + auto options = std::make_shared(); + options->ignore_unknown_fields = true; + options->patch_dirs = {"../../testdata/patchconf/"}; + options->paths["ItemConf"] = "../../testdata/conf/ItemConf.json"; - bool ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, &options); + bool ok = Hub::Instance().Load("../../testdata/conf/", tableau::Format::kJSON, options); if (!ok) { std::cout << "protobuf hub load failed: " << tableau::GetErrMsg() << std::endl; return 1; diff --git a/test/cpp-tableau-loader/src/protoconf/hero_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/hero_conf.pc.cc index a6428088..16094a7e 100644 --- a/test/cpp-tableau-loader/src/protoconf/hero_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hero_conf.pc.cc @@ -12,7 +12,7 @@ namespace tableau { const std::string HeroConf::kProtoName = "HeroConf"; -bool HeroConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool HeroConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; @@ -71,7 +71,7 @@ const HeroConf::Hero_Attr_OrderedMap* HeroConf::GetOrderedMap(const std::string& const std::string HeroBaseConf::kProtoName = "HeroBaseConf"; -bool HeroBaseConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool HeroBaseConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; diff --git a/test/cpp-tableau-loader/src/protoconf/hero_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/hero_conf.pc.h index 53ec91a2..02698c01 100644 --- a/test/cpp-tableau-loader/src/protoconf/hero_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/hero_conf.pc.h @@ -15,7 +15,7 @@ namespace tableau { class HeroConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::HeroConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } @@ -46,7 +46,7 @@ class HeroConf : public Messager { class HeroBaseConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::HeroBaseConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } diff --git a/test/cpp-tableau-loader/src/protoconf/hub.pc.cc b/test/cpp-tableau-loader/src/protoconf/hub.pc.cc index c4339b8a..77e2d003 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hub.pc.cc @@ -10,9 +10,17 @@ #include "util.pc.h" namespace tableau { -Registrar Registry::registrar = Registrar(); +std::once_flag Registry::once; +Registrar Registry::registrar; -bool Hub::Load(const std::string& dir, Format fmt /* = Format::kJSON */, const LoadOptions* options /* = nullptr */) { +Hub::Hub() { tableau::Registry::Init(); } + +void Hub::InitOnce(std::shared_ptr options) { + std::call_once(init_once_, [&]() { options_ = options; }); +} + +bool Hub::Load(const std::string& dir, Format fmt /* = Format::kJSON */, + std::shared_ptr options /* = nullptr */) { auto msger_map = InternalLoad(dir, fmt, options); if (!msger_map) { return false; @@ -26,7 +34,7 @@ bool Hub::Load(const std::string& dir, Format fmt /* = Format::kJSON */, const L } bool Hub::AsyncLoad(const std::string& dir, Format fmt /* = Format::kJSON */, - const LoadOptions* options /* = nullptr */) { + std::shared_ptr options /* = nullptr */) { auto msger_map = InternalLoad(dir, fmt, options); if (!msger_map) { return false; @@ -47,7 +55,7 @@ void Hub::InitScheduler() { } std::shared_ptr Hub::InternalLoad(const std::string& dir, Format fmt /* = Format::kJSON */, - const LoadOptions* options /* = nullptr */) const { + std::shared_ptr options /* = nullptr */) const { // intercept protobuf error logs auto old_handler = google::protobuf::SetLogHandler(util::ProtobufLogHandler); auto msger_map = NewMessagerMap(); @@ -72,14 +80,14 @@ std::shared_ptr Hub::InternalLoad(const std::string& dir, Format fm std::shared_ptr Hub::NewMessagerMap() const { std::shared_ptr msger_map = std::make_shared(); for (auto&& it : Registry::registrar) { - if (!options_.filter || options_.filter(it.first)) { + if (options_ == nullptr || options_->filter == nullptr || options_->filter(it.first)) { (*msger_map)[it.first] = it.second(); } } return msger_map; } -std::shared_ptr Hub::GetMessagerMap() const { return GetMessagerContainer()->msger_map_; } +std::shared_ptr Hub::GetMessagerMap() const { return GetMessagerContainerWithProvider()->msger_map_; } void Hub::SetMessagerMap(std::shared_ptr msger_map) { // replace with thread-safe guarantee. @@ -88,14 +96,14 @@ void Hub::SetMessagerMap(std::shared_ptr msger_map) { } const std::shared_ptr Hub::GetMessager(const std::string& name) const { - auto msger_map = GetMessagerMap(); - if (msger_map) { - auto it = msger_map->find(name); - if (it != msger_map->end()) { - return it->second; - } + return GetMessagerContainerWithProvider()->GetMessager(name); +} + +std::shared_ptr Hub::GetMessagerContainerWithProvider() const { + if (options_ != nullptr && options_->provider != nullptr) { + return options_->provider(*this); } - return nullptr; + return msger_container_; } bool Hub::Postprocess(std::shared_ptr msger_map) { @@ -115,7 +123,7 @@ bool Hub::Postprocess(std::shared_ptr msger_map) { return true; } -std::time_t Hub::GetLastLoadedTime() const { return GetMessagerContainer()->last_loaded_time_; } +std::time_t Hub::GetLastLoadedTime() const { return GetMessagerContainerWithProvider()->last_loaded_time_; } MessagerContainer::MessagerContainer(std::shared_ptr msger_map /* = nullptr*/) : msger_map_(msger_map != nullptr ? msger_map : std::make_shared()), @@ -124,8 +132,20 @@ MessagerContainer::MessagerContainer(std::shared_ptr msger_map /* = InitShard1(); } +const std::shared_ptr MessagerContainer::GetMessager(const std::string& name) const { + if (msger_map_) { + auto it = msger_map_->find(name); + if (it != msger_map_->end()) { + return it->second; + } + } + return nullptr; +} + void Registry::Init() { - InitShard0(); - InitShard1(); + std::call_once(once, []() { + InitShard0(); + InitShard1(); + }); } } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/hub.pc.h b/test/cpp-tableau-loader/src/protoconf/hub.pc.h index 9611d52f..bde26d02 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/hub.pc.h @@ -22,7 +22,10 @@ using MessagerMap = std::unordered_map>; // FilterFunc filter in messagers if returned value is true. // NOTE: name is the protobuf message name, e.g.: "message ItemConf{...}". using Filter = std::function; -using MessagerContainerProvider = std::function()>; +// MessagerContainerProvider provides a custom MessagerContainer for hub. +// If not specified, the hub's default MessagerContainer will be used. +// NOTE: This func must return non-nil MessagerContainer. +using MessagerContainerProvider = std::function(const Hub&)>; struct HubOptions { // Filter can only filter in certain specific messagers based on the @@ -35,16 +38,20 @@ struct HubOptions { class Hub { public: - Hub(const HubOptions* options = nullptr) - : msger_container_(std::make_shared()), options_(options ? *options : HubOptions{}) {} + Hub(); + + // InitOnce inits the hub only once, and the subsequent calls will not take effect. + void InitOnce(std::shared_ptr options); + /***** Synchronous Loading *****/ // Load fills messages (in MessagerContainer) from files in the specified directory and format. - bool Load(const std::string& dir, Format fmt = Format::kJSON, const LoadOptions* options = nullptr); + bool Load(const std::string& dir, Format fmt = Format::kJSON, std::shared_ptr options = nullptr); /***** Asynchronous Loading *****/ // Load configs into temp MessagerContainer, and you should call LoopOnce() in you app's main loop, // in order to take the temp MessagerContainer into effect. - bool AsyncLoad(const std::string& dir, Format fmt = Format::kJSON, const LoadOptions* options = nullptr); + bool AsyncLoad(const std::string& dir, Format fmt = Format::kJSON, + std::shared_ptr options = nullptr); int LoopOnce(); // You'd better initialize the scheduler in the main thread. void InitScheduler(); @@ -55,12 +62,7 @@ class Hub { /***** MessagerContainer *****/ // This function is exposed only for use in MessagerContainerProvider. - std::shared_ptr GetMessagerContainer() const { - if (options_.provider != nullptr) { - return options_.provider(); - } - return msger_container_; - } + std::shared_ptr GetMessagerContainer() const { return msger_container_; } /***** Access APIs *****/ template @@ -77,8 +79,9 @@ class Hub { private: std::shared_ptr InternalLoad(const std::string& dir, Format fmt = Format::kJSON, - const LoadOptions* options = nullptr) const; + std::shared_ptr options = nullptr) const; std::shared_ptr NewMessagerMap() const; + std::shared_ptr GetMessagerContainerWithProvider() const; const std::shared_ptr GetMessager(const std::string& name) const; bool Postprocess(std::shared_ptr msger_map); @@ -90,8 +93,10 @@ class Hub { std::shared_ptr msger_container_; // Loading scheduler. internal::Scheduler* sched_ = nullptr; + // Init once + std::once_flag init_once_; // Hub options - const HubOptions options_; + std::shared_ptr options_; }; template @@ -163,6 +168,7 @@ class MessagerContainer { std::time_t last_loaded_time_; private: + const std::shared_ptr GetMessager(const std::string& name) const; void InitShard0(); void InitShard1(); @@ -196,6 +202,7 @@ class Registry { static void InitShard1(); private: + static std::once_flag once; static Registrar registrar; }; diff --git a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc index 157445b0..d7fbeb61 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc @@ -11,23 +11,23 @@ namespace tableau { template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->hero_base_conf_; + return GetMessagerContainerWithProvider()->hero_base_conf_; } template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->hero_conf_; + return GetMessagerContainerWithProvider()->hero_conf_; } template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->item_conf_; + return GetMessagerContainerWithProvider()->item_conf_; } void MessagerContainer::InitShard0() { - hero_base_conf_ = std::dynamic_pointer_cast((*msger_map_)["HeroBaseConf"]); - hero_conf_ = std::dynamic_pointer_cast((*msger_map_)["HeroConf"]); - item_conf_ = std::dynamic_pointer_cast((*msger_map_)["ItemConf"]); + hero_base_conf_ = std::dynamic_pointer_cast(GetMessager("HeroBaseConf")); + hero_conf_ = std::dynamic_pointer_cast(GetMessager("HeroConf")); + item_conf_ = std::dynamic_pointer_cast(GetMessager("ItemConf")); } void Registry::InitShard0() { diff --git a/test/cpp-tableau-loader/src/protoconf/hub_shard1.pc.cc b/test/cpp-tableau-loader/src/protoconf/hub_shard1.pc.cc index 5778079d..e063eeeb 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub_shard1.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hub_shard1.pc.cc @@ -11,47 +11,47 @@ namespace tableau { template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->patch_merge_conf_; + return GetMessagerContainerWithProvider()->patch_merge_conf_; } template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->patch_replace_conf_; + return GetMessagerContainerWithProvider()->patch_replace_conf_; } template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->recursive_patch_conf_; + return GetMessagerContainerWithProvider()->recursive_patch_conf_; } template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->activity_conf_; + return GetMessagerContainerWithProvider()->activity_conf_; } template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->chapter_conf_; + return GetMessagerContainerWithProvider()->chapter_conf_; } template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->task_conf_; + return GetMessagerContainerWithProvider()->task_conf_; } template <> const std::shared_ptr Hub::Get() const { - return GetMessagerContainer()->theme_conf_; + return GetMessagerContainerWithProvider()->theme_conf_; } void MessagerContainer::InitShard1() { - patch_merge_conf_ = std::dynamic_pointer_cast((*msger_map_)["PatchMergeConf"]); - patch_replace_conf_ = std::dynamic_pointer_cast((*msger_map_)["PatchReplaceConf"]); - recursive_patch_conf_ = std::dynamic_pointer_cast((*msger_map_)["RecursivePatchConf"]); - activity_conf_ = std::dynamic_pointer_cast((*msger_map_)["ActivityConf"]); - chapter_conf_ = std::dynamic_pointer_cast((*msger_map_)["ChapterConf"]); - task_conf_ = std::dynamic_pointer_cast((*msger_map_)["TaskConf"]); - theme_conf_ = std::dynamic_pointer_cast((*msger_map_)["ThemeConf"]); + patch_merge_conf_ = std::dynamic_pointer_cast(GetMessager("PatchMergeConf")); + patch_replace_conf_ = std::dynamic_pointer_cast(GetMessager("PatchReplaceConf")); + recursive_patch_conf_ = std::dynamic_pointer_cast(GetMessager("RecursivePatchConf")); + activity_conf_ = std::dynamic_pointer_cast(GetMessager("ActivityConf")); + chapter_conf_ = std::dynamic_pointer_cast(GetMessager("ChapterConf")); + task_conf_ = std::dynamic_pointer_cast(GetMessager("TaskConf")); + theme_conf_ = std::dynamic_pointer_cast(GetMessager("ThemeConf")); } void Registry::InitShard1() { diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc index d8527ca3..c4ca73ad 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc @@ -12,7 +12,7 @@ namespace tableau { const std::string ItemConf::kProtoName = "ItemConf"; -bool ItemConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool ItemConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h index 77442e63..e5afd07c 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h @@ -15,7 +15,7 @@ namespace tableau { class ItemConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::ItemConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } diff --git a/test/cpp-tableau-loader/src/protoconf/load.pc.cc b/test/cpp-tableau-loader/src/protoconf/load.pc.cc index 1020552f..46659083 100644 --- a/test/cpp-tableau-loader/src/protoconf/load.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/load.pc.cc @@ -168,7 +168,7 @@ bool PatchMessage(google::protobuf::Message& dst, const google::protobuf::Messag } bool LoadMessageWithPatch(google::protobuf::Message& msg, const std::string& path, Format fmt, tableau::Patch patch, - const LoadOptions* options /* = nullptr*/) { + std::shared_ptr options /* = nullptr*/) { if (options == nullptr) { return LoadMessageByPath(msg, path, fmt, nullptr); } @@ -249,7 +249,7 @@ bool LoadMessageWithPatch(google::protobuf::Message& msg, const std::string& pat } bool LoadMessageByPath(google::protobuf::Message& msg, const std::string& path, Format fmt, - const LoadOptions* options /* = nullptr*/) { + std::shared_ptr options /* = nullptr*/) { std::string content; ReadFunc read_func = util::ReadFile; if (options != nullptr && options->read_func) { @@ -277,7 +277,7 @@ bool LoadMessageByPath(google::protobuf::Message& msg, const std::string& path, } bool LoadMessage(google::protobuf::Message& msg, const std::string& dir, Format fmt, - const LoadOptions* options /* = nullptr*/) { + std::shared_ptr options /* = nullptr*/) { std::string name = util::GetProtoName(msg); std::string path; if (options) { diff --git a/test/cpp-tableau-loader/src/protoconf/load.pc.h b/test/cpp-tableau-loader/src/protoconf/load.pc.h index e61f957e..4fc8a035 100644 --- a/test/cpp-tableau-loader/src/protoconf/load.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/load.pc.h @@ -42,7 +42,7 @@ struct LoadOptions { }; bool LoadMessageByPath(google::protobuf::Message& msg, const std::string& path, Format fmt = Format::kJSON, - const LoadOptions* options = nullptr); + std::shared_ptr options = nullptr); bool LoadMessage(google::protobuf::Message& msg, const std::string& dir, Format fmt = Format::kJSON, - const LoadOptions* options = nullptr); + std::shared_ptr options = nullptr); } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/messager.pc.h b/test/cpp-tableau-loader/src/protoconf/messager.pc.h index c0f73bfc..3e8de4e7 100644 --- a/test/cpp-tableau-loader/src/protoconf/messager.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/messager.pc.h @@ -27,7 +27,7 @@ class Messager { static const std::string& Name() { return kEmpty; } const Stats& GetStats() { return stats_; } // Load fills message from file in the specified directory and format. - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) = 0; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) = 0; // Message returns the inner message data. virtual const google::protobuf::Message* Message() const { return nullptr; } // callback after all messagers loaded. diff --git a/test/cpp-tableau-loader/src/protoconf/patch_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/patch_conf.pc.cc index de89e988..22f8dc1d 100644 --- a/test/cpp-tableau-loader/src/protoconf/patch_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/patch_conf.pc.cc @@ -12,7 +12,7 @@ namespace tableau { const std::string PatchReplaceConf::kProtoName = "PatchReplaceConf"; -bool PatchReplaceConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool PatchReplaceConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; @@ -22,7 +22,7 @@ bool PatchReplaceConf::Load(const std::string& dir, Format fmt, const LoadOption const std::string PatchMergeConf::kProtoName = "PatchMergeConf"; -bool PatchMergeConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool PatchMergeConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; @@ -40,7 +40,7 @@ const protoconf::Item* PatchMergeConf::Get(uint32_t id) const { const std::string RecursivePatchConf::kProtoName = "RecursivePatchConf"; -bool RecursivePatchConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool RecursivePatchConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; diff --git a/test/cpp-tableau-loader/src/protoconf/patch_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/patch_conf.pc.h index 44ed81cb..6f0c366a 100644 --- a/test/cpp-tableau-loader/src/protoconf/patch_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/patch_conf.pc.h @@ -15,7 +15,7 @@ namespace tableau { class PatchReplaceConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::PatchReplaceConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } @@ -28,7 +28,7 @@ class PatchReplaceConf : public Messager { class PatchMergeConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::PatchMergeConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } @@ -43,7 +43,7 @@ class PatchMergeConf : public Messager { class RecursivePatchConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::RecursivePatchConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc index 1a8f8582..effa1bd9 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc @@ -12,7 +12,7 @@ namespace tableau { const std::string ActivityConf::kProtoName = "ActivityConf"; -bool ActivityConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool ActivityConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; @@ -240,7 +240,7 @@ const protoconf::Section::SectionItem* ActivityConf::FindFirstAward(uint32_t id) const std::string ChapterConf::kProtoName = "ChapterConf"; -bool ChapterConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool ChapterConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; @@ -258,7 +258,7 @@ const protoconf::ChapterConf::Chapter* ChapterConf::Get(uint64_t id) const { const std::string ThemeConf::kProtoName = "ThemeConf"; -bool ThemeConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool ThemeConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; @@ -288,7 +288,7 @@ const std::string* ThemeConf::Get(const std::string& name, const std::string& pa const std::string TaskConf::kProtoName = "TaskConf"; -bool TaskConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { +bool TaskConf::Load(const std::string& dir, Format fmt, std::shared_ptr options /* = nullptr */) { tableau::util::TimeProfiler profiler; bool loaded = LoadMessage(data_, dir, fmt, options); bool ok = loaded ? ProcessAfterLoad() : false; diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h index 3947e957..09aeb632 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h @@ -15,7 +15,7 @@ namespace tableau { class ActivityConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::ActivityConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } @@ -102,7 +102,7 @@ class ActivityConf : public Messager { class ChapterConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::ChapterConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } @@ -117,7 +117,7 @@ class ChapterConf : public Messager { class ThemeConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::ThemeConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } @@ -133,7 +133,7 @@ class ThemeConf : public Messager { class TaskConf : public Messager { public: static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + virtual bool Load(const std::string& dir, Format fmt, std::shared_ptr options = nullptr) override; const protoconf::TaskConf& Data() const { return data_; } const google::protobuf::Message* Message() const override { return &data_; } diff --git a/test/cpp-tableau-loader/src/protoconf/util.pc.cc b/test/cpp-tableau-loader/src/protoconf/util.pc.cc index 1e92f206..fb61f76e 100644 --- a/test/cpp-tableau-loader/src/protoconf/util.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/util.pc.cc @@ -138,7 +138,8 @@ const std::string& Format2Ext(Format fmt) { } } -bool JSON2Message(const std::string& json, google::protobuf::Message& msg, const LoadOptions* options /* = nullptr */) { +bool JSON2Message(const std::string& json, google::protobuf::Message& msg, + std::shared_ptr options /* = nullptr */) { google::protobuf::util::Status status; if (options != nullptr) { google::protobuf::util::JsonParseOptions parse_options; diff --git a/test/cpp-tableau-loader/src/protoconf/util.pc.h b/test/cpp-tableau-loader/src/protoconf/util.pc.h index 32b1b3d3..e6b70f90 100644 --- a/test/cpp-tableau-loader/src/protoconf/util.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/util.pc.h @@ -87,7 +87,8 @@ Format Ext2Format(const std::string& ext); // and the error message can be obtained by GetErrMsg(). const std::string& Format2Ext(Format fmt); -bool JSON2Message(const std::string& json, google::protobuf::Message& msg, const LoadOptions* options = nullptr); +bool JSON2Message(const std::string& json, google::protobuf::Message& msg, + std::shared_ptr options = nullptr); bool Text2Message(const std::string& text, google::protobuf::Message& msg); bool Bin2Message(const std::string& bin, google::protobuf::Message& msg);