#pragma once #include #include #include "misc/advanced_mutex.h" #include "channel/TreeView.h" #include "Definitions.h" #include "Properties.h" #include "PermissionManager.h" namespace ts { class BasicChannel; class BasicChannelTree; namespace ChannelType { enum ChannelType { permanent, semipermanent, temporary }; } struct BasicChannelEntry { BasicChannelEntry* previus{}; std::shared_ptr current = nullptr; BasicChannelEntry* next{}; BasicChannelEntry* children{}; ~BasicChannelEntry() { this->current = nullptr; } }; class BasicChannel : public TreeEntry { public: BasicChannel(ChannelId parentId, ChannelId channelId); BasicChannel(std::shared_ptr parent, ChannelId channelId); virtual ~BasicChannel(); bool hasParent(){ return !!this->parent(); } std::shared_ptr parent(); inline std::string name(){ return properties()[property::CHANNEL_NAME]; } inline ChannelId channelOrder(){ return this->previousChannelId(); } inline Properties& properties() const { return *this->_properties; } ChannelType::ChannelType channelType(); void setChannelType(ChannelType::ChannelType); bool passwordMatch(std::string password, bool hashed = false); bool defaultChannel() { return (*this->_properties)[property::CHANNEL_FLAG_DEFAULT]; } int64_t emptySince(); inline std::chrono::system_clock::time_point createdTimestamp() { return std::chrono::system_clock::time_point() + std::chrono::milliseconds(this->properties()[property::CHANNEL_CREATED_AT].as()); } 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; } std::vector update_properties_from_permissions(); 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 */ assert(permission_manager); const auto data = permission_manager->permission_value_flagged(permission); return BasicChannel::permission_granted(data,granted_value, require_granted_value); } ts_always_inline bool talk_power_granted(const permission::v2::PermissionFlaggedValue& granted_value) { return this->permission_granted(permission::i_client_needed_talk_power, granted_value, false); } ts_always_inline std::shared_ptr permissions(){ return this->_permissions; } virtual void setPermissionManager(const std::shared_ptr&); virtual void setProperties(const std::shared_ptr&); private: ts_always_inline static bool permission_granted(const permission::v2::PermissionFlaggedValue& channel_permission_value, const permission::v2::PermissionFlaggedValue& granted_value, bool require_granted_value) { if(!channel_permission_value.has_value || channel_permission_value.value == 0) { return !require_granted_value || granted_value.has_value; } if(channel_permission_value.value == -1) { return granted_value.value == -1; } return granted_value.value >= channel_permission_value.value; } public: [[nodiscard]] ChannelId channelId() const override; [[nodiscard]] ChannelId previousChannelId() const override; void setPreviousChannelId(ChannelId id) override; void setParentChannelId(ChannelId id) override; void setLinkedHandle(const std::weak_ptr &) override; protected: std::weak_ptr _link; std::shared_ptr _properties; std::shared_ptr _permissions; ChannelId _channel_order = 0; ChannelId _channel_id = 0; }; class BasicChannelTree : public TreeView { public: BasicChannelTree(); virtual ~BasicChannelTree(); size_t channel_count() { return this->entry_count(); } std::shared_ptr findLinkedChannel(ChannelId channelId); std::shared_ptr findChannel(ChannelId channelId); std::shared_ptr findChannel(ChannelId channelId, std::deque> avariable); std::shared_ptr findChannel(const std::string &name, const std::shared_ptr &layer); std::shared_ptr findChannelByPath(const std::string& path); //std::deque> topChannels(); std::deque> channels(const std::shared_ptr &root = nullptr, int deep = -1); virtual std::shared_ptr createChannel(ChannelId parentId, ChannelId orderId, const std::string &name); virtual std::deque> delete_channel_root(const std::shared_ptr &); inline bool change_order(const std::shared_ptr& channel, ChannelId channelId) { return this->move_entry(channel, channel->parent(), this->find_entry(channelId)); } inline bool move_channel(const std::shared_ptr& channel, const std::shared_ptr& parent, const std::shared_ptr& order) { return this->move_entry(channel, parent, order); } bool setDefaultChannel(const std::shared_ptr &); std::shared_ptr getDefaultChannel(); void printChannelTree(std::function = [](std::string msg) { std::cout << msg << std::endl; }); protected: virtual ChannelId generateChannelId(); virtual void on_channel_entry_deleted(const std::shared_ptr &); virtual std::shared_ptr allocateChannel(const std::shared_ptr &parent, ChannelId channelId); }; } DEFINE_TRANSFORMS(ts::ChannelType::ChannelType, uint8_t);