1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #ifndef ENGINE_KERNEL_H |
4 | #define ENGINE_KERNEL_H |
5 | |
6 | class IKernel; |
7 | class IInterface; |
8 | |
9 | class IInterface |
10 | { |
11 | // friend with the kernel implementation |
12 | friend class CKernel; |
13 | IKernel *m_pKernel; |
14 | |
15 | protected: |
16 | IKernel *Kernel() { return m_pKernel; } |
17 | |
18 | public: |
19 | IInterface() : |
20 | m_pKernel(nullptr) {} |
21 | virtual void Shutdown() {} |
22 | virtual ~IInterface() {} |
23 | }; |
24 | |
25 | #define MACRO_INTERFACE(Name) \ |
26 | public: \ |
27 | static const char *InterfaceName() { return Name; } \ |
28 | \ |
29 | private: |
30 | |
31 | // This kernel thingie makes the structure very flat and basically singletons. |
32 | // I'm not sure if this is a good idea but it works for now. |
33 | class IKernel |
34 | { |
35 | // hide the implementation |
36 | virtual void RegisterInterfaceImpl(const char *pInterfaceName, IInterface *pInterface, bool Destroy) = 0; |
37 | virtual void ReregisterInterfaceImpl(const char *pInterfaceName, IInterface *pInterface) = 0; |
38 | virtual IInterface *RequestInterfaceImpl(const char *pInterfaceName) = 0; |
39 | |
40 | public: |
41 | static IKernel *Create(); |
42 | virtual void Shutdown() = 0; |
43 | virtual ~IKernel() {} |
44 | |
45 | // templated access to handle pointer conversions and interface names |
46 | template<class TINTERFACE> |
47 | void RegisterInterface(TINTERFACE *pInterface, bool Destroy = true) |
48 | { |
49 | RegisterInterfaceImpl(pInterfaceName: TINTERFACE::InterfaceName(), pInterface, Destroy); |
50 | } |
51 | template<class TINTERFACE> |
52 | void ReregisterInterface(TINTERFACE *pInterface) |
53 | { |
54 | ReregisterInterfaceImpl(pInterfaceName: TINTERFACE::InterfaceName(), pInterface); |
55 | } |
56 | |
57 | // Usage example: |
58 | // IMyInterface *pMyHandle = Kernel()->RequestInterface<IMyInterface>() |
59 | template<class TINTERFACE> |
60 | TINTERFACE *RequestInterface() |
61 | { |
62 | return reinterpret_cast<TINTERFACE *>(RequestInterfaceImpl(pInterfaceName: TINTERFACE::InterfaceName())); |
63 | } |
64 | }; |
65 | |
66 | #endif |
67 | |