diff --git a/include/cserver/engine/components.hpp b/include/cserver/engine/components.hpp index 8a1e883..18e01b6 100644 --- a/include/cserver/engine/components.hpp +++ b/include/cserver/engine/components.hpp @@ -160,22 +160,47 @@ struct ServiceContextForComponent { }; }; +template +struct ServiceContextForComponentWithCliArgs : ServiceContextForComponent { + int argc; + const char** argv; + + constexpr ServiceContextForComponentWithCliArgs(T& context, int argc, const char** argv) : + ServiceContextForComponent(context), + argc(argc), + argv(argv) {}; +}; + + template -inline constexpr auto InitComponents(T& ccontext) -> void { +inline constexpr auto InitComponents(T& ccontext, int argc, const char** argv) -> void { static auto& context = ccontext; static auto& taskProcessor = context.taskProcessor; static auto& ioContext = taskProcessor.ioContext; + static constexpr utempl::ConstexprString cliArgs = [] -> decltype(auto) { + if constexpr(!std::is_same_v()), void>) { + return T::kConfig.template Get<"cliArgs">(); + } else { + return ""; + }; + }(); static utempl::Tuple inited = TransformDependencyGraphToTupleWithDependenciesToInitedFlagChanges(ioContext); auto work = make_work_guard(ioContext); - [](std::index_sequence){ - (boost::asio::co_spawn(ioContext, []() -> cserver::Task<> { + [argc, argv](std::index_sequence){ + (boost::asio::co_spawn(ioContext, [argc, argv]() -> cserver::Task<> { auto& dependencies = Get(inited); for(auto* flag : dependencies) { co_await flag->AsyncWait(); }; - ServiceContextForComponent(decltype(T::kUtils)::kComponentConfigs)), T> currentContext{context}; - Get(context.storage).emplace(currentContext); + using Current = decltype(Get(decltype(T::kUtils)::kComponentConfigs)); + if constexpr(Current::kName == cliArgs) { + ServiceContextForComponentWithCliArgs currentContext{context, argc, argv}; + Get(context.storage).emplace(currentContext); + } else { + ServiceContextForComponent currentContext{context}; + Get(context.storage).emplace(currentContext); + }; auto& componentInitFlag = GetInitFlagFor(ioContext); componentInitFlag.NotifyAll(); if constexpr(requires{Get(context.storage)->Run();}) { @@ -251,8 +276,8 @@ struct ServiceContext { taskProcessor{utempl::Wrapper{}, *this} ,storage{} { }; - constexpr auto Run() { - impl::InitComponents(*this); + constexpr auto Run(int argc, const char** argv) { + impl::InitComponents(*this, argc, argv); this->taskProcessor.Run(); }; @@ -309,6 +334,8 @@ consteval auto Ignore() {}; template struct DependencyInfoInjector { + int argc{}; + const char** argv{}; static constexpr ConstexprConfig kConfig = Config; static constexpr DependenciesUtils kUtils; static constexpr utempl::ConstexprString kName = Current::kName; @@ -545,9 +572,9 @@ struct ServiceContextBuilder { return ServiceContext{}; }; - static constexpr auto Run() -> void { + static constexpr auto Run(int argc = 0, const char** argv = nullptr) -> void { static auto context = GetServiceContext(); - context.Run(); + context.Run(argc, argv); context.taskProcessor.ioContext.run(); }; };