InspIRCd  4.0
dynref.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2019-2020 Sadie Powell <[email protected]>
5  * Copyright (C) 2013-2015 Attila Molnar <[email protected]>
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 insp::intrusive_list_node<dynamic_reference_base>
26 {
27  public:
29  {
30  public:
33  virtual void OnCapture() = 0;
34  };
35 
36  private:
37  std::string name;
38  CaptureHook* hook = nullptr;
39  void resolve();
40  static void* operator new(std::size_t) = delete;
41  static void* operator new[](std::size_t) = delete;
42  protected:
43  ServiceProvider* value = nullptr;
44  public:
45  ModuleRef creator;
46  dynamic_reference_base(Module* Creator, const std::string& Name);
48  inline const std::string& GetProvider() const { return name; }
49  void SetProvider(const std::string& newname);
50 
54  void SetCaptureHook(CaptureHook* h) { hook = h; }
55 
56  void check();
57  operator bool() const { return (value != NULL); }
58  static void reset_all();
59 };
60 
61 inline void dynamic_reference_base::check()
62 {
63  if (!value)
64  throw ModuleException("Dynamic reference to '" + name + "' failed to resolve. Are you missing a module?");
65 }
66 
67 template<typename T>
69 {
70  public:
71  dynamic_reference(Module* Creator, const std::string& Name)
72  : dynamic_reference_base(Creator, Name) {}
73 
74  inline T* operator->()
75  {
76  check();
77  return static_cast<T*>(value);
78  }
79 
80  T* operator*()
81  {
82  return operator->();
83  }
84 
85  const T* operator->() const
86  {
87  return static_cast<T*>(value);
88  }
89 
90  const T* operator*() const
91  {
92  return operator->();
93  }
94 };
95 
96 template<typename T>
98 {
99  public:
100  dynamic_reference_nocheck(Module* Creator, const std::string& Name)
101  : dynamic_reference_base(Creator, Name) {}
102 
103  T* operator->()
104  {
105  return static_cast<T*>(value);
106  }
107 
108  T* operator*()
109  {
110  return operator->();
111  }
112 
113  const T* operator->() const
114  {
115  return static_cast<T*>(value);
116  }
117 
118  const T* operator*() const
119  {
120  return operator->();
121  }
122 };
123 
124 class ModeHandler;
125 class ChanModeReference : public dynamic_reference_nocheck<ModeHandler>
126 {
127  public:
128  ChanModeReference(Module* mod, const std::string& modename)
129  : dynamic_reference_nocheck<ModeHandler>(mod, "mode/" + modename) {}
130 };
131 
132 class UserModeReference : public dynamic_reference_nocheck<ModeHandler>
133 {
134  public:
135  UserModeReference(Module* mod, const std::string& modename)
136  : dynamic_reference_nocheck<ModeHandler>(mod, "umode/" + modename) {}
137 };
Definition: dynref.h:126
Definition: mode.h:100
Definition: base.h:178
Definition: modules.h:286
Definition: base.h:204
Definition: dynref.h:133
Definition: dynref.h:26
void SetCaptureHook(CaptureHook *h)
Definition: dynref.h:54
Definition: dynref.h:98
Definition: dynref.h:69
Definition: intrusive_list.h:34