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
6class IKernel;
7class IInterface;
8
9class IInterface
10{
11 // friend with the kernel implementation
12 friend class CKernel;
13 IKernel *m_pKernel;
14
15protected:
16 IKernel *Kernel() { return m_pKernel; }
17
18public:
19 IInterface() :
20 m_pKernel(nullptr) {}
21 virtual void Shutdown() {}
22 virtual ~IInterface() {}
23};
24
25#define MACRO_INTERFACE(Name) \
26public: \
27 static const char *InterfaceName() { return Name; } \
28\
29private:
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.
33class 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
40public:
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