#pragma once #include #include namespace Seele { template struct Dependencies; template <> struct Dependencies<> { int x; template Dependencies operator|(const Dependencies&) { return Dependencies(); } }; template struct Dependencies : public Dependencies { template Dependencies operator|(const Dependencies&) { return Dependencies(); } int x; }; namespace Component { template Comp& getComponent(); } template concept has_dependencies = requires(Comp) { Comp::dependencies; }; #define REQUIRE_COMPONENT(x) \ private: \ x& get##x() { return getComponent(); } \ const x& get##x() const { return getComponent(); } \ \ public: \ constexpr static Dependencies dependencies = {}; #define DECLARE_COMPONENT(x) \ void accessComponent(x& val); \ template <> x& getComponent(); #define DEFINE_COMPONENT(x) \ thread_local x* tl_##x = nullptr; \ void Seele::Component::accessComponent(x& ref) { tl_##x = &ref; } \ template <> x& Seele::Component::getComponent() { return *tl_##x; } } // namespace Seele