diff --git a/CMakeLists.txt b/CMakeLists.txt index d9609e8..db7a902 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,7 +90,7 @@ endif() set(SOURCE_FILES src/misc/rnd.cpp - src/misc/time.cpp + src/misc/duration_utils.cpp src/misc/memtracker.cpp src/misc/digest.cpp src/misc/base64.cpp diff --git a/src/BasicChannel.cpp b/src/BasicChannel.cpp index e7df9dc..4e870db 100644 --- a/src/BasicChannel.cpp +++ b/src/BasicChannel.cpp @@ -23,7 +23,9 @@ BasicChannel::BasicChannel(ChannelId parentId, ChannelId channelId) { void BasicChannel::setPermissionManager(const std::shared_ptr& manager) { this->_permissions = manager; - this->update_properties_from_permissions(); + + bool flag_view_update; + this->update_properties_from_permissions(flag_view_update); } void BasicChannel::setProperties(const std::shared_ptr& props) { @@ -48,34 +50,45 @@ void BasicChannel::setProperties(const std::shared_ptr& props) { this->_channel_id = this->channelId(); } -std::vector BasicChannel::update_properties_from_permissions() { +std::vector BasicChannel::update_properties_from_permissions(bool& need_view_update) { std::vector result; result.reserve(2); auto permission_manager = this->permissions(); /* keeps the manager until we've finished our calculations */ /* update the icon id */ { - IconId target_icon_id = 0; - auto& permission_icon_flags = permission_manager->permission_flags(permission::i_icon_id); - if(permission_icon_flags.value_set) - target_icon_id = (IconId) permission_manager->permission_values(permission::i_icon_id).value; + IconId target_icon_id{0}; + auto fvalue = permission_manager->permission_value_flagged(permission::i_icon_id); + if(fvalue.has_value) + target_icon_id = (IconId) fvalue.value; if(this->properties()[property::CHANNEL_ICON_ID] != target_icon_id) { this->properties()[property::CHANNEL_ICON_ID] = target_icon_id; result.push_back(property::CHANNEL_ICON_ID); } } + /* update the channel talk power */ { permission::PermissionValue talk_power{0}; - auto& permission_tp_flags = permission_manager->permission_flags(permission::i_client_needed_talk_power); - if(permission_tp_flags.value_set) - talk_power = permission_manager->permission_values(permission::i_client_needed_talk_power).value; + auto fvalue = permission_manager->permission_value_flagged(permission::i_client_needed_talk_power); + if(fvalue.has_value) + talk_power = fvalue.value; if(this->properties()[property::CHANNEL_NEEDED_TALK_POWER] != talk_power) { this->properties()[property::CHANNEL_NEEDED_TALK_POWER] = talk_power; result.push_back(property::CHANNEL_NEEDED_TALK_POWER); } } + /* needed view power */ + { + auto fvalue = permission_manager->permission_value_flagged(permission::i_channel_needed_view_power); + if(this->last_view_power.has_value != fvalue.has_value) + need_view_update = true; + else + need_view_update = fvalue.value != this->last_view_power.value; + this->last_view_power = fvalue; + } + return result; } diff --git a/src/BasicChannel.h b/src/BasicChannel.h index 681157a..1d42e8e 100644 --- a/src/BasicChannel.h +++ b/src/BasicChannel.h @@ -59,9 +59,9 @@ namespace ts { } ts_always_inline bool permission_require_property_update(const permission::PermissionType& permission) { - return permission == permission::i_icon_id || permission == permission::i_client_needed_talk_power; + return permission == permission::i_icon_id || permission == permission::i_client_needed_talk_power || permission == permission::i_channel_needed_view_power; } - std::vector update_properties_from_permissions(); + std::vector update_properties_from_permissions(bool& /* need view update */); inline bool permission_granted(const permission::PermissionType& permission, const permission::v2::PermissionFlaggedValue& granted_value, bool require_granted_value) { auto permission_manager = this->permissions(); /* copy the manager */ @@ -100,6 +100,8 @@ namespace ts { std::shared_ptr _properties; std::shared_ptr _permissions; + permission::v2::PermissionFlaggedValue last_view_power{0, false}; + ChannelId _channel_order = 0; ChannelId _channel_id = 0; }; diff --git a/src/Error.h b/src/Error.h index d33fbbb..301472d 100644 --- a/src/Error.h +++ b/src/Error.h @@ -180,13 +180,13 @@ namespace ts { }; struct detailed_command_result { - error::type error_id; - std::map extra_properties; + error::type error_id{}; + std::map extra_properties{}; }; enum struct command_result_type { - detailed = 0b00, - error = 0b10, + error = 0b00, /* must be 0 because 0 is the default value! */ + detailed = 0b01, bulked = 0b11 }; @@ -303,6 +303,12 @@ namespace ts { } #endif + inline command_result& reset(command_result&& other) { + this->release_data(); + std::exchange(this->data, other.data); + return *this; + } + inline void release_data() { auto type = this->type(); if(type == command_result_type::bulked) { @@ -315,15 +321,12 @@ namespace ts { this->data = 0; } -#ifndef _NDEBUG /* We dont need to secure that because gcc deduct us to an uint64_t and the only advantage is the mem leak test which is deactivated anyways */ - command_result(command_result&) = delete; - command_result(const command_result&) = delete; - command_result(command_result&& other) : data(other.data) { - other.data = 0; - } -#endif - command_result() = default; + command_result(const command_result&) = delete; + command_result(command_result&& other) noexcept { + /* we've to specify a move constructor since, we're a "trivial" type, which means that our "data" will just get copied */ + std::swap(this->data, other.data); + } explicit command_result(permission::PermissionType permission) { this->data = (uint64_t) command_result_type::error; @@ -360,10 +363,7 @@ namespace ts { #ifndef _NDEBUG /* if we're not using any debug we dont have to use a deconstructor. A deconstructor prevent a direct uint64_t return as described above */ ~command_result() { - if((this->data & 0x01) == 0x00) { - // this->details needs to be removed 'till this gets destructed - assert(this->data == 0); - } + assert(this->data == 0); } #endif }; @@ -373,7 +373,8 @@ namespace ts { friend struct command_result; public: command_result_bulk() = default; - command_result_bulk(command_result&& result) { this->results.push_back(std::forward(result)); } + explicit command_result_bulk(command_result&& result) { this->results.push_back(std::forward(result)); } + ~command_result_bulk() { for(auto& result : this->results) result.release_data(); @@ -383,6 +384,10 @@ namespace ts { this->results.reserve(length); } + inline void insert_result(ts::command_result&& result) { + this->results.push_back(std::forward(result)); + } + inline void emplace_result(permission::PermissionType permission) { this->results.emplace_back(permission); } @@ -395,6 +400,12 @@ namespace ts { this->results.emplace_back(error, message); } + template + inline void emplace_result_n(size_t times, const Args&&... args) { + while(times-- > 0) + this->results.emplace_back(args...); + } + [[nodiscard]] inline auto begin() { return this->results.begin(); } [[nodiscard]] inline auto end() { return this->results.end(); } [[nodiscard]] inline auto cbegin() const { return this->results.cbegin(); } diff --git a/src/PermissionManager.h b/src/PermissionManager.h index 8fa1257..f8386a1 100644 --- a/src/PermissionManager.h +++ b/src/PermissionManager.h @@ -553,6 +553,8 @@ namespace ts { bool clientSupported = true; + [[nodiscard]] inline bool is_invalid() const { return this->type == permission::undefined || this->type == permission::unknown; } + // PermissionTypeEntry(PermissionTypeEntry&& ref) : type(ref.type), group(ref.group), name(ref.name), description(ref.description), clientSupported(ref.clientSupported) {} //PermissionTypeEntry(const PermissionTypeEntry& ref) : type(ref.type), group(ref.group), name(ref.name), description(ref.description), clientSupported(ref.clientSupported) {} PermissionTypeEntry(PermissionTypeEntry&& ref) = delete; diff --git a/src/log/LogSinks.cpp b/src/log/LogSinks.cpp index 7963d58..29afd0b 100644 --- a/src/log/LogSinks.cpp +++ b/src/log/LogSinks.cpp @@ -31,7 +31,7 @@ namespace logger { } while(++index); } else #endif - cout << message; + cout << message << std::flush; } void TerminalSink::flush_() { diff --git a/src/misc/time.cpp b/src/misc/duration_utils.cpp similarity index 100% rename from src/misc/time.cpp rename to src/misc/duration_utils.cpp