Browse Source

Committing various work which was apparently never committed; should break out of that habit

master
Jessica James 3 years ago
parent
commit
1a78688d0d
  1. 2
      CMakeLists.txt
  2. 2
      build/GNU/CMakeLists.txt
  3. 3
      src/bot/CMakeLists.txt
  4. 60
      src/bot/base_commands.cpp
  5. 48
      src/bot/console/console.cpp
  6. 30
      src/bot/console/console.hpp
  7. 53
      src/bot/console/console_command_context.cpp
  8. 41
      src/bot/console/console_command_context.hpp
  9. 5
      src/bot/main.cpp
  10. 38
      src/bot/shutdown.cpp
  11. 29
      src/bot/shutdown.hpp
  12. 2
      src/common/CMakeLists.txt
  13. 2
      src/common/app_parameters.cpp
  14. 52
      src/common/io/command_manager.cpp
  15. 3
      src/common/parsers/json.cpp
  16. 44
      src/common/unicode.cpp
  17. 2
      src/include/io/ansi/ansi_text.hpp
  18. 4
      src/include/io/command_context.hpp
  19. 14
      src/include/io/command_manager.hpp
  20. 2
      src/include/io/irc/irc_text.hpp
  21. 13
      src/include/unicode.hpp
  22. 2
      src/test/CMakeLists.txt

2
CMakeLists.txt

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.8)
project(jessilib)
# Set common constants
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(JESSILIB_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
# Include compiler-specific build configuration

2
build/GNU/CMakeLists.txt

@ -10,4 +10,4 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
# Enable std::filesystem
set(JESSILIB_ADDITOINAL_LIBS "stdc++fs")
set(JESSILIB_ADDITOINAL_LIBS "stdc++fs" pthread)

3
src/bot/CMakeLists.txt

@ -1,6 +1,7 @@
# Setup source files
set(SOURCE_FILES
main.cpp)
main.cpp
console/console_command_context.cpp console/console.cpp shutdown.cpp base_commands.cpp)
# Setup executable build target
add_executable(jessibot ${SOURCE_FILES})

60
src/bot/base_commands.cpp

@ -0,0 +1,60 @@
/**
* Copyright (C) 2020 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"
#include "shutdown.hpp"
namespace jessibot {
namespace io {
using namespace jessilib::io;
command quit_command{ [](command_context& context) {
using namespace jessilib::io;
text quit_text{ "Closing jessibot", text::property::bold, color{ 0xFF0000 } }; // TODO: localize
context.publicReply(formatted_message{ "{}", quit_text });
notify_shutdown();
}, "quit" };
// ISSUE: help command has no way to know what commands exist for the given context
command help_command{ [](command_context& context) {
auto details = context.details();
auto table_name = details["table"].get<std::string>();
if (table_name.empty()) {
text error_text{ "ERROR", text::property::bold, color{ 0xFF0000 } }; // TODO: localize
context.publicReply(formatted_message{ "{} command context is missing permission table name", error_text });
return;
}
// table examples: "console", "irc", "irc+", "irc%", "irc@"; should table instead be 'tables'?
text table_text{ table_name, text::property::bold, color{ 0x0000FF } };
context.publicReply(formatted_message{ "Commands for table '{}':", table_text });
// TODO: read some permission table and filter commands based upon permission and context information
const command_manager& manager = command_manager::instance();
manager.foreach([&context](basic_command* in_command) {
context.publicReply(formatted_message{ "{}", in_command->label() });
return true;
});
}, "help" };
} // namespace io
} // namespace jessibot

48
src/bot/console/console.cpp

@ -0,0 +1,48 @@
/**
* Copyright (C) 2020 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 "console.hpp"
#include <iostream>
#include "io/command_manager.hpp"
#include "io/ansi/ansi_text.hpp"
#include "shutdown.hpp"
#include "console/console_command_context.hpp"
namespace jessibot {
namespace io {
void console_input_loop() {
using namespace jessilib::io;
std::string input;
auto shutdown_future = get_shutdown_future();
while (shutdown_future.wait_for(std::chrono::milliseconds(10)) != std::future_status::ready) {
std::getline(std::cin, input); // TODO: use a non-bloicking call and poll running periodically
jessibot::io::console_command_context context{ input };
if (!command_manager::instance().execute_command(context)) {
text error_text{ "ERROR", text::property::bold, color{ 0xFF0000 }};
text keyword_text{ context.keyword(), text::property::bold, color{ 0x0000FF }};
auto result = process_message<ansi::text_wrapper>(formatted_message{"{} Command \"{}\" not found", error_text, keyword_text});
std::cout << result << std::endl;
}
}
}
} // namespace io
} // namespace jessibot

30
src/bot/console/console.hpp

@ -0,0 +1,30 @@
/**
* Copyright (C) 2020 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 <atomic>
namespace jessibot {
namespace io {
void console_input_loop();
} // namespace io
} // namespace jessibot

53
src/bot/console/console_command_context.cpp

@ -0,0 +1,53 @@
/**
* Copyright (C) 2020 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 "console_command_context.hpp"
#include <iostream>
#include "io/ansi/ansi_text.hpp"
namespace jessibot {
namespace io {
/** Reply */
bool console_command_context::privateReply(const jessilib::io::formatted_message& in_message) {
auto result = jessilib::io::process_message<jessilib::io::ansi::text_wrapper>(in_message);
std::cout << result << std::endl;
return true;
}
bool console_command_context::publicReply(const jessilib::io::formatted_message& in_message) {
// Consoles only have 1 output mechanism
return privateReply(in_message);
}
/** Additional contextual details */
jessilib::object console_command_context::details() const {
static jessilib::object s_details {
jessilib::object::map_t{ { "table", "console" } }
};
return s_details;
}
std::string console_command_context::getText(std::string_view tag) const {
return { tag.begin(), tag.end() }; // TODO: implement properly
}
} // namespace io
} // namespace jessilib

