1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#ifndef COMPONENTS_LUA_INPUTACTIONS
#define COMPONENTS_LUA_INPUTACTIONS
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
#include <sol/sol.hpp>
#include <components/lua/asyncpackage.hpp>
#include <components/lua/scriptscontainer.hpp>
#include <components/misc/algorithm.hpp>
namespace LuaUtil::InputAction
{
enum class Type
{
Boolean,
Number,
Range,
};
struct Info
{
std::string mKey;
Type mType;
std::string mL10n;
std::string mName;
std::string mDescription;
sol::main_object mDefaultValue;
bool mPersistent;
};
class MultiTree
{
public:
using Node = size_t;
Node insert();
bool multiEdge(Node target, const std::vector<Node>& source);
size_t size() const { return mParents.size(); }
template <typename Function> // Function = void(Node)
void traverse(Function callback) const;
void clear()
{
mParents.clear();
mChildren.clear();
}
private:
std::vector<std::vector<Node>> mParents;
std::vector<std::vector<Node>> mChildren;
bool validateTree() const;
};
class Registry
{
public:
using ConstIterator = std::vector<Info>::const_iterator;
void insert(const Info& info);
size_t size() const { return mKeys.size(); }
std::optional<std::string> firstKey() const { return mKeys.empty() ? std::nullopt : std::optional(mKeys[0]); }
std::optional<std::string> nextKey(std::string_view key) const;
std::optional<Info> operator[](std::string_view actionKey);
bool bind(
std::string_view key, const LuaUtil::Callback& callback, const std::vector<std::string_view>& dependencies);
sol::object valueOfType(std::string_view key, Type type);
void update(double dt);
void registerHandler(std::string_view key, const LuaUtil::Callback& handler)
{
mHandlers[safeIdByKey(key)].push_back(handler);
}
void clear(bool force = false);
private:
using Id = MultiTree::Node;
Id safeIdByKey(std::string_view key);
struct Binding
{
LuaUtil::Callback mCallback;
std::vector<Id> mDependencies;
};
std::vector<std::string> mKeys;
std::unordered_map<std::string, Id, Misc::StringUtils::StringHash, std::equal_to<>> mIds;
std::vector<Info> mInfo;
std::vector<std::vector<LuaUtil::Callback>> mHandlers;
std::vector<std::vector<Binding>> mBindings;
std::vector<sol::object> mValues;
MultiTree mBindingTree;
};
}
namespace LuaUtil::InputTrigger
{
struct Info
{
std::string mKey;
std::string mL10n;
std::string mName;
std::string mDescription;
bool mPersistent;
};
class Registry
{
public:
std::optional<std::string> firstKey() const
{
return mIds.empty() ? std::nullopt : std::optional(mIds.begin()->first);
}
std::optional<std::string> nextKey(std::string_view key) const
{
auto it = mIds.find(key);
if (it == mIds.end() || ++it == mIds.end())
return std::nullopt;
return it->first;
}
std::optional<Info> operator[](std::string_view key);
void insert(const Info& info);
void registerHandler(std::string_view key, const LuaUtil::Callback& callback);
void activate(std::string_view key);
void clear(bool force = false);
private:
using Id = size_t;
Id safeIdByKey(std::string_view key);
std::unordered_map<std::string, Id, Misc::StringUtils::StringHash, std::equal_to<>> mIds;
std::vector<Info> mInfo;
std::vector<std::vector<LuaUtil::Callback>> mHandlers;
};
}
#endif // COMPONENTS_LUA_INPUTACTIONS
|