5 #define PLUGIN_EXPORT __declspec(dllexport)
28 template<
typename M,
typename =
void>
29 struct HasPluginName : std::false_type {};
31 struct HasPluginName<M, std::void_t<decltype(M::name)>>
32 : std::is_convertible<decltype(M::name), const char*> {};
34 template<
typename M,
typename =
void>
35 struct HasPluginVersion : std::false_type {};
37 struct HasPluginVersion<M, std::void_t<decltype(M::version)>>
38 : std::is_convertible<decltype(M::version), const char*> {};
40 template<
typename M,
typename =
void>
41 struct HasThumbnail : std::false_type {};
43 struct HasThumbnail<M, std::void_t<decltype(M::Images::THUMBNAIL)>>
85 virtual const char*
getName()
const {
return "Unnamed Plugin"; }
91 virtual const char*
getVersion()
const {
return "1.0.0"; }
127 bool is()
const {
return dynamic_cast<const T*
>(
this) !=
nullptr; }
136 T*
getIf() {
return dynamic_cast<T*
>(
this); }
144 const T*
getIf()
const {
return dynamic_cast<const T*
>(
this); }
147 virtual Plugin* asPlugin() {
return this; }
153 template<
typename... Traits>
154 struct TraitsHaveCore : std::disjunction<
155 std::is_base_of<Core, Traits>...
158 template<
typename Manifest,
typename... Traits>
159 struct PluginBase :
public Plugin,
165 static_assert(HasPluginName<Manifest>::value,
166 "[Malena] Manifest is missing: static constexpr const char* name = \"Your Plugin Name\";");
167 static_assert(HasPluginVersion<Manifest>::value,
168 "[Malena] Manifest is missing: static constexpr const char* version = \"1.0.0\";");
170 using manifest_type = Manifest;
172 const char* getName()
const override {
return Manifest::name; }
173 const char* getVersion()
const override {
return Manifest::version; }
174 ml::Plugin* asPlugin()
override {
return this; }
176 const sf::Texture* getThumbnail()
const override
178 if constexpr (HasThumbnail<Manifest>::value)
184 using GatherFlags<Manifest, Traits...>::type::enableFlag;
185 using GatherFlags<Manifest, Traits...>::type::disableFlag;
186 using GatherFlags<Manifest, Traits...>::type::checkFlag;
187 using GatherFlags<Manifest, Traits...>::type::setFlag;
188 using GatherFlags<Manifest, Traits...>::type::toggleFlag;
190 using GatherStates<Manifest, Traits...>::type::setState;
191 using GatherStates<Manifest, Traits...>::type::getState;
192 using GatherStates<Manifest, Traits...>::type::isState;
193 using GatherStates<Manifest, Traits...>::type::onStateEnter;
194 using GatherStates<Manifest, Traits...>::type::onStateExit;
197 template<
typename Manifest,
typename... Traits>
198 struct PluginBaseWithCore :
public Plugin,
204 static_assert(HasPluginName<Manifest>::value,
205 "[Malena] Manifest is missing: static constexpr const char* name = \"Your Plugin Name\";");
206 static_assert(HasPluginVersion<Manifest>::value,
207 "[Malena] Manifest is missing: static constexpr const char* version = \"1.0.0\";");
209 using manifest_type = Manifest;
211 const char* getName()
const override {
return Manifest::name; }
212 const char* getVersion()
const override {
return Manifest::version; }
213 ml::Plugin* asPlugin()
override {
return this; }
215 const sf::Texture* getThumbnail()
const override
217 if constexpr (HasThumbnail<Manifest>::value)
223 using FlagManager<
ml::Flag>::enableFlag;
224 using FlagManager<
ml::Flag>::disableFlag;
225 using FlagManager<
ml::Flag>::checkFlag;
226 using FlagManager<
ml::Flag>::setFlag;
227 using FlagManager<
ml::Flag>::toggleFlag;
229 using GatherFlags<Manifest, Traits...>::type::enableFlag;
230 using GatherFlags<Manifest, Traits...>::type::disableFlag;
231 using GatherFlags<Manifest, Traits...>::type::checkFlag;
232 using GatherFlags<Manifest, Traits...>::type::setFlag;
233 using GatherFlags<Manifest, Traits...>::type::toggleFlag;
235 using GatherStates<Manifest, Traits...>::type::setState;
236 using GatherStates<Manifest, Traits...>::type::getState;
237 using GatherStates<Manifest, Traits...>::type::isState;
238 using GatherStates<Manifest, Traits...>::type::onStateEnter;
239 using GatherStates<Manifest, Traits...>::type::onStateExit;
267 template<
typename Manifest,
typename... Traits>
269 TraitsHaveCore<Traits...>::value,
270 PluginBaseWithCore<
Manifest, Traits...>,
284 template<
typename T,
typename =
void>
287 static ml::Plugin* create() {
return nullptr; }
292 struct PluginHelper<T, std::enable_if_t<std::is_base_of_v<ml::Plugin, T>>>
294 static ml::Plugin* create() {
return (
new T())->asPlugin(); }
295 static void destroy(ml::Plugin* p) {
delete p; }
329#define ML_EXPORT(ClassName) \
332 PLUGIN_EXPORT ml::Plugin* createPlugin() \
334 return ml::exports::PluginHelper<ClassName>::create(); \
336 PLUGIN_EXPORT void destroyPlugin(ml::Plugin* p) \
338 ml::exports::PluginHelper<ClassName>::destroy(p); \
342 namespace ml::exports { \
344 inline struct _Register_##ClassName \
346 _Register_##ClassName() \
348 ml::exports::FireableHelper<ClassName>::doRegister(); \
351 std::is_base_of_v<ml::Plugin, ClassName> || \
352 std::is_base_of_v<ml::Fireable, ClassName>, \
353 "[Malena] ML_EXPORT: '" #ClassName "' is not a " \
354 "recognised exportable Malena type. " \
355 "Must derive from ml::Plugin or ml::Fireable."); \
357 } _instance_##ClassName; \
Provides ML_EXPORT for registering Malena types at startup.
Tags a class with a manifest type and wires in its State manager.
Base class for all Malena manifests.
Abstract base class for all Malena plugins.
virtual const sf::Texture * getThumbnail() const
Return a pointer to this plugin's thumbnail texture, or nullptr.
virtual void onUnload()
Called just before the plugin is destroyed and unloaded.
bool is() const
Return true if this plugin is an instance of T.
const T * getIf() const
Const overload of getIf.
virtual const char * getVersion() const
Return the plugin's version string.
virtual const char * getName() const
Return the plugin's display name.
T * getIf()
Return a T* if this plugin is an instance of T, or nullptr otherwise.
virtual ~Plugin()=default
virtual void onLoad()
Called immediately after the plugin is loaded and constructed.
static const sf::Texture & get(const Asset &asset)
std::conditional_t< TraitsHaveCore< Traits... >::value, PluginBaseWithCore< Manifest, Traits... >, PluginBase< Manifest, Traits... > > PluginWith
Primary base class for manifest-driven plugins.
Flag
System-level boolean flags available on every ml::Core object.
Collects all Flag enums from a component manifest and its traits.
Collects all State enums from a component manifest and its traits.