Catos Engine (Source) 0.0.1
Lightweight Game engine
Loading...
Searching...
No Matches
registry.h
Go to the documentation of this file.
1#pragma once
2
3
4
6#include <unordered_map>
7#include <iostream>
8#include <any>
9#include "type_utils.h"
10#include "types.h"
11#include <functional>
12#include <deque>
13#include <fstream>
14#include <typeindex>
15#include <regex>
16
17
18
19using namespace catos;
20
21
22
23
24namespace catos {
25
26 // Properties :)
28 class Property {
29
30 public:
33
34 virtual ~Property() {};
35
36 virtual void* get_value(const void* obj_ptr) = 0;
37 virtual const char* get_name() = 0;
38 virtual const char* get_type_name() = 0;
39 virtual size_t& get_type_hash() = 0;
40
41 virtual void set_name(const char* name) = 0;
42
43 virtual void registerToPy() = 0;
44
45 cstr desc = "NONE";
46 };
47
49 template<typename T, typename U>
50 class PropertyImpl : public Property {
51
52
53 public:
55 const char* name;
56
57
58 std::string type_name;
59 size_t type_hash;
60
66
68 void set_name(const char* new_name) override {
69 name = new_name;
70 }
71
72
73
74
76 void* get_value(const void* objPtr) override {
77 const T* obj = static_cast<const T*>(objPtr);
78 return const_cast<void*>(reinterpret_cast<const void*>(&(obj->*memberPtr)));
79 }
80
81
83 const char* get_name() override{
84 return name;
85 }
86
88 const char* get_type_name() override {
89 return type_name.c_str();
90 };
91
93 size_t& get_type_hash() override {
94 return type_hash;
95 };
96
97 void registerToPy() override {
99
100 inst.registerProperty<T, U>(name, memberPtr);
101 }
102
103 };
104
105 //Method ;-; | I DID IT RAHHHHHHH
106
108 public:
109
110 virtual void registerToPy(const char* name) = 0;
111 };
112
113 template<typename ReturnType, class ClassType, typename... Args>
115 private:
116 ReturnType(ClassType::* _ptr)(Args...);
117
118 public:
119 MethodHolderImpl(ReturnType(ClassType::* memberPtr)(Args...)) : _ptr(memberPtr) {
120
121 }
122
123 void registerToPy(const char* name) override {
125
126 inst.registerMethod<ClassType>(name, _ptr);
127 }
128 };
129
130
131 template<typename ReturnType, class ClassType, typename... Args>
134
135 public:
136
137 ReturnType (ClassType::* memPtr)(Args...);
138 MethodInvoker(ReturnType (ClassType::* ptr)(Args...)) {
139 memPtr = ptr;
140 };
142 static ReturnType callFunction(void* FuncInst, void* instance, Args... args) {
143 return (static_cast<ClassType*>(instance)->*static_cast<MethodInvoker<ReturnType, ClassType, Args...>*>(FuncInst)->memPtr)(args...);
144 }
145 };
146
147
148
149
150 template<typename... Args>
151 std::string getNames() {
152 std::string str;
153 int argC = 0;
154 (str.append(std::string(typeid(Args).name()) + std::string(" arg") + std::to_string(argC++) + ","), ...);
155
156 return str;
157 }
158
159 template<typename... Args>
160 std::string getArgNames() {
161 std::string str =",";
162 int argC = 0;
163
164 argC = sizeof...(Args);
165
166 for (int i=0; i < argC; i++) {
167 str += "arg" + std::to_string(i);
168 str += ",";
169 }
170
171 return str;
172 }
173
174
175
177 class Method {
178
179 public:
180 template<typename ReturnType, class ClassType, typename... Args>
181 Method(ReturnType(ClassType::* method)(Args...)) {
182 _mFunc = MethodInvoker<ReturnType, ClassType, Args...>(method);
183
184 holder = new MethodHolderImpl<ReturnType, ClassType, Args...>(method);
185
186 ptr = &MethodInvoker<ReturnType, ClassType, Args...>::callFunction;
187
188
190
191
192 if (getNames<Args...>() != "") {
193
194 parameters = getNames<Args...>();
195
196
197 std::string search = "char const * __ptr64";
198 std::string replace = "string";
199
200 size_t pos = 0;
201 // replace cstr to string
202 while((pos = parameters.find(search, pos)) != std::string::npos) {
203 parameters.replace(pos, search.length(), replace);
204 pos += replace.length();
205 }
206 search = "class catos:: ";
207 replace = "ref ";
208 pos = 0;
209
210 // Change class catos:: to ref for c#
211 while((pos = parameters.find(search, pos)) != std::string::npos) {
212 parameters.replace(pos, search.length(), replace);
213 pos += replace.length();
214 }
215
216 // remove ","
217 parameters.erase(parameters.size() - 1, 1);
218 parameterNames = getArgNames<Args...>();
219 parameterNames.erase(parameterNames.size() - 1, 1);
220 }
221
222 };
223
225 delete holder;
226 }
227
228 template<typename R, typename... Args>
229 R invoke_function(void* instance, Args... args) {
230 return std::any_cast<R(*)(void*, void*, Args...)>(ptr)(&_mFunc, instance, args...);
231 };
232
233 template<typename... Args>
234 void invoke_function(void* instance, Args... args) {
235 std::any_cast<void(*)(void*, void*, Args...)>(ptr)(&_mFunc, instance, args...);
236 };
237
238 void registerToPy(const char* name) {
239 holder->registerToPy(name);
240 }
241
242
243 cstr desc = "NONE";
244 std::string returnName = "void";
245
246 std::string parameters;
247 std::string parameterNames;
248 private:
249
250 std::any ptr;
251 std::any _mFunc;
252 MethodHolder* holder;
253 };
254
255
256
257
258 //Type
260 class TypeInfo {
261
262 public:
263
264 size_t type_hash;
265 std::string name;
266
267
268 template<typename T, typename U>
270 TypeInfo& property(const char* property_name, U T::* member, cstr description) {
271
272
273
274 properties[property_name] = new PropertyImpl<T, U>(member);
275 properties[property_name]->set_name(property_name);
276 properties[property_name]->desc = description;
277
278
279
280 // Return itself so that we can keep adding properties without having to write the instance again.
281 return *this;
282 }
283
285 template<typename ClassT, typename ReturnV, typename... Args>
286 constexpr TypeInfo& method(const char* method_name, ReturnV(ClassT::* ptr)(Args...), cstr description) {
287 methods[method_name] = new Method{ptr};
288 methods[method_name]->desc = description;
289
290
291 return *this;
292 }
293
295 Property* get_property(const char* property_name) {
296 auto it = properties.find(property_name);
297
298
299 if (it != properties.end()) {
300 return it->second;
301 }
302
303 //TODO replace with logger
304 std::cerr << "Could not find property\n";
305
306 return nullptr;
307 };
308
310 Method* get_method(const char* method_name) {
311 auto it = methods.find(method_name);
312
313 if (it != methods.end()) {
314 return it->second;
315 }
316
317 return nullptr;
318 };
319
320 template<typename T>
322 auto& inst = ScriptingEngine::getInstance();
323
324 auto structPos = name.find("struct");
325
326 if (structPos == std::string::npos) {
327 structPos = name.find("class");
328 }
329
330 inst.registerClass<T>(name.substr(structPos + 7).c_str());
331
332 for (auto property : properties) {
333 property.second->registerToPy();
334 }
335
336 for (auto method : methods) {
337 method.second->registerToPy(method.first.c_str());
338 }
339 };
340
342 static bool is_valid(Property* ptr) { return ptr != nullptr; };
343 static bool is_valid(Method* ptr) { return ptr != nullptr; };
344
345 std::unordered_map<std::string , Property* > properties;
346 std::unordered_map<std::string , Method* > methods;
347 };
348
349 //Core system :)_
351 class Registry {
352
353 public:
354
355
356
357 template<typename A>
360
361 size_t hash = type_utils::get_type_hash<A>();
362
363 // This means the user is trying to register a new type!
364 if (_register.find(hash) == _register.end()) {
365 _register.insert(std::pair<size_t, TypeInfo>(hash, TypeInfo{.type_hash = hash, .name= type_utils::get_type_name<A>() }));
366 }
367
368
369 return _register[hash];
370 };
371
372
375 std::ofstream out("../../../Resources/Catos/catos.py");
376
377 out << R"(""")" << "\n";
378
379 out << "The Python version of The Catos Game engine\n"
380 << "The python api is automatically generated by Catos\n"
381 << "NOTE: This API is only for scripting. \n";
382
383 out << R"(""")" << "\n";
384 for (auto type : _register) {
385
386 auto namespacePos = type.second.name.find("::");
387 auto structPos = type.second.name.find("struct");
388
389
390
391 if (namespacePos != std::string::npos) {
392 out << "class " << type.second.name.substr(namespacePos + 2) << ":\n";
393 } else {
394 out << "class " << type.second.name.substr(structPos + 7) << ":\n";
395 }
396
397 for (auto prop : type.second.properties) {
398 out << R"( """ )" << prop.second->desc << R"( """ )" << std::endl;
399 out << " " << prop.first << " = None\n";
400 }
401
402 for (auto meth : type.second.methods) {
403
404
405
406 if (meth.first == "init" || meth.first == "Init") {
407 out << R"( """ )" << meth.second->desc << R"( """ )" << std::endl;
408 out << " def __init__(self):\n pass\n";
409 } else {
410 out << " def " << meth.first << "(self)";
411 if (meth.second->returnName != "void") { out << " -> " << meth.second->returnName << ":\n"; } else { out << ":\n"; }
412 out << R"( """ )" << meth.second->desc << R"( """ )" << std::endl;
413 out << " pass\n";
414 }
415 }
416 }
417
418 out.close();
419 }
420
421
424 std::ofstream out("../../script_test.py");
425
426 out << "///Catos Lib (auto generated)\n";
427 out << "namespace catos {\n \n";
428 for (auto& type : _register) {
429
430 auto namespacePos = type.second.name.find("::");
431 auto structPos = type.second.name.find("struct");
432
433
434
435 if (namespacePos != std::string::npos) {
436 out << "struct " << type.second.name.substr(namespacePos + 2) << " {\n";
437 } else {
438 out << "struct " << type.second.name.substr(structPos + 7) << " {\n";
439 }
440
441 for (auto& prop : type.second.properties) {
442 out << " /*" << prop.second->desc << "*/\n";
443 out << " public " << prop.second->get_type_name() << " " << prop.second->get_name() << ";\n" ;
444 }
445
446 for (auto meth : type.second.methods) {
447
448 auto nPos = meth.second->returnName.find("::");
449 auto sPos = meth.second->returnName.find("struct");
450
451 if (nPos != std::string::npos || sPos != std::string::npos) {
452 out << " public void " << meth.first << "(" << meth.second->parameters << ") {\n";
453 out << " LibNative." << meth.first << "_native(ref this " << meth.second->parameterNames << ");\n";
454 out << " }\n";
455 } else {
456 out << " public " << meth.second->returnName << " " << meth.first << "() {\n";
457 out << " LibNative." << meth.first << "_native(ref this);\n";
458 out << " }\n";
459 }
460
461
462 }
463
464 out << "}\n \n";
465 }
466
467 out << "class LibNative {\n\n";
468
469 for (auto& type : _register) {
470
471 auto namespacePos = type.second.name.find("::");
472 auto structPos = type.second.name.find("struct");
473
474
475 std::string finalName;
476
477 if (namespacePos != std::string::npos) {
478 finalName = type.second.name.substr(namespacePos + 2);
479 } else {
480 finalName = type.second.name.substr(structPos + 7);
481 }
482
483 out << " //BEGIN DEF For " << finalName.c_str() << "\n";
484
485 for (auto meth : type.second.methods) {
486
487 auto nPos = meth.second->returnName.find("::");
488 auto sPos = meth.second->returnName.find("struct");
489
490 if (nPos != std::string::npos || sPos != std::string::npos) {
491 out << " [MethodImplAttribute(MethodImplOptions.InternalCall)]\n";
492 out << " public static extern void " << meth.first << "_native(ref " << finalName << " instance" << ", " << meth.second->parameters << ");\n \n";
493
494 } else {
495 out << " [MethodImplAttribute(MethodImplOptions.InternalCall)]\n";
496 out << " public static extern " << meth.second->returnName << " " << meth.first << "_native(ref " << finalName << " instance);\n \n";
497
498 }
499
500 }
501
502 out << " //END DEF For " << finalName.c_str() << "\n \n \n";
503 }
504
505 out << "}\n";
506
507
508 out << "}///NAMESPACE CATOS \n";
509 out.close();
510 }
511
513 template<typename A>
515 return (_register[type_utils::get_type_hash<A>()]);
516 }
517
518 //TODO Dummy function!!!
521 for (auto val : _register) {
522 TypeInfo& info = val.second;
523 std::cout << info.name.c_str() << " { \n";
524
525 for (auto& prop : info.properties) {
526
527 std::cout << " " << prop.second->get_type_name() << " " << prop.second->get_name() << ";\n";
528 }
529 std::cout << "}\n";
530 }
531 }
532
533
534
535
536 private:
537 std::unordered_map<size_t, TypeInfo> _register;
538 std::unordered_map<size_t, const void* > _instance_register;
539 };
540}
const char * cstr
Definition types.h:13
std::string_view str
Definition types.h:12
Definition application.h:13
std::string getNames()
Definition registry.h:151
std::string getArgNames()
Definition registry.h:160
size_t get_type_hash()
Definition type_utils.h:14
See PropertyImpl for details.
Definition registry.h:28
virtual void set_name(const char *name)=0
virtual size_t & get_type_hash()=0
virtual void * get_value(const void *obj_ptr)=0
virtual void registerToPy()=0
cstr desc
Definition registry.h:45
virtual ~Property()
Definition registry.h:34
virtual const char * get_type_name()=0
virtual const char * get_name()=0
PropertyImpl implements Property and holds an member function pointer. Used to get an value of an fie...
Definition registry.h:50
std::string type_name
Definition registry.h:58
const char * get_name() override
Get the name of the property.
Definition registry.h:83
void set_name(const char *new_name) override
Set the name of the property.
Definition registry.h:68
const char * name
Definition registry.h:55
void registerToPy() override
Definition registry.h:97
void * get_value(const void *objPtr) override
Use Get value (which can be cased to the desired type) to return an value of an instance.
Definition registry.h:76
U T::* memberPtr
Definition registry.h:54
size_t & get_type_hash() override
Returns (a reference of) the type's hash.
Definition registry.h:93
PropertyImpl(U T::*memPtr)
PropertyImpl exist in order to avoid having to deal with templates at the user-side.
Definition registry.h:62
size_t type_hash
Definition registry.h:59
const char * get_type_name() override
Returns the name of the fields type.
Definition registry.h:88
Definition registry.h:107
virtual void registerToPy(const char *name)=0
Definition registry.h:114
void registerToPy(const char *name) override
Definition registry.h:123
MethodHolderImpl(ReturnType(ClassType::*memberPtr)(Args...))
Definition registry.h:119
MethodInvoker invokes the method (with args) given at creation.
Definition registry.h:133
ReturnType(ClassType::* memPtr)(Args...)
Definition registry.h:137
MethodInvoker(ReturnType(ClassType::*ptr)(Args...))
Definition registry.h:138
static ReturnType callFunction(void *FuncInst, void *instance, Args... args)
Runs the function.
Definition registry.h:142
Stores a function pointer for running it.
Definition registry.h:177
std::string returnName
Definition registry.h:244
Method(ReturnType(ClassType::*method)(Args...))
Definition registry.h:181
void registerToPy(const char *name)
Definition registry.h:238
R invoke_function(void *instance, Args... args)
Definition registry.h:229
cstr desc
Definition registry.h:243
void invoke_function(void *instance, Args... args)
Definition registry.h:234
~Method()
Definition registry.h:224
std::string parameterNames
Definition registry.h:247
std::string parameters
Definition registry.h:246
Typeinfo is an object that holds all information about a specific type.
Definition registry.h:260
static bool is_valid(Property *ptr)
Checks wether or not the ptr is a nullptr;.
Definition registry.h:342
Property * get_property(const char *property_name)
Returns a property object based on the name given.
Definition registry.h:295
static bool is_valid(Method *ptr)
Definition registry.h:343
std::unordered_map< std::string, Property * > properties
Definition registry.h:345
size_t type_hash
Definition registry.h:264
std::unordered_map< std::string, Method * > methods
Definition registry.h:346
void registerToPython()
Definition registry.h:321
Method * get_method(const char *method_name)
Returns a method object based on the name given.
Definition registry.h:310
constexpr TypeInfo & method(const char *method_name, ReturnV(ClassT::*ptr)(Args...), cstr description)
Registers a method with a name and a member function pointer (returns the Type object again).
Definition registry.h:286
TypeInfo & property(const char *property_name, U T::*member, cstr description)
Registers a property with a name and a member pointer (Returns itself).
Definition registry.h:270
std::string name
Definition registry.h:265
The registry is the core system and provides reflection to the rest of the engine.
Definition registry.h:351
TypeInfo & get_type()
Returns the registered Type.
Definition registry.h:514
TypeInfo & register_class()
With this function you register a class to the Registry.
Definition registry.h:359
void print_current_register()
Prints out the items in the Registry.
Definition registry.h:520
void gen_python_bindings_file()
Deprecated!!!
Definition registry.h:374
void gen_cs_bindings_file()
TODO this shit is so ugly ;-;.
Definition registry.h:423
static ScriptingEngine & getInstance()
singleton :D
Definition ScriptingEngine.cpp:11