41
src/bot/console/console_command_context.hpp

@ -0,0 +1,41 @@
/**
* Copyright (C) 2020 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 "io/command_context.hpp"
namespace jessibot {
namespace io {
class console_command_context : public jessilib::io::command_context {
public:
using jessilib::io::command_context::command_context;
/** Reply */
bool privateReply(const jessilib::io::formatted_message& in_message) override;
bool publicReply(const jessilib::io::formatted_message& in_message) override;
/** Additional contextual details */
jessilib::object details() const override;
std::string getText(std::string_view tag) const override;
}; // class console_command_context
} // namespace io
} // namespace jessibot

5
src/bot/main.cpp

@ -16,12 +16,10 @@
* Written by Jessica James <jessica.aj@outlook.com>
*/
#include <unordered_set>
#include <iostream>
#include "app_parameters.hpp"
#include "parsers/json.hpp"
// TODO: input loop
#include "console/console.hpp"
int main(int argc, char** argv) {
jessilib::app_parameters parameters{ argc, argv };
@ -31,5 +29,6 @@ int main(int argc, char** argv) {
std::cout << std::endl << jessilib::json_parser{}.serialize(parameters) << std::endl;
}
jessibot::io::console_input_loop();
return 0;
}

38
src/bot/shutdown.cpp

