You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/lua/inputactions.hpp

150 lines
4.1 KiB
C++

#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;
};
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()
{
mKeys.clear();
mIds.clear();
mInfo.clear();
mHandlers.clear();
mBindings.clear();
mValues.clear();
mBindingTree.clear();
}
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;
};
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()
{
mInfo.clear();
mHandlers.clear();
mIds.clear();
}
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