# Rewards code review 1. MainMenuBase - возможно стоит добавить метод и для коллекций PrepareCollectionsRewards() и вынести туда нужный кусочек кода из PrepareCollections чтобы по интерфейсу сразу было понять что именно имеет свойства ревардсов и легче читалось. - PrepareLootBoxes**Rewards**() ? 2. Common.cpp - gui::AttachToButtons(...) выглядит немного костыльно, по-сути мы же не должны подписываться на кнопки повторно, хотя у себя в коде тоже что-то такое писала :) ``` if (button) { **button->RemoveActionListener(listener);** button->AddActionListener(listener); } ``` 3. VCORE_AccountImpl::OnRewardsDataReceived - стоит добавить проверку размера массива loot_box_skins, что прислал сервер, на всякий случай чтобы избежать падение клиента в месте loot_box_skins[i]. Если нет скина использовать дефолтный. 4. RewardLootBox::GetLootBoxLevelSkinnedName - запись типа `const bool key_is_present = data.find(KEY) != data.end();` можно заменить на более короткую `const bool key_is_present = data.count(KEY);` 5. VCORE_LootBoxes::GetConvertedLootBoxes возможно также стоит подобавлять проверки на наличие ключей (?), это касается и других похожих кусков кода - основная идея избежать падение клиента ``` j_data["id"] = raw_loot_box.loot_box_id; j_data["level"] = raw_loot_box.loot_box_level; j_data["skin"] = raw_loot_box.loot_box_skin; ``` Похоже, я бы добавила проверку ``` void VCORE_LootBoxes::SetLootboxOpened(const LootBoxId_t loot_box_id, const std::vector<Reward_t>& rewards_data) { m_loot_boxes_rewards[loot_box_id] = rewards_data; } ``` 6. std::vector<Reward_t> подобные записи можно заменять алиасами, так более короткие записи (особенно, если используется как параметр метода) и проще модифицировать в одно метсте если что 7. std::find_if(...) != data.end() --> std::none_of 8. Reward.hpp - #include <gui/include/event/ActionListener.hpp> - лишний - возмона инвалидация итератора ``` void Reward::NotifyListeners(const std::string& command) { const std::list<RewardListener*> listeners = m_listeners; for (const auto& listener : listeners) { cpp::count_ptr<Reward> keep(this); if (listener) listener->OnRewardNotification(this, command); } } ``` 9. Стоит добавить дефолтные параметры для всех полей, там же флоаты и инты typedef int64_t Time; typedef float Coord; ``` struct RewardLootBoxPopupData_t { bool is_set{ false }; gwc::Time wait_before_processing; gwc::Time wait_between_processings; gwc::Time move_duration; gwc::Time fade_duration; gwc::Time scale_duration; gwc::Time shift_duration; gwc::Time loot_box_scale_up_duration; gwc::Time loot_box_scale_down_duration; gwc::Coord default_shift_x_offset; gwc::Coord default_destination_x; gwc::Coord default_destination_y; gwc::Coord loot_box_scale_up_value; gwc::Coord loot_box_scale_down_value; gwc::Coord spine_view_scale_value; }; ``` 10. RewardMoney и др. Если есть билдеры, то конструктор можно сделать protected (?) 11. RewardsManager - void ActionPerformed(gui::ActionEvent* event) **override**; - cpp::count_ptr<Reward> GetRewardById(vcore::RewardId_t reward_id, const RewardsContainer_t& all_rewards) - не используется - #include <vgui/include/components/VGUI_Panel.hpp> - лишний 12. RewardCollection.cpp #include <vsdk/Rewards/include/RewardsCmd.hpp> - лишний 13. RewardLootBox.cpp const std::string LOOTBOX_SPINE_ANIMATION_CLOSED_IDLE = "lootbox_closed_idle"; - не используется 14. RewardMoney.cpp #include <vsdk/Rewards/include/RewardsCmd.hpp> - лишний