/* * Copyright (C) 20011-2015 ACore3 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef _OBJECTSTORAGE_H #define _OBJECTSTORAGE_H #include "inc/database.h" #include "inc/cursor.h" #include "inc/query.h" #include #include #include "Object.h" #include "ObjectGuid.h" class Player; class Transport; class Guild; // ------------------------------------------------------------ // In memory database section // ------------------------------------------------------------ extern dbDatabase object_storage_db; // // BaseTable // - uzywac tylko poprzed dziediczenie. Klasa // ma tylko na celu stworzenia metod odpowiedzialnych // za konwertowanie danych // class BaseTable { protected: uint64 _guid; public: ObjectGuid GetGuid() { return ConvertUInt64ToObjectGuid(_guid); } protected: inline const char* ConvertString(std::string str) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); return str.c_str(); } inline uint64 ConvertObjectGuid(ObjectGuid guid) { return guid.GetRawValue(); } inline ObjectGuid ConvertUInt64ToObjectGuid(uint64 raw) { return ObjectGuid(raw); } }; class PlayerTable : BaseTable { private: uint32 _guidGuild; uint8 _level; uint8 _race; uint8 _class; char const* _name; char const* _guildName; public: PlayerTable(Player* player) { _guid = ConvertObjectGuid(player->GetGUID()); _level = player->getLevel(); _race = player->getRace(); _class = player->getClass(); _name = ConvertString(player->GetName()); if (player->GetGuild()) { _guildName = ConvertString(player->GetGuildName()); _guidGuild = player->GetGuildId(); } else { _guidGuild = 0; _guildName = ""; } } public: TYPE_DESCRIPTOR(KEY(_guid, INDEXED)); TYPE_DESCRIPTOR(KEY(_guidGuild, INDEXED)); TYPE_DESCRIPTOR(KEY(_level, INDEXED)); TYPE_DESCRIPTOR(KEY(_race, INDEXED)); TYPE_DESCRIPTOR(KEY(_class, INDEXED)); TYPE_DESCRIPTOR(KEY(_name, INDEXED|HASHED)); TYPE_DESCRIPTOR(KEY(_guildName, INDEXED|HASHED)); }; REGISTER(PlayerTable); // ------------------------------------------------------------ // ObjectStorage Section // ------------------------------------------------------------ template class ObjectStorage { public: static_assert( (std::is_same::value && std::is_same::value) || std::is_same::value || std::is_same::value, "Only Player/Transport/Guild can be registered in global ObjectStorage"); typedef std::unordered_map MapType; public: static void Insert(T* o) { boost::unique_lock lock(_lock); _objectMap[o->GetGUID()] = o; if (!std::is_same::value) InsertToTable(o); } static void Remove(T* o) { boost::unique_lock lock(_lock); _objectMap.erase(o->GetGUID()); if (!std::is_same::value) RemoveFromTable(o); } static T* Find(ObjectGuid guid) { boost::shared_lock lock(_lock); typename MapType::iterator itr = _objectMap.find(guid); return (itr != _objectMap.end()) ? itr->second : nullptr; } static T* Find(dbQuery q) { boost::shared_lock lock(_lock); if (std::is_same::value) ASSERT(false, 'You must implement table class for using find by query'); dbCursor cursor(object_storage_db); if (cursor.select(q) == 0) return nullptr; ObjectGuid guid = cursor.GetGuid(); typename MapType::iterator itr = _objectMap.find(guid); return (itr != _objectMap.end()) ? itr->second : nullptr; } static std::list FindAll(dbQuery q, int& found, int maxReturn = -1) { boost::shared_lock lock(_lock); if (std::is_same::value) ASSERT(false, 'You must implement table class for using find by query'); std::list objects; dbCursor cursor(object_storage_db); found = cursor.select(q) > 0; if (found > 0 && (maxReturn == -1 || maxReturn > 0)) { int iter = 0; do { if (maxReturn > 0 && ++iter > maxReturn) break; ObjectGuid guid = cursor.GetGuid(); typename MapType::iterator itr = _objectMap.find(guid); if (itr != _objectMap.end()) objects.insert(itr->second); } while (cursor.next()); } return objects; } static MapType& GetContainer() { return _objectMap; } static boost::shared_mutex* GetLock() { return &_lock; } private: ObjectStorage() { } static void InsertToTable(T* o) { object_storage_db->insert(new Y(o)); } static void RemoveFromTable(T* o) { dbQuery q; q = "_guid=", o->GetGUID().GetRawValue(); dbCursor cursor(object_storage_db); if (cursor.select(q) != 0) cursor.removeAllSelected(); } static boost::shared_mutex _lock; static MapType _objectMap; }; #endif