8 #define PLUGIN_EXPORT __declspec(dllexport)
32 template<
typename M,
typename =
void>
33 struct HasPluginName : std::false_type {};
35 struct HasPluginName<M, std::void_t<decltype(M::name)>>
36 : std::is_convertible<decltype(M::name), const char*> {};
38 template<
typename M,
typename =
void>
39 struct HasPluginVersion : std::false_type {};
41 struct HasPluginVersion<M, std::void_t<decltype(M::version)>>
42 : std::is_convertible<decltype(M::version), const char*> {};
44 template<
typename M,
typename =
void>
45 struct HasThumbnail : std::false_type {};
47 struct HasThumbnail<M, std::void_t<decltype(M::Images::THUMBNAIL)>>
89 virtual const char*
getName()
const {
return "Unnamed Plugin"; }
95 virtual const char*
getVersion()
const {
return "1.0.0"; }
131 bool is()
const {
return dynamic_cast<const T*
>(
this) !=
nullptr; }
140 T*
getIf() {
return dynamic_cast<T*
>(
this); }
148 const T*
getIf()
const {
return dynamic_cast<const T*
>(
this); }
151 virtual Plugin* asPlugin() {
return this; }
157 template<
typename... Traits>
158 struct TraitsHaveCore : std::disjunction<
159 std::is_base_of<Core, Traits>...
162 template<
typename Manifest,
typename... Traits>
163 struct PluginBase :
public Plugin,
169 static_assert(HasPluginName<Manifest>::value,
170 "[Malena] Manifest is missing: static constexpr const char* name = \"Your Plugin Name\";");
171 static_assert(HasPluginVersion<Manifest>::value,
172 "[Malena] Manifest is missing: static constexpr const char* version = \"1.0.0\";");
174 using manifest_type = Manifest;
176 const char* getName()
const override {
return Manifest::name; }
177 const char* getVersion()
const override {
return Manifest::version; }
178 ml::Plugin* asPlugin()
override {
return this; }
180 const sf::Texture* getThumbnail()
const override
182 if constexpr (HasThumbnail<Manifest>::value)
188 using GatherFlags<Manifest, Traits...>::type::enableFlag;
189 using GatherFlags<Manifest, Traits...>::type::disableFlag;
190 using GatherFlags<Manifest, Traits...>::type::checkFlag;
191 using GatherFlags<Manifest, Traits...>::type::setFlag;
192 using GatherFlags<Manifest, Traits...>::type::toggleFlag;
194 using GatherStates<Manifest, Traits...>::type::setState;
195 using GatherStates<Manifest, Traits...>::type::getState;
196 using GatherStates<Manifest, Traits...>::type::isState;
197 using GatherStates<Manifest, Traits...>::type::onStateEnter;
198 using GatherStates<Manifest, Traits...>::type::onStateExit;
201 template<
typename Manifest,
typename... Traits>
202 struct PluginBaseWithCore :
public Plugin,
208 static_assert(HasPluginName<Manifest>::value,
209 "[Malena] Manifest is missing: static constexpr const char* name = \"Your Plugin Name\";");
210 static_assert(HasPluginVersion<Manifest>::value,
211 "[Malena] Manifest is missing: static constexpr const char* version = \"1.0.0\";");
213 using manifest_type = Manifest;
215 const char* getName()
const override {
return Manifest::name; }
216 const char* getVersion()
const override {
return Manifest::version; }
217 ml::Plugin* asPlugin()
override {
return this; }
219 const sf::Texture* getThumbnail()
const override
221 if constexpr (HasThumbnail<Manifest>::value)
227 using FlagManager<
ml::Flag>::enableFlag;
228 using FlagManager<
ml::Flag>::disableFlag;
229 using FlagManager<
ml::Flag>::checkFlag;
230 using FlagManager<
ml::Flag>::setFlag;
231 using FlagManager<
ml::Flag>::toggleFlag;
233 using GatherFlags<Manifest, Traits...>::type::enableFlag;
234 using GatherFlags<Manifest, Traits...>::type::disableFlag;
235 using GatherFlags<Manifest, Traits...>::type::checkFlag;
236 using GatherFlags<Manifest, Traits...>::type::setFlag;
237 using GatherFlags<Manifest, Traits...>::type::toggleFlag;
239 using GatherStates<Manifest, Traits...>::type::setState;
240 using GatherStates<Manifest, Traits...>::type::getState;
241 using GatherStates<Manifest, Traits...>::type::isState;
242 using GatherStates<Manifest, Traits...>::type::onStateEnter;
243 using GatherStates<Manifest, Traits...>::type::onStateExit;
271 template<
typename Manifest,
typename... Traits>
273 TraitsHaveCore<Traits...>::value,
274 PluginBaseWithCore<
Manifest, Traits...>,
288 template<
typename T,
typename =
void>
291 static ml::Plugin* create() {
return nullptr; }
296 struct PluginHelper<T, std::enable_if_t<std::is_base_of_v<ml::Plugin, T>>>
298 static ml::Plugin* create() {
return (
new T())->asPlugin(); }
299 static void destroy(ml::Plugin* p) {
delete p; }
333#define ML_EXPORT(ClassName) \
336 PLUGIN_EXPORT ml::Plugin* createPlugin() \
338 return ml::exports::PluginHelper<ClassName>::create(); \
340 PLUGIN_EXPORT void destroyPlugin(ml::Plugin* p) \
342 ml::exports::PluginHelper<ClassName>::destroy(p); \
346 namespace ml::exports { \
348 inline struct _Register_##ClassName \
350 _Register_##ClassName() \
352 ml::exports::FireableHelper<ClassName>::doRegister(); \
355 std::is_base_of_v<ml::Plugin, ClassName> || \
356 std::is_base_of_v<ml::Fireable, ClassName>, \
357 "[Malena] ML_EXPORT: '" #ClassName "' is not a " \
358 "recognised exportable Malena type. " \
359 "Must derive from ml::Plugin or ml::Fireable."); \
361 } _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.