@ -0,0 +1,38 @@
/**
* Copyright (C) 2020 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 "shutdown.hpp"
namespace jessibot {
std::promise<void>& shutdown_promise() {
static std::promise<void> s_shutdown_promise;
return s_shutdown_promise;
}
std::shared_future<void> get_shutdown_future() {
static std::shared_future<void> s_shutdown_future{ shutdown_promise().get_future().share() };
return s_shutdown_future;
}
void notify_shutdown() {
shutdown_promise().set_value();
}
} // namespace jessibot

29
src/bot/shutdown.hpp

@ -0,0 +1,29 @@
/**
* Copyright (C) 2020 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 <future>
namespace jessibot {
std::shared_future<void> get_shutdown_future();
void notify_shutdown();
} // namespace jessibot

2
src/common/CMakeLists.txt

@ -1,6 +1,6 @@
# Setup source files
set(SOURCE_FILES
timer/timer.cpp timer/timer_manager.cpp thread_pool.cpp timer/timer_context.cpp timer/cancel_token.cpp timer/synchronized_timer.cpp object.cpp parser/parser.cpp parser/parser_manager.cpp config.cpp serialize.cpp parsers/json.cpp unicode.cpp io/command.cpp io/command_context.cpp io/message.cpp app_parameters.cpp)
timer/timer.cpp timer/timer_manager.cpp thread_pool.cpp timer/timer_context.cpp timer/cancel_token.cpp timer/synchronized_timer.cpp object.cpp parser/parser.cpp parser/parser_manager.cpp config.cpp serialize.cpp parsers/json.cpp unicode.cpp io/command.cpp io/command_context.cpp io/message.cpp app_parameters.cpp io/command_manager.cpp)
# Setup library build target
add_library(jessilib ${SOURCE_FILES})

2
src/common/app_parameters.cpp

@ -35,7 +35,7 @@ app_parameters::app_parameters(int in_argc, const char** in_argv) {
m_path = in_argv[0];
// Process args
std::string_view key{ nullptr };
std::string_view key;
std::string value;
auto flush_value = [&key, &value, this]() {
// This is the start of a key; flush what we were previously processing

52
src/common/io/command_manager.cpp

@ -0,0 +1,52 @@
/**
* Copyright (C) 2020 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_manager.hpp"
namespace jessilib {
namespace io {
void command_manager::register_command(basic_command& in_command) {
std::lock_guard<std::shared_mutex> guard{ m_commands_mutex };
m_commands.push_back(&in_command);
}
void command_manager::unregister_command(basic_command& in_command) {
std::lock_guard<std::shared_mutex> guard{ m_commands_mutex };
std::remove(m_commands.begin(), m_commands.end(), &in_command);
}
bool command_manager::execute_command(command_context& in_context) {
std::shared_lock<std::shared_mutex> lock{ m_commands_mutex };
for (auto& command : m_commands) {
if (in_context.keyword() == command->label()) {
command->execute(in_context);
return true;
}
}
return false;
}
command_manager& command_manager::instance() {
static command_manager s_command_manager;
return s_command_manager;
}
} // namespace io
} // namespace jessilib

3
src/common/parsers/json.cpp

@ -259,6 +259,7 @@ std::string read_json_string(std::string_view& in_data) {
// Valid unicode sequence
result += in_data.substr(0, codepoint.units);
//result.append(reinterpret_cast<const char8_t*>(in_data.data()), codepoint.units);
in_data.remove_prefix(codepoint.units);
break;
}
@ -539,4 +540,4 @@ std::string json_parser::serialize(const object& in_object) {
}
}
} // namespace jessilib
} // namespace jessilib

44
src/common/unicode.cpp

@ -32,7 +32,7 @@ void append_helper(std::basic_ostream<T>& out_string, T in_value) {
out_string << in_value;
}
template<typename T>
template<typename T, typename CharT>
size_t encode_codepoint_utf8(T& out_destination, char32_t in_codepoint) {
if (in_codepoint > 0x10FFFF) {
return 0;
@ -40,30 +40,30 @@ size_t encode_codepoint_utf8(T& out_destination, char32_t in_codepoint) {
if (in_codepoint <= 0x007F) {
// 1-byte sequence (7 bits)
append_helper(out_destination, static_cast<char>(in_codepoint));
append_helper(out_destination, static_cast<CharT>(in_codepoint));
return 1;
}
if (in_codepoint <= 0x07FF) {
// 2-byte sequence (11 bits; 5 + 6)
append_helper(out_destination, static_cast<char>(0xC0 | ((in_codepoint >> 6) & 0x1F)));
append_helper(out_destination, static_cast<char>(0x80 | (in_codepoint & 0x3F)));
append_helper(out_destination, static_cast<CharT>(0xC0 | ((in_codepoint >> 6) & 0x1F)));
append_helper(out_destination, static_cast<CharT>(0x80 | (in_codepoint & 0x3F)));
return 2;
}
if (in_codepoint <= 0xFFFF) {
// 3-byte sequence (16 bits; 4 + 6 + 6)
append_helper(out_destination, static_cast<char>(0xE0 | ((in_codepoint >> 12) & 0x0F)));
append_helper(out_destination, static_cast<char>(0x80 | ((in_codepoint >> 6) & 0x3F)));
append_helper(out_destination, static_cast<char>(0x80 | (in_codepoint & 0x3F)));
append_helper(out_destination, static_cast<CharT>(0xE0 | ((in_codepoint >> 12) & 0x0F)));
append_helper(out_destination, static_cast<CharT>(0x80 | ((in_codepoint >> 6) & 0x3F)));
append_helper(out_destination, static_cast<CharT>(0x80 | (in_codepoint & 0x3F)));
return 3;
}
// 4-byte sequence (21 bits; 3 + 6 + 6 + 6)
append_helper(out_destination, static_cast<char>(0xF0 | ((in_codepoint >> 18) & 0x07)));
append_helper(out_destination, static_cast<char>(0x80 | ((in_codepoint >> 12) & 0x3F)));
append_helper(out_destination, static_cast<char>(0x80 | ((in_codepoint >> 6) & 0x3F)));
append_helper(out_destination, static_cast<char>(0x80 | (in_codepoint & 0x3F)));
append_helper(out_destination, static_cast<CharT>(0xF0 | ((in_codepoint >> 18) & 0x07)));
append_helper(out_destination, static_cast<CharT>(0x80 | ((in_codepoint >> 12) & 0x3F)));
append_helper(out_destination, static_cast<CharT>(0x80 | ((in_codepoint >> 6) & 0x3F)));
append_helper(out_destination, static_cast<CharT>(0x80 | (in_codepoint & 0x3F)));
return 4;
}
@ -97,7 +97,11 @@ size_t encode_codepoint_utf32(T& out_destination, char32_t in_codepoint) {
}
size_t encode_codepoint(std::string& out_string, char32_t in_codepoint) {
return encode_codepoint_utf8(out_string, in_codepoint);
return encode_codepoint_utf8<std::string, char>(out_string, in_codepoint);
}
size_t encode_codepoint(std::u8string& out_string, char32_t in_codepoint) {
return encode_codepoint_utf8<std::u8string, char8_t>(out_string, in_codepoint);
}
size_t encode_codepoint(std::u16string& out_string, char32_t in_codepoint) {
@ -109,7 +113,11 @@ size_t encode_codepoint(std::u32string& out_string, char32_t in_codepoint) {
}
size_t encode_codepoint(std::basic_ostream<char>& out_stream, char32_t in_codepoint) {
return encode_codepoint_utf8(out_stream, in_codepoint);
return encode_codepoint_utf8<std::basic_ostream<char>, char>(out_stream, in_codepoint);
}
size_t encode_codepoint(std::basic_ostream<char8_t>& out_stream, char32_t in_codepoint) {
return encode_codepoint_utf8<std::basic_ostream<char8_t>, char8_t>(out_stream, in_codepoint);
}
size_t encode_codepoint(std::basic_ostream<char16_t>& out_stream, char32_t in_codepoint) {
@ -120,8 +128,8 @@ size_t encode_codepoint(std::basic_ostream<char32_t>& out_stream, char32_t in_co
return encode_codepoint_utf32(out_stream, in_codepoint);
}
std::string encode_codepoint_u8(char32_t in_codepoint) {
std::string result;
std::u8string encode_codepoint_u8(char32_t in_codepoint) {
std::u8string result;
encode_codepoint(result, in_codepoint);
return result;
}
@ -141,6 +149,10 @@ std::u32string encode_codepoint_u32(char32_t in_codepoint) {
/** decode_codepoint */
get_endpoint_result decode_codepoint(const std::string_view& in_string) {
return decode_codepoint(std::u8string_view{ reinterpret_cast<const char8_t*>(in_string.data()), in_string.size() });
}
get_endpoint_result decode_codepoint(const std::u8string_view& in_string) {
get_endpoint_result result{ 0, 0 };
if (in_string.empty()) {
@ -254,4 +266,4 @@ get_endpoint_result decode_surrogate_pair(char16_t in_high_surrogate, char16_t i
return { 0, 0 };
}
} // namespace jessilib
} // namespace jessilib

