#pragma once #include <memory> #include <string> #include <unordered_map> #include <vector> #ifdef VOID #undef VOID #endif namespace Retro { class Variant { public: enum class Type { BOOL, INT, FLOAT, VOID }; Variant() {} Variant(int64_t); Variant(double); Variant(bool); template<typename T> T cast() const { switch (m_type) { case Type::BOOL: return m_vb; case Type::INT: return m_vi; case Type::FLOAT: return m_vf; case Type::VOID: default: return T(); } } operator int() const; operator int64_t() const; operator float() const; operator double() const; operator bool() const; private: Type m_type = Type::VOID; union { bool m_vb; int64_t m_vi; double m_vf; }; }; class GameData; class ScriptContext { public: static std::shared_ptr<ScriptContext> get(const std::string& type); static std::vector<std::string> listContexts(); static void reset(); virtual void setData(const GameData*); virtual bool init() = 0; virtual bool load(const std::string&) = 0; virtual Variant callFunction(const std::string&) = 0; virtual std::vector<std::string> listFunctions() = 0; protected: const GameData* data(); private: const GameData* m_data; }; }