Skip to content

Commit c931575

Browse files
committed
get started on modules
1 parent 64574ff commit c931575

File tree

7 files changed

+188
-21
lines changed

7 files changed

+188
-21
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@
1616
[submodule "third_party/robin-map"]
1717
path = third_party/robin-map
1818
url = https://github.com/Tessil/robin-map.git
19+
[submodule "third_party/semver"]
20+
path = third_party/semver
21+
url = https://github.com/Rythe-Interactive/semver.git

.rythe_project

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ local project = {
55
"public third_party/argh:header-only",
66
"public third_party/stb:header-only",
77
"public third_party/tinygltf:header-only",
8-
"public third_party/tinyobj:header-only"
8+
"public third_party/tinyobj:header-only",
9+
"public third_party/semver:header-only"
910
},
1011
defines = { "RYTHE_INTERNAL" }
1112
}

src/core/entry/entry_point.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* @param [in] engine The engine object
2323
* @ref rythe::core::Engine::reportModule<T,...>()
2424
*/
25-
extern rsl::result<void> init_program(rythe::core::Program& program);
25+
extern rsl::result<void> init_program(rythe::core::program& program);
2626

2727
#if defined(RYTHE_ENTRY)
2828

@@ -35,7 +35,7 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
3535
int main(int argc, char** argv)
3636
{
3737
rsl::log::setup();
38-
rythe::core::Program program;
38+
rythe::core::program program;
3939

4040
{
4141
auto result = init_program(program);
@@ -48,7 +48,7 @@ int main(int argc, char** argv)
4848
}
4949
program.initialize();
5050

51-
while (program.isRunning())
51+
while (program.is_running())
5252
{
5353
program.update();
5454
}

src/core/module/module.hpp

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#pragma once
2+
#include <semver.hpp>
3+
4+
#include <rsl/hashed_string>
5+
#include <rsl/memory>
6+
#include <rsl/primitives>
7+
#include <rsl/type_traits>
8+
#include <rsl/utilities>
9+
10+
namespace rythe::core
11+
{
12+
struct feature_desc
13+
{
14+
std::string_view name;
15+
rsl::id_type id;
16+
semver::version version;
17+
};
18+
19+
struct feature_base
20+
{
21+
[[nodiscard]] virtual std::string_view get_name() const noexcept = 0;
22+
[[nodiscard]] virtual rsl::id_type get_id() const noexcept = 0;
23+
[[nodiscard]] virtual rsl::hashed_string get_hashed_name() const noexcept = 0;
24+
[[nodiscard]] virtual semver::version get_version() const noexcept = 0;
25+
26+
template <typename T>
27+
const T* try_cast() const noexcept
28+
{
29+
if (T::feature_id == get_id())
30+
{
31+
return static_cast<T*>(this);
32+
}
33+
34+
return nullptr;
35+
}
36+
37+
template <typename T>
38+
T* try_cast() noexcept
39+
{
40+
return const_cast<T*>(rsl::as_const(*this).template try_cast<T>());
41+
}
42+
43+
template <typename T>
44+
const T& cast() const
45+
{
46+
const T* ptr = try_cast<T>();
47+
rsl_assert_invalid_cast(ptr);
48+
return ptr;
49+
}
50+
51+
template <typename T>
52+
T& cast()
53+
{
54+
return const_cast<T&>(rsl::as_const(*this).template cast<T>());
55+
}
56+
};
57+
58+
namespace internal
59+
{
60+
template <typename T>
61+
struct get_feature_name
62+
{
63+
constexpr static auto value = rsl::type_name<T>();
64+
};
65+
66+
template <typename T>
67+
requires requires {
68+
{ T::feature_name } -> rsl::constexpr_string_type;
69+
}
70+
struct get_feature_name<T>
71+
{
72+
constexpr static auto value = T::feature_name;
73+
};
74+
75+
template <typename T>
76+
struct get_feature_version
77+
{
78+
constexpr static semver::version value = semver::version();
79+
};
80+
81+
template <typename T>
82+
requires requires {
83+
{ T::feature_version } -> rsl::convertible_to<semver::version>;
84+
}
85+
struct get_feature_version<T>
86+
{
87+
constexpr static semver::version value = T::feature_version;
88+
};
89+
} // namespace internal
90+
91+
template <typename Impl>
92+
struct feature : public feature_base
93+
{
94+
constexpr static rsl::id_type feature_id = rsl::hash_string(internal::get_feature_name<Impl>::value);
95+
constexpr static rsl::hashed_string feature_hashed_name =
96+
rsl::hashed_string(internal::get_feature_name<Impl>::value);
97+
98+
[[nodiscard]] std::string_view get_name() const noexcept override
99+
{
100+
return internal::get_feature_name<Impl>::value;
101+
}
102+
[[nodiscard]] rsl::id_type get_id() const noexcept override { return feature_id; }
103+
[[nodiscard]] rsl::hashed_string get_hashed_name() const noexcept override { return feature_hashed_name; }
104+
[[nodiscard]] semver::version get_version() const noexcept override
105+
{
106+
return internal::get_feature_version<Impl>::value;
107+
}
108+
};
109+
110+
class engine;
111+
112+
class module_base
113+
{
114+
public:
115+
virtual rsl::result<void> initialize() noexcept = 0;
116+
virtual std::span<const feature_desc> get_features_descriptions() const noexcept = 0;
117+
118+
virtual const feature_base* try_get_feature(rsl::id_type id) const noexcept = 0;
119+
feature_base* try_get_feature(rsl::id_type id) noexcept;
120+
const feature_base& get_feature(rsl::id_type id) const;
121+
feature_base& get_feature(rsl::id_type id);
122+
123+
[[nodiscard]] const engine& get_engine() const noexcept;
124+
[[nodiscard]] engine& get_engine() noexcept;
125+
126+
rsl::pmu_allocator& get_allocator() noexcept;
127+
const rsl::pmu_allocator& get_allocator() const noexcept;
128+
129+
module_base(engine& engine);
130+
131+
private:
132+
engine* m_engine{};
133+
};
134+
135+
class module : public module_base
136+
{
137+
public:
138+
template <typename T, typename... Args>
139+
void add_feature(Args&&... args)
140+
{
141+
add_feature(std::unique_ptr<feature_base, rsl::stl_pmu_deleter<feature_base>>(
142+
rsl::allocate<T>(get_allocator(), 1, rsl::forward<Args>(args)...),
143+
rsl::make_stl_pmu_deleter(&get_allocator())
144+
));
145+
}
146+
147+
void add_feature(std::unique_ptr<feature_base, rsl::stl_pmu_deleter<feature_base>>&& featurePtr);
148+
149+
std::span<const feature_desc> get_features_descriptions() const noexcept override;
150+
const feature_base* try_get_feature(rsl::id_type id) const noexcept override;
151+
152+
private:
153+
std::vector<feature_desc> m_featureDescriptions;
154+
std::vector<std::unique_ptr<feature_base, rsl::stl_pmu_deleter<feature_base>>> m_features;
155+
};
156+
} // namespace rythe::core

src/core/program/program.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace rythe::core
44
{
5-
void Engine::setup(Program* ptr)
5+
void engine::setup(program& program)
66
{
77
rsl::log::debug("Engine[{}] Instance initialized", m_engineId);
8-
m_programPtr = ptr;
8+
m_programPtr = &program;
99
}
1010
} // namespace rythe::core

src/core/program/program.hpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,41 @@
1010

1111
namespace rythe::core
1212
{
13-
class Program;
13+
class program;
1414

15-
class Engine
15+
class engine
1616
{
1717
private:
18-
Program* m_programPtr = nullptr;
18+
program* m_programPtr = nullptr;
1919
rsl::id_type m_engineId = 0;
20-
rsl::type_map m_context;
20+
rsl::pmu_allocator* m_allocator = nullptr;
21+
rsl::pmu_alloc_type_map m_context;
2122

2223
public:
23-
Engine(rsl::id_type id)
24-
: m_engineId(id)
24+
engine(rsl::id_type id, rsl::pmu_allocator* allocator = rsl::allocator_context::threadSpecificAllocator)
25+
: m_engineId(id),
26+
m_allocator(allocator),
27+
m_context(allocator)
2528
{
2629
}
2730

28-
void setup(Program* ptr);
31+
void setup(program& program);
2932

3033
void update() { rsl::log::debug("Engine[{}] Update", m_engineId); }
3134

3235
void shutdown() { rsl::log::debug("Engine[{}] Shutdown", m_engineId); }
3336

34-
rsl::type_map& get_context() noexcept { return m_context; }
35-
const rsl::type_map& get_context() const noexcept { return m_context; }
37+
rsl::pmu_alloc_type_map& get_context() noexcept { return m_context; }
38+
const rsl::pmu_alloc_type_map& get_context() const noexcept { return m_context; }
39+
40+
rsl::pmu_allocator& get_allocator() noexcept { return *m_allocator; }
41+
const rsl::pmu_allocator& get_allocator() const noexcept { return *m_allocator; }
3642
};
3743

38-
class Program
44+
class program
3945
{
4046
private:
41-
std::unordered_map<rsl::id_type, std::unique_ptr<Engine>> m_engines;
47+
std::unordered_map<rsl::id_type, std::unique_ptr<engine>> m_engines;
4248
rsl::type_map m_context;
4349
rsl::id_type m_lastIdx = 0;
4450
bool m_running = false;
@@ -49,7 +55,7 @@ namespace rythe::core
4955
rsl::log::debug("Initializing Program Instance");
5056
for (auto& [id, engine] : m_engines)
5157
{
52-
engine->setup(this);
58+
engine->setup(*this);
5359
}
5460
m_running = true;
5561
}
@@ -76,13 +82,13 @@ namespace rythe::core
7682
rsl::type_map& get_context() noexcept { return m_context; }
7783
const rsl::type_map& get_context() const noexcept { return m_context; }
7884

79-
[[rythe_always_inline]] bool isRunning() { return m_running; }
85+
[[rythe_always_inline]] bool is_running() { return m_running; }
8086

8187
[[rythe_always_inline]] void stop() { m_running = false; }
8288

83-
[[rythe_always_inline]] Engine& addEngineInstance()
89+
[[rythe_always_inline]] engine& add_engine_instance()
8490
{
85-
return *(m_engines.emplace(m_lastIdx, std::make_unique<Engine>(Engine{m_lastIdx++})).first->second);
91+
return *(m_engines.emplace(m_lastIdx, std::make_unique<engine>(engine{m_lastIdx++})).first->second);
8692
}
8793
};
8894
} // namespace rythe::core

third_party/semver

Submodule semver added at 95f82a4

0 commit comments

Comments
 (0)