mirror of https://github.com/JAJames/jessilib.git
Jessica James
4 years ago
7 changed files with 356 additions and 9 deletions
@ -0,0 +1,50 @@ |
|||||
|
/**
|
||||
|
* Copyright (C) 2019 Jessica James. |
||||
|
* |
||||
|
* Permission to use, copy, modify, and/or distribute this software for any |
||||
|
* purpose with or without fee is hereby granted, provided that the above |
||||
|
* copyright notice and this permission notice appear in all copies. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
* |
||||
|
* Written by Jessica James <jessica.aj@outlook.com> |
||||
|
*/ |
||||
|
|
||||
|
#include "io/command.hpp" |
||||
|
#include "io/command_manager.hpp" |
||||
|
|
||||
|
namespace jessilib { |
||||
|
namespace io { |
||||
|
|
||||
|
command::command(callback_t in_callback, std::string_view in_label) |
||||
|
: m_callback{ std::move(in_callback) }, |
||||
|
m_label{ std::move(in_label) } { |
||||
|
// Register command
|
||||
|
command_manager::instance().register_command(*this); |
||||
|
} |
||||
|
|
||||
|
command::~command() { |
||||
|
// Unregister command
|
||||
|
command_manager::instance().unregister_command(*this); |
||||
|
} |
||||
|
|
||||
|
std::string_view command::label() const { |
||||
|
return m_label; |
||||
|
} |
||||
|
|
||||
|
void command::execute(command_context& in_context) const { |
||||
|
m_callback(in_context); |
||||
|
} |
||||
|
|
||||
|
command test_command{ [](command_context&) { |
||||
|
// do stuff
|
||||
|
}, "test" }; |
||||
|
|
||||
|
} // namespace io
|
||||
|
} // namespace jessilib
|
@ -0,0 +1,97 @@ |
|||||
|
/**
|
||||
|
* Copyright (C) 2019 Jessica James. |
||||
|
* |
||||
|
* Permission to use, copy, modify, and/or distribute this software for any |
||||
|
* purpose with or without fee is hereby granted, provided that the above |
||||
|
* copyright notice and this permission notice appear in all copies. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
* |
||||
|
* Written by Jessica James <jessica.aj@outlook.com> |
||||
|
*/ |
||||
|
|
||||
|
#include "io/command_context.hpp" |
||||
|
|
||||
|
namespace jessilib { |
||||
|
namespace io { |
||||
|
|
||||
|
command_context::command_context(std::string_view in_input) |
||||
|
: m_input{ in_input } { |
||||
|
// Strip leading whitespace
|
||||
|
std::size_t pos = in_input.find_first_not_of(' '); |
||||
|
if (pos != std::string_view::npos) { |
||||
|
in_input.remove_prefix(pos); |
||||
|
|
||||
|
// Whitespace is stripped; parse keyword from input
|
||||
|
pos = in_input.find(' '); |
||||
|
if (pos == std::string_view::npos) { |
||||
|
pos = in_input.size(); |
||||
|
} |
||||
|
m_keyword = in_input.substr(0, pos); |
||||
|
in_input.remove_prefix(pos); |
||||
|
|
||||
|
// Strip leading whitespace and parse parameter from remaining input
|
||||
|
pos = in_input.find_first_not_of(' '); |
||||
|
if (pos != std::string_view::npos) { |
||||
|
in_input.remove_prefix(pos); |
||||
|
m_parameter = in_input; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
command_context::command_context(std::string_view in_input, std::string_view in_keyword, std::string_view in_parameter) |
||||
|
: m_input{ std::move(in_input) }, |
||||
|
m_keyword{ std::move(in_keyword) }, |
||||
|
m_parameter{ std::move(in_parameter) } { |
||||
|
// Empty ctor body
|
||||
|
} |
||||
|
|
||||
|
std::string_view command_context::input() const { |
||||
|
return m_input; |
||||
|
} |
||||
|
|
||||
|
std::string_view command_context::keyword() const { |
||||
|
return m_keyword; |
||||
|
} |
||||
|
|
||||
|
std::string_view command_context::parameter() const { |
||||
|
return m_parameter; |
||||
|
} |
||||
|
|
||||
|
std::vector<std::string_view> command_context::paramaters() const { |
||||
|
std::vector<std::string_view> result; |
||||
|
std::string_view parameter = m_parameter; |
||||
|
|
||||
|
// Strip leading whitespace
|
||||
|
std::size_t pos = parameter.find_first_not_of(' '); |
||||
|
if (pos == std::string_view::npos) { |
||||
|
// parameter is empty; return empty vector
|
||||
|
return result; |
||||
|
} |
||||
|
parameter.remove_prefix(pos); |
||||
|
|
||||
|
// Parse parameter into result
|
||||
|
while (!parameter.empty()) { |
||||
|
// Parse word from parameter into result
|
||||
|
pos = parameter.find(' '); |
||||
|
if (pos == std::string_view::npos) { |
||||
|
pos = parameter.size(); |
||||
|
} |
||||
|
result.push_back(parameter.substr(0, pos)); |
||||
|
|
||||
|
// Strip word and trailing whitespace
|
||||
|
parameter.remove_prefix(pos); |
||||
|
parameter.remove_prefix(std::min(parameter.find_first_not_of(' '), parameter.size())); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
}; |
||||
|
|
||||
|
} // namespace io
|
||||
|
} // namespace jessilib
|
@ -0,0 +1,65 @@ |
|||||
|
/**
|
||||
|
* Copyright (C) 2019 Jessica James. |
||||
|
* |
||||
|
* Permission to use, copy, modify, and/or distribute this software for any |
||||
|
* purpose with or without fee is hereby granted, provided that the above |
||||
|
* copyright notice and this permission notice appear in all copies. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
* |
||||
|
* Written by Jessica James <jessica.aj@outlook.com> |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <string_view> |
||||
|
#include <functional> |
||||
|
#include "command_context.hpp" |
||||
|
|
||||
|
namespace jessilib { |
||||
|
namespace io { |
||||
|
|
||||
|
class basic_command { |
||||
|
public: |
||||
|
virtual ~basic_command() = default; |
||||
|
virtual std::string_view label() const = 0; |
||||
|
virtual void execute(command_context& in_context) const = 0; |
||||
|
}; // class basic_command
|
||||
|
|
||||
|
class command : public basic_command { |
||||
|
public: |
||||
|
// Types
|
||||
|
using callback_t = std::function<void(command_context&)>; |
||||
|
|
||||
|
// Delete all implicit constructors and assignment operators
|
||||
|
command() = delete; |
||||
|
command(const command&) = delete; |
||||
|
command(command&&) = delete; |
||||
|
command& operator=(const command&) = delete; |
||||
|
command& operator=(command&&) = delete; |
||||
|
|
||||
|
// Instantiates and self-registers a command
|
||||
|
command(callback_t in_callback, std::string_view in_label); |
||||
|
|
||||
|
// Cleans up and unregisters the command
|
||||
|
virtual ~command(); |
||||
|
|
||||
|
// Unique label associated with command
|
||||
|
virtual std::string_view label() const override; |
||||
|
|
||||
|
// Executes the command
|
||||
|
virtual void execute(command_context& in_context) const override; |
||||
|
|
||||
|
private: |
||||
|
callback_t m_callback; |
||||
|
std::string_view m_label; |
||||
|
}; // class command
|
||||
|
|
||||
|
} // namespace io
|
||||
|
} // namespace jessilib
|
@ -0,0 +1,54 @@ |
|||||
|
/**
|
||||
|
* Copyright (C) 2019 Jessica James. |
||||
|
* |
||||
|
* Permission to use, copy, modify, and/or distribute this software for any |
||||
|
* purpose with or without fee is hereby granted, provided that the above |
||||
|
* copyright notice and this permission notice appear in all copies. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
* |
||||
|
* Written by Jessica James <jessica.aj@outlook.com> |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <string_view> |
||||
|
#include "object.hpp" |
||||
|
#include "message.hpp" |
||||
|
|
||||
|
namespace jessilib { |
||||
|
namespace io { |
||||
|
|
||||
|
class command_context { |
||||
|
public: |
||||
|
command_context(std::string_view in_input); |
||||
|
command_context(std::string_view in_input, std::string_view in_keyword, std::string_view in_parameter); |
||||
|
|
||||
|
/** User input */ |
||||
|
std::string_view input() const; |
||||
|
std::string_view keyword() const; |
||||
|
std::string_view parameter() const; |
||||
|
std::vector<std::string_view> paramaters() const; |
||||
|
|
||||
|
/** Reply */ |
||||
|
virtual bool privateReply(const formatted_message& in_message); // Reply to invoker privately (i.e: PM)
|
||||
|
virtual bool publicReply(const formatted_message& in_message); // Reply to invoker publicly (i.e: channel)
|
||||
|
|
||||
|
/** Additional contextual details */ |
||||
|
virtual object details() const = 0; // Additional details
|
||||
|
virtual std::string getText(std::string_view tag) const = 0; // Get localized text
|
||||
|
|
||||
|
private: |
||||
|
std::string_view m_input; |
||||
|
std::string_view m_keyword; |
||||
|
std::string_view m_parameter; |
||||
|
}; // class command_context
|
||||
|
|
||||
|
} // namespace io
|
||||
|
} // namespace jessilib
|
@ -0,0 +1,69 @@ |
|||||
|
/**
|
||||
|
* Copyright (C) 2019 Jessica James. |
||||
|
* |
||||
|
* Permission to use, copy, modify, and/or distribute this software for any |
||||
|
* purpose with or without fee is hereby granted, provided that the above |
||||
|
* copyright notice and this permission notice appear in all copies. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
* |
||||
|
* Written by Jessica James <jessica.aj@outlook.com> |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <shared_mutex> |
||||
|
#include "command.hpp" |
||||
|
|
||||
|
namespace jessilib { |
||||
|
namespace io { |
||||
|
|
||||
|
class command_manager { |
||||
|
public: |
||||
|
struct entry { |
||||
|
basic_command* m_command; |
||||
|
}; |
||||
|
|
||||
|
void register_command(basic_command& in_command); |
||||
|
void unregister_command(basic_command& in_command); |
||||
|
bool execute_command(const command_context& in_context); |
||||
|
|
||||
|
// executes a predicate for each command, until the predicate returns false or no commands remain
|
||||
|
template<typename predicate_t> // TODO: add check for non-const
|
||||
|
void foreach(predicate_t&& in_predicate) { |
||||
|
std::lock_guard<std::shared_mutex> guard{ m_commands_mutex }; |
||||
|
for (auto& command_entry : m_commands) { |
||||
|
if (!in_predicate(command_entry)) { |
||||
|
// Predicate returned false; we're done here
|
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// executes a predicate for each command, until the predicate returns false or no commands remain
|
||||
|
template<typename predicate_t> // TODO: add check for const
|
||||
|
void foreach(predicate_t&& in_predicate) const { |
||||
|
std::shared_lock<std::shared_mutex> guard{ m_commands_mutex }; |
||||
|
for (const auto& command_entry : m_commands) { |
||||
|
if (!in_predicate(command_entry)) { |
||||
|
// Predicate returned false; we're done here
|
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static command_manager& instance(); |
||||
|
|
||||
|
private: |
||||
|
std::vector<entry> m_commands; |
||||
|
mutable std::shared_mutex m_commands_mutex; |
||||
|
}; |
||||
|
|
||||
|
} // namespace io
|
||||
|
} // namespace jessilib
|
Loading…
Reference in new issue