move to new build system
This commit is contained in:
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDE_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_
|
||||
#define INCLUDE_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_
|
||||
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class console_consumer final {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
console_consumer() { E_SUBSCRIBE_ALL(process_event); }
|
||||
|
||||
public:
|
||||
~console_consumer() { E_CONSUMER_RELEASE(); }
|
||||
|
||||
private:
|
||||
void process_event(const event &e) {
|
||||
#ifdef _WIN32
|
||||
#ifdef _DEBUG
|
||||
OutputDebugString((e.get_single_line() + "\n").c_str());
|
||||
#endif
|
||||
#endif
|
||||
if (e.get_event_level() == event_level::error) {
|
||||
std::cerr << e.get_single_line() << std::endl;
|
||||
} else {
|
||||
std::cout << e.get_single_line() << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDE_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_
|
||||
#define INCLUDE_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_
|
||||
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class logging_consumer {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
logging_consumer(const std::string &log_directory, const event_level &level);
|
||||
|
||||
~logging_consumer();
|
||||
|
||||
private:
|
||||
const std::uint8_t MAX_LOG_FILES = 5;
|
||||
const std::uint64_t MAX_LOG_FILE_SIZE = (1024 * 1024 * 5);
|
||||
|
||||
private:
|
||||
event_level event_level_ = event_level::normal;
|
||||
const std::string log_directory_;
|
||||
const std::string log_path_;
|
||||
bool logging_active_ = true;
|
||||
std::mutex log_mutex_;
|
||||
std::condition_variable log_notify_;
|
||||
std::deque<std::shared_ptr<event>> event_queue_;
|
||||
std::unique_ptr<std::thread> logging_thread_;
|
||||
FILE *log_file_ = nullptr;
|
||||
|
||||
private:
|
||||
void check_log_roll(std::size_t count);
|
||||
|
||||
void close_log_file();
|
||||
|
||||
void logging_thread(bool drain);
|
||||
|
||||
void process_event(const event &event);
|
||||
|
||||
void reopen_log_file();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_
|
74
repertory2/librepertory2/include/events/event.hpp
Normal file
74
repertory2/librepertory2/include/events/event.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDE_EVENTS_EVENT_HPP_
|
||||
#define INCLUDE_EVENTS_EVENT_HPP_
|
||||
|
||||
namespace repertory {
|
||||
enum class event_level {
|
||||
error,
|
||||
warn,
|
||||
normal,
|
||||
debug,
|
||||
verbose,
|
||||
};
|
||||
|
||||
auto event_level_from_string(std::string level) -> event_level;
|
||||
|
||||
auto event_level_to_string(const event_level &level) -> std::string;
|
||||
|
||||
class event {
|
||||
protected:
|
||||
explicit event(bool allow_async) : allow_async_(allow_async) {}
|
||||
|
||||
event(const std::stringstream &ss, json j, bool allow_async)
|
||||
: allow_async_(allow_async), ss_(ss.str()), j_(std::move(j)) {}
|
||||
|
||||
public:
|
||||
event(const event &) = delete;
|
||||
event(event &&) = delete;
|
||||
auto operator=(const event &) -> event & = delete;
|
||||
auto operator=(event &&) -> event & = delete;
|
||||
virtual ~event() = default;
|
||||
|
||||
private:
|
||||
bool allow_async_;
|
||||
|
||||
protected:
|
||||
std::stringstream ss_;
|
||||
json j_;
|
||||
|
||||
public:
|
||||
[[nodiscard]] virtual auto clone() const -> std::shared_ptr<event> = 0;
|
||||
|
||||
[[nodiscard]] auto get_allow_async() const -> bool { return allow_async_; }
|
||||
|
||||
[[nodiscard]] virtual auto get_event_level() const -> event_level = 0;
|
||||
|
||||
[[nodiscard]] auto get_json() const -> json { return j_; }
|
||||
|
||||
[[nodiscard]] virtual auto get_name() const -> std::string = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_single_line() const -> std::string = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_EVENT_HPP_
|
262
repertory2/librepertory2/include/events/event_system.hpp
Normal file
262
repertory2/librepertory2/include/events/event_system.hpp
Normal file
@ -0,0 +1,262 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDE_EVENTS_EVENT_SYSTEM_HPP_
|
||||
#define INCLUDE_EVENTS_EVENT_SYSTEM_HPP_
|
||||
|
||||
#include "events/event.hpp"
|
||||
#include "events/t_event_system.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
using event_system = t_event_system<event>;
|
||||
using event_consumer = event_system::event_consumer;
|
||||
|
||||
#define E_CAST(t) ((std::string)t)
|
||||
#define E_DOUBLE(d) std::to_string(d)
|
||||
#define E_DOUBLE_PRECISE(dbl_val) \
|
||||
([](const double &d) -> std::string { \
|
||||
std::stringstream ss; \
|
||||
ss << std::fixed << std::setprecision(2) << d; \
|
||||
return ss.str(); \
|
||||
})(dbl_val)
|
||||
#define E_FROM_BOOL(t) std::to_string(t)
|
||||
#define E_FROM_EXCEPTION(e) std::string(e.what() ? e.what() : "")
|
||||
#define E_FROM_INT32(t) std::to_string(t)
|
||||
#define E_FROM_INT64(t) std::to_string(t)
|
||||
#define E_FROM_UINT16(t) std::to_string(t)
|
||||
#define E_FROM_STRING_ARRAY(a) \
|
||||
([](const auto &array) -> std::string { \
|
||||
std::stringstream ret; \
|
||||
for (const auto &item : array) { \
|
||||
ret << (std::string(item) + " "); \
|
||||
} \
|
||||
return std::string(ret).TrimRight(); \
|
||||
})(a)
|
||||
|
||||
#define E_PERCENT(d) \
|
||||
([](const double &d) -> std::string { \
|
||||
std::stringstream ss; \
|
||||
ss << std::fixed << std::setprecision(2) << d; \
|
||||
ss << "%"; \
|
||||
return ss; \
|
||||
})(d)
|
||||
#define E_STRING(t) t
|
||||
#define E_FROM_CURL_CODE(t) std::string(curl_easy_strerror(t))
|
||||
#define E_FROM_UINT8(t) std::to_string(t)
|
||||
#define E_FROM_UINT32(t) std::to_string(t)
|
||||
#define E_FROM_UINT64(t) std::to_string(t)
|
||||
#define E_FROM_SIZE_T(t) std::to_string(t)
|
||||
#define E_FROM_API_FILE_ERROR(e) api_error_to_string(e)
|
||||
|
||||
#define E_PROP(type, name, short_name, ts) \
|
||||
private: \
|
||||
void init_##short_name(const type &val) { \
|
||||
auto ts_val = ts(val); \
|
||||
ss_ << "|" << #short_name << "|" << ts_val; \
|
||||
j_[#name] = ts_val; \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
[[nodiscard]] auto get_##name() const->json { return j_[#name]; }
|
||||
|
||||
#define E_BEGIN(name, el) \
|
||||
class name final : public virtual event { \
|
||||
private: \
|
||||
name(const std::stringstream &ss, const json &j, bool allow_async) \
|
||||
: event(ss, j, allow_async) {} \
|
||||
\
|
||||
public: \
|
||||
~name() override = default; \
|
||||
\
|
||||
public: \
|
||||
static const event_level level = event_level::el; \
|
||||
\
|
||||
public: \
|
||||
[[nodiscard]] auto get_name() const -> std::string override { \
|
||||
return #name; \
|
||||
} \
|
||||
\
|
||||
[[nodiscard]] auto get_event_level() const -> event_level override { \
|
||||
return name::level; \
|
||||
} \
|
||||
\
|
||||
[[nodiscard]] auto get_single_line() const -> std::string override { \
|
||||
const auto s = ss_.str(); \
|
||||
return get_name() + (s.empty() ? "" : s); \
|
||||
} \
|
||||
\
|
||||
[[nodiscard]] auto clone() const -> std::shared_ptr<event> override { \
|
||||
return std::shared_ptr<name>(new name(ss_, j_, get_allow_async())); \
|
||||
}
|
||||
#define E_END() }
|
||||
|
||||
#define E_SIMPLE(event_name, el, allow_async) \
|
||||
E_BEGIN(event_name, el) \
|
||||
public: \
|
||||
event_name() : event(allow_async) {} \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE1(event_name, el, allow_async, type, name, short_name, tc) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv) : event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE2(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2) : event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE3(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE4(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3, type4, name4, short_name4, tc4) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, \
|
||||
const type4 &tv4) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
init_##short_name4(tv4); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE5(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3, type4, name4, short_name4, tc4, type5, name5, \
|
||||
short_name5, tc5) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, \
|
||||
const type4 &tv4, const type5 &tv5) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
init_##short_name4(tv4); \
|
||||
init_##short_name5(tv5); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_PROP(type5, name5, short_name5, tc5) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE6(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3, type4, name4, short_name4, tc4, type5, name5, \
|
||||
short_name5, tc5, type6, name6, short_name6, tc6) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, \
|
||||
const type4 &tv4, const type5 &tv5, const type6 &tv6) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
init_##short_name4(tv4); \
|
||||
init_##short_name5(tv5); \
|
||||
init_##short_name6(tv6); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_PROP(type5, name5, short_name5, tc5) \
|
||||
E_PROP(type6, name6, short_name6, tc6) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE7(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3, type4, name4, short_name4, tc4, type5, name5, \
|
||||
short_name5, tc5, type6, name6, short_name6, tc6, type7, \
|
||||
name7, short_name7, tc7) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, \
|
||||
const type4 &tv4, const type5 &tv5, const type6 &tv6, \
|
||||
const type7 &tv7) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
init_##short_name4(tv4); \
|
||||
init_##short_name5(tv5); \
|
||||
init_##short_name6(tv6); \
|
||||
init_##short_name7(tv7); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_PROP(type5, name5, short_name5, tc5) \
|
||||
E_PROP(type6, name6, short_name6, tc6) \
|
||||
E_PROP(type7, name7, short_name7, tc7) \
|
||||
E_END()
|
||||
|
||||
#define E_CONSUMER() \
|
||||
private: \
|
||||
std::vector<std::shared_ptr<repertory::event_consumer>> event_consumers_
|
||||
|
||||
#define E_CONSUMER_RELEASE() event_consumers_.clear()
|
||||
|
||||
#define E_SUBSCRIBE(name, callback) \
|
||||
event_consumers_.emplace_back(std::make_shared<repertory::event_consumer>( \
|
||||
#name, [this](const event &evt) { callback(evt); }))
|
||||
|
||||
#define E_SUBSCRIBE_EXACT(name, callback) \
|
||||
event_consumers_.emplace_back(std::make_shared<repertory::event_consumer>( \
|
||||
#name, [this](const event &evt) { \
|
||||
callback(dynamic_cast<const name &>(evt)); \
|
||||
}))
|
||||
|
||||
#define E_SUBSCRIBE_ALL(callback) \
|
||||
event_consumers_.emplace_back(std::make_shared<repertory::event_consumer>( \
|
||||
[this](const event &evt) { callback(evt); }))
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_EVENT_SYSTEM_HPP_
|
301
repertory2/librepertory2/include/events/events.hpp
Normal file
301
repertory2/librepertory2/include/events/events.hpp
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDE_EVENTS_EVENTS_HPP_
|
||||
#define INCLUDE_EVENTS_EVENTS_HPP_
|
||||
|
||||
#include "events/event_system.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE2(curl_error, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, res, res, E_FROM_CURL_CODE
|
||||
);
|
||||
|
||||
E_SIMPLE3(debug_log, debug, true,
|
||||
std::string, function, func, E_STRING,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, data, data, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(directory_removed, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(directory_removed_externally, warn, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(directory_remove_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(drive_mount_failed, error, true,
|
||||
std::string, location, loc, E_STRING,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_mounted, normal, true,
|
||||
std::string, location, loc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_mount_result, normal, true,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_unmount_pending, normal, true,
|
||||
std::string, location, loc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_unmounted, normal, true,
|
||||
std::string, location, loc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(event_level_changed, normal, true,
|
||||
std::string, new_event_level, level, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_queued, error, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_removed, warn, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_retry, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_get_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_get_api_list_failed, error, true,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_pinned, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_read_bytes_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING,
|
||||
std::size_t, retry, retry, E_FROM_SIZE_T
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_removed, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_removed_externally, warn, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_remove_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_rename_failed, error, true,
|
||||
std::string, from_api_path, FROM, E_STRING,
|
||||
std::string, to_api_path, TO, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_get_size_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(filesystem_item_added, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, parent, parent, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE4(filesystem_item_closed, verbose, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL,
|
||||
bool, changed, changed, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE5(filesystem_item_handle_closed, verbose, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::uint64_t, handle, handle, E_FROM_UINT64,
|
||||
std::string, source, src, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL,
|
||||
bool, changed, changed, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE4(filesystem_item_handle_opened, verbose, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::uint64_t, handle, handle, E_FROM_UINT64,
|
||||
std::string, source, src, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE2(filesystem_item_evicted, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(filesystem_item_get_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(filesystem_item_opened, verbose, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_unpinned, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(file_upload_completed, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR,
|
||||
bool, cancelled, cancel, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_upload_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_not_found, warn, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_queued, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_upload_removed, debug, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_upload_retry, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_started, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE(item_scan_begin, normal, true);
|
||||
|
||||
E_SIMPLE(item_scan_end, normal, true);
|
||||
|
||||
E_SIMPLE1(orphaned_file_deleted, warn, true,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(orphaned_file_detected, warn, true,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(orphaned_file_processed, warn, true,
|
||||
std::string, source, src, E_STRING,
|
||||
std::string, dest, dest, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(orphaned_file_processing_failed, error, true,
|
||||
std::string, source, src, E_STRING,
|
||||
std::string, dest, dest, E_STRING,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(polling_item_begin, debug, true,
|
||||
std::string, item_name, item, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(polling_item_end, debug, true,
|
||||
std::string, item_name, item, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(provider_offline, error, true,
|
||||
std::string, host_name_or_ip, host, E_STRING,
|
||||
std::uint16_t, port, port, E_FROM_UINT16
|
||||
);
|
||||
|
||||
E_SIMPLE2(provider_upload_begin, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(provider_upload_end, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE2(repertory_exception, error, true,
|
||||
std::string, function, func, E_STRING,
|
||||
std::string, message, msg, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(rpc_server_exception, error, true,
|
||||
std::string, exception, exception, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(service_shutdown_begin, debug, true,
|
||||
std::string, service, svc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(service_shutdown_end, debug, true,
|
||||
std::string, service, svc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(service_started, debug, true,
|
||||
std::string, service, svc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE(unmount_requested, normal, true);
|
||||
#ifndef _WIN32
|
||||
E_SIMPLE2(unmount_result, normal, true,
|
||||
std::string, location, loc, E_STRING,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
#endif
|
||||
// clang-format on
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_EVENTS_HPP_
|
192
repertory2/librepertory2/include/events/t_event_system.hpp
Normal file
192
repertory2/librepertory2/include/events/t_event_system.hpp
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_
|
||||
#define INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_
|
||||
|
||||
#include "events/event.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
template <typename event_type> class t_event_system final {
|
||||
public:
|
||||
t_event_system(const t_event_system &) = delete;
|
||||
t_event_system(t_event_system &&) = delete;
|
||||
auto operator=(const t_event_system &) -> t_event_system & = delete;
|
||||
auto operator=(t_event_system &&) -> t_event_system & = delete;
|
||||
|
||||
protected:
|
||||
t_event_system() = default;
|
||||
|
||||
~t_event_system() { stop(); }
|
||||
|
||||
public:
|
||||
class event_consumer final {
|
||||
public:
|
||||
explicit event_consumer(std::function<void(const event &)> callback)
|
||||
: callback_(std::move(callback)) {
|
||||
t_event_system::instance().attach(this);
|
||||
}
|
||||
|
||||
event_consumer(const std::string &event_name,
|
||||
std::function<void(const event &)> callback)
|
||||
: callback_(std::move(callback)) {
|
||||
t_event_system::instance().attach(event_name, this);
|
||||
}
|
||||
|
||||
~event_consumer() { t_event_system::instance().release(this); }
|
||||
|
||||
public:
|
||||
event_consumer(const event_consumer &) = delete;
|
||||
event_consumer(event_consumer &&) = delete;
|
||||
auto operator=(const event_consumer &) -> event_consumer & = delete;
|
||||
auto operator=(event_consumer &&) -> event_consumer & = delete;
|
||||
|
||||
private:
|
||||
std::function<void(const event &)> callback_;
|
||||
|
||||
public:
|
||||
void notify_event(const event &event) { callback_(event); }
|
||||
};
|
||||
|
||||
private:
|
||||
static t_event_system event_system_;
|
||||
|
||||
public:
|
||||
static auto instance() -> t_event_system &;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::deque<event_consumer *>>
|
||||
event_consumers_;
|
||||
std::recursive_mutex consumer_mutex_;
|
||||
std::vector<std::shared_ptr<event_type>> event_list_;
|
||||
std::condition_variable event_notify_;
|
||||
std::mutex event_mutex_;
|
||||
std::unique_ptr<std::thread> event_thread_;
|
||||
std::mutex run_mutex_;
|
||||
stop_type stop_requested_ = false;
|
||||
|
||||
private:
|
||||
void process_events() {
|
||||
std::vector<std::shared_ptr<event_type>> events;
|
||||
{
|
||||
unique_mutex_lock lock(event_mutex_);
|
||||
if (not stop_requested_ && event_list_.empty()) {
|
||||
event_notify_.wait_for(lock, 1s);
|
||||
}
|
||||
|
||||
if (not event_list_.empty()) {
|
||||
events.insert(events.end(), event_list_.begin(), event_list_.end());
|
||||
event_list_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
const auto notify_events = [this](const std::string &name,
|
||||
const event_type &event) {
|
||||
std::deque<std::future<void>> futures;
|
||||
recur_mutex_lock lock(consumer_mutex_);
|
||||
if (event_consumers_.find(name) != event_consumers_.end()) {
|
||||
for (auto *consumer : event_consumers_[name]) {
|
||||
if (event.get_allow_async()) {
|
||||
futures.emplace_back(
|
||||
std::async(std::launch::async, [consumer, &event]() {
|
||||
consumer->notify_event(event);
|
||||
}));
|
||||
} else {
|
||||
consumer->notify_event(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (not futures.empty()) {
|
||||
futures.front().get();
|
||||
futures.pop_front();
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto &evt : events) {
|
||||
notify_events("", *evt.get());
|
||||
notify_events(evt->get_name(), *evt.get());
|
||||
}
|
||||
}
|
||||
|
||||
void queue_event(std::shared_ptr<event_type> evt) {
|
||||
mutex_lock lock(event_mutex_);
|
||||
event_list_.push_back(std::move(evt));
|
||||
event_notify_.notify_all();
|
||||
}
|
||||
|
||||
public:
|
||||
void attach(event_consumer *consumer) {
|
||||
recur_mutex_lock lock(consumer_mutex_);
|
||||
event_consumers_[""].push_back(consumer);
|
||||
}
|
||||
|
||||
void attach(const std::string &event_name, event_consumer *consumer) {
|
||||
recur_mutex_lock lock(consumer_mutex_);
|
||||
event_consumers_[event_name].push_back(consumer);
|
||||
}
|
||||
|
||||
template <typename event_t, typename... arg_t> void raise(arg_t &&...args) {
|
||||
queue_event(std::make_shared<event_t>(std::forward<arg_t>(args)...));
|
||||
}
|
||||
|
||||
void release(event_consumer *consumer) {
|
||||
recur_mutex_lock lock(consumer_mutex_);
|
||||
auto iter =
|
||||
std::find_if(event_consumers_.begin(), event_consumers_.end(),
|
||||
[&](const auto &item) -> bool {
|
||||
return utils::collection_includes(item.second, consumer);
|
||||
});
|
||||
|
||||
if (iter != event_consumers_.end()) {
|
||||
utils::remove_element_from((*iter).second, consumer);
|
||||
}
|
||||
}
|
||||
|
||||
void start() {
|
||||
mutex_lock lock(run_mutex_);
|
||||
if (not event_thread_) {
|
||||
stop_requested_ = false;
|
||||
event_thread_ = std::make_unique<std::thread>([this]() {
|
||||
while (not stop_requested_) {
|
||||
process_events();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
mutex_lock lock(run_mutex_);
|
||||
if (event_thread_) {
|
||||
stop_requested_ = true;
|
||||
event_notify_.notify_all();
|
||||
|
||||
event_thread_->join();
|
||||
event_thread_.reset();
|
||||
|
||||
process_events();
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_
|
Reference in New Issue
Block a user