]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/dynref.h
Remove the Kiwi links from the readme.
[user/henk/code/inspircd.git] / include / dynref.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2019-2020 Sadie Powell <sadie@witchery.services>
5  *   Copyright (C) 2013-2015 Attila Molnar <attilamolnar@hush.com>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #pragma once
22
23 #include "base.h"
24
25 class CoreExport dynamic_reference_base : public interfacebase, public insp::intrusive_list_node<dynamic_reference_base>
26 {
27  public:
28         class CaptureHook
29         {
30          public:
31                 /** Called when the target of the dynamic_reference has been acquired
32                  */
33                 virtual void OnCapture() = 0;
34         };
35
36  private:
37         std::string name;
38         CaptureHook* hook;
39         void resolve();
40  protected:
41         ServiceProvider* value;
42  public:
43         ModuleRef creator;
44         dynamic_reference_base(Module* Creator, const std::string& Name);
45         ~dynamic_reference_base();
46         inline const std::string& GetProvider() const { return name; }
47         void SetProvider(const std::string& newname);
48
49         /** Set handler to call when the target object becomes available
50          * @param h Handler to call
51          */
52         void SetCaptureHook(CaptureHook* h) { hook = h; }
53
54         void check();
55         operator bool() const { return (value != NULL); }
56         static void reset_all();
57 };
58
59 inline void dynamic_reference_base::check()
60 {
61         if (!value)
62                 throw ModuleException("Dynamic reference to '" + name + "' failed to resolve. Are you missing a module?");
63 }
64
65 template<typename T>
66 class dynamic_reference : public dynamic_reference_base
67 {
68  public:
69         dynamic_reference(Module* Creator, const std::string& Name)
70                 : dynamic_reference_base(Creator, Name) {}
71
72         inline T* operator->()
73         {
74                 check();
75                 return static_cast<T*>(value);
76         }
77
78         T* operator*()
79         {
80                 return operator->();
81         }
82
83         const T* operator->() const
84         {
85                 return static_cast<T*>(value);
86         }
87
88         const T* operator*() const
89         {
90                 return operator->();
91         }
92 };
93
94 template<typename T>
95 class dynamic_reference_nocheck : public dynamic_reference_base
96 {
97  public:
98         dynamic_reference_nocheck(Module* Creator, const std::string& Name)
99                 : dynamic_reference_base(Creator, Name) {}
100
101         T* operator->()
102         {
103                 return static_cast<T*>(value);
104         }
105
106         T* operator*()
107         {
108                 return operator->();
109         }
110
111         const T* operator->() const
112         {
113                 return static_cast<T*>(value);
114         }
115
116         const T* operator*() const
117         {
118                 return operator->();
119         }
120 };
121
122 class ModeHandler;
123 class ChanModeReference : public dynamic_reference_nocheck<ModeHandler>
124 {
125  public:
126         ChanModeReference(Module* mod, const std::string& modename)
127                 : dynamic_reference_nocheck<ModeHandler>(mod, "mode/" + modename) {}
128 };
129
130 class UserModeReference : public dynamic_reference_nocheck<ModeHandler>
131 {
132  public:
133         UserModeReference(Module* mod, const std::string& modename)
134                 : dynamic_reference_nocheck<ModeHandler>(mod, "umode/" + modename) {}
135 };