2
src/include/io/ansi/ansi_text.hpp

@ -50,7 +50,7 @@ static constexpr std::string_view COLOR_BG_DEFAULT{ "49" };
} // namespace ansi
template<>
std::string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper& in_text) {
inline std::string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper& in_text) {
std::string result;
result.reserve(in_text.string().size() + 8);

4
src/include/io/command_context.hpp

@ -37,8 +37,8 @@ public:
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)
virtual bool privateReply(const formatted_message& in_message) = 0; // Reply to invoker privately (i.e: PM)
virtual bool publicReply(const formatted_message& in_message) = 0; // Reply to invoker publicly (i.e: channel)
/** Additional contextual details */
virtual object details() const = 0; // Additional details

14
src/include/io/command_manager.hpp

@ -26,13 +26,9 @@ 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);
bool execute_command(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
@ -61,9 +57,13 @@ public:
static command_manager& instance();
private:
std::vector<entry> m_commands;
//struct entry {
// basic_command* m_command;
//};
std::vector<basic_command*> m_commands;
mutable std::shared_mutex m_commands_mutex;
};
} // namespace io
} // namespace jessilib
} // namespace jessilib

2
src/include/io/irc/irc_text.hpp

@ -138,7 +138,7 @@ text::property properties_to_toggle(text::property in_active_properties, text::p
} // namespace irc
template<>
std::string text_to_string<irc::text_wrapper>(const irc::text_wrapper& in_text) {
inline std::string text_to_string<irc::text_wrapper>(const irc::text_wrapper& in_text) {
std::string result;
result.reserve(in_text.string().size() + 8);

13
src/include/unicode.hpp

@ -26,13 +26,15 @@ namespace jessilib {
/** encode_codepoint */
size_t encode_codepoint(std::string& out_string, char32_t in_codepoint);
size_t encode_codepoint(std::string& out_string, char32_t in_codepoint); // ASSUMES UTF-8
size_t encode_codepoint(std::u8string& out_string, char32_t in_codepoint);
size_t encode_codepoint(std::u16string& out_string, char32_t in_codepoint);
size_t encode_codepoint(std::u32string& out_string, char32_t in_codepoint);
size_t encode_codepoint(std::basic_ostream<char>& out_stream, char32_t in_codepoint);
size_t encode_codepoint(std::basic_ostream<char>& out_stream, char32_t in_codepoint); // ASSUMES UTF-8
size_t encode_codepoint(std::basic_ostream<char8_t>& out_stream, char32_t in_codepoint);
size_t encode_codepoint(std::basic_ostream<char16_t>& out_stream, char32_t in_codepoint);
size_t encode_codepoint(std::basic_ostream<char32_t>& out_stream, char32_t in_codepoint);
std::string encode_codepoint_u8(char32_t in_codepoint);
std::u8string encode_codepoint_u8(char32_t in_codepoint);
std::u16string encode_codepoint_u16(char32_t in_codepoint);
std::u32string encode_codepoint_u32(char32_t in_codepoint);
@ -43,7 +45,8 @@ struct get_endpoint_result {
size_t units{};
};
get_endpoint_result decode_codepoint(const std::string_view& in_string); // UTF-8
get_endpoint_result decode_codepoint(const std::string_view& in_string); // ASSUMES UTF-8
get_endpoint_result decode_codepoint(const std::u8string_view& in_string); // UTF-8
get_endpoint_result decode_codepoint(const std::u16string_view& in_string); // UTF-16
get_endpoint_result decode_codepoint(const std::u32string_view& in_string); // UTF-32
@ -59,7 +62,7 @@ char32_t advance_codepoint(std::basic_string_view<T>& in_string) {
/** next_codepoint */
template<typename T>
std::string_view next_codepoint(const std::basic_string_view<T>& in_string) {
std::basic_string_view<T> next_codepoint(const std::basic_string_view<T>& in_string) {
return in_string.substr(decode_codepoint(in_string).units);
}

2
src/test/CMakeLists.txt

@ -1,6 +1,6 @@
# Setup source files
set(SOURCE_FILES
timer.cpp thread_pool.cpp util.cpp object.cpp parser.cpp config.cpp parsers/json.cpp unicode.cpp app_parameters.cpp io/color.cpp)
timer.cpp thread_pool.cpp util.cpp object.cpp parser.cpp config.cpp parsers/json.cpp unicode.cpp app_parameters.cpp io/color.cpp duration.cpp)
# Setup gtest
add_subdirectory(googletest/googletest)

Loading…
Cancel
Save