refactor tile serialize

This commit is contained in:
2025-07-31 18:02:14 +02:00
parent c8159bae6e
commit 1a455a3d6b
10 changed files with 84 additions and 117 deletions

View File

@@ -18,9 +18,6 @@ using Vec2fp = Vec2<FpFloat>;
namespace game { namespace game {
struct WalkableTile;
enum class EffectType : std::uint8_t { enum class EffectType : std::uint8_t {
Slowness = 0, Slowness = 0,
Stun, Stun,
@@ -127,6 +124,8 @@ class MobListener {
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {} virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {}
}; };
using MobList = std::vector<MobPtr>;
// typedef utils::ObjectNotifier<MobListener> MobNotifier; // typedef utils::ObjectNotifier<MobListener> MobNotifier;
} // namespace game } // namespace game

View File

@@ -1,10 +1,11 @@
#pragma once #pragma once
#include <td/Maths.h> #include <td/Maths.h>
#include <td/game/Mobs.h>
#include <td/game/Team.h> #include <td/game/Team.h>
#include <td/game/Towers.h> #include <td/game/Towers.h>
#include <sp/io/SerializableMessage.h>
namespace td { namespace td {
namespace game { namespace game {
@@ -31,37 +32,44 @@ static constexpr Color RED{255, 0, 0};
static constexpr Color GREEN{0, 255, 0}; static constexpr Color GREEN{0, 255, 0};
static constexpr Color BLUE{0, 0, 255}; static constexpr Color BLUE{0, 0, 255};
struct Tile { class TileHandler;
virtual TileType GetType() const = 0;
virtual ~Tile() = default; using Tile = sp::MessageBase<TileType, TileHandler>;
template <TileType ID, typename TileData>
using ConcreteTile = sp::ConcreteMessage<TileData, Tile, ID>;
namespace data {
struct EmptyData {};
struct TowerTileData {
std::uint8_t m_ColorPaletteRef;
TeamColor m_TeamOwner;
}; };
struct TowerTile : Tile { struct WalkableTileData {
std::uint8_t color_palette_ref; Direction m_Direction;
TeamColor team_owner;
virtual TileType GetType() const {
return TileType::Tower;
}
}; };
struct WalkableTile : Tile { struct DecorationTileData {
Direction direction; std::uint16_t m_ColorPaletteRef;
virtual TileType GetType() const {
return TileType::Walk;
}
}; };
} // namespace data
struct DecorationTile : Tile { using EmptyTile = ConcreteTile<TileType::None, data::EmptyData>;
std::uint16_t color_palette_ref; using TowerTile = ConcreteTile<TileType::Tower, data::TowerTileData>;
using WalkableTile = ConcreteTile<TileType::Walk, data::WalkableTileData>;
using DecorationTile = ConcreteTile<TileType::Decoration, data::DecorationTileData>;
virtual TileType GetType() const { using AllTiles = std::tuple<EmptyTile, TowerTile, WalkableTile, DecorationTile>;
return TileType::Decoration;
}
};
typedef std::shared_ptr<Tile> TilePtr; using TileFactory = sp::MessageFactory<Tile, AllTiles>;
class TileHandler : public sp::GenericHandler<AllTiles>{};
using TilePtr = std::shared_ptr<sp::SerializableMessage<TileFactory>>;
// typedef std::shared_ptr<Tile> TilePtr;
typedef std::vector<std::uint16_t> ChunkPalette; typedef std::vector<std::uint16_t> ChunkPalette;
typedef std::shared_ptr<WalkableTile> WalkableTilePtr; typedef std::shared_ptr<WalkableTile> WalkableTilePtr;
@@ -85,6 +93,21 @@ struct Chunk {
} }
// TODO: keep data packed // TODO: keep data packed
/*
std::size_t startLong = static_cast<std::size_t>((tileNumber * bitsPerTile) / BITS_IN_LONG);
std::size_t startOffset = static_cast<std::size_t>((tileNumber * bitsPerTile) % BITS_IN_LONG);
std::size_t endLong = static_cast<std::size_t>(((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG);
std::uint64_t value = static_cast<std::uint64_t>(a_Chunk->m_Tiles[tileNumber]);
value &= individualValueMask;
chunkData[startLong] |= (value << startOffset);
if (startLong != endLong) {
chunkData[endLong] = (value >> (BITS_IN_LONG - startOffset));
}
*/
}; };
typedef std::shared_ptr<Chunk> ChunkPtr; typedef std::shared_ptr<Chunk> ChunkPtr;
@@ -93,17 +116,12 @@ typedef std::array<Color, 2> TowerTileColorPalette;
typedef std::vector<TilePtr> TilePalette; typedef std::vector<TilePtr> TilePalette;
typedef std::vector<MobPtr> MobList;
typedef std::array<Color, 2> SpawnColorPalette; typedef std::array<Color, 2> SpawnColorPalette;
typedef std::vector<TowerPtr> TowerList; typedef std::vector<TowerPtr> TowerList;
using ChunkList = std::unordered_map<ChunkCoord, ChunkPtr>; using ChunkList = std::unordered_map<ChunkCoord, ChunkPtr>;
sp::DataBuffer& operator>>(sp::DataBuffer& buffer, TilePtr& tile);
} // namespace game } // namespace game
} // namespace td } // namespace td

View File

@@ -13,6 +13,7 @@
#include <td/Types.h> #include <td/Types.h>
#include <td/common/NonCopyable.h> #include <td/common/NonCopyable.h>
#include <td/protocol/command/CommandData.h> #include <td/protocol/command/CommandData.h>
#include <sp/io/SerializableMessage.h>
namespace td { namespace td {
namespace protocol { namespace protocol {
@@ -32,8 +33,6 @@ class CommandHandler;
using CommandBase = sp::MessageBase<CommandID, CommandHandler>; using CommandBase = sp::MessageBase<CommandID, CommandHandler>;
using CommandPtr = std::unique_ptr<CommandBase>;
template <typename TData, CommandID ID> template <typename TData, CommandID ID>
using CommandMessage = sp::ConcreteMessage<TData, CommandBase, ID>; using CommandMessage = sp::ConcreteMessage<TData, CommandBase, ID>;
@@ -61,5 +60,7 @@ using CommandFactory = sp::MessageFactory<CommandBase, AllCommands>;
using LockStep = std::vector<std::shared_ptr<CommandBase>>; using LockStep = std::vector<std::shared_ptr<CommandBase>>;
using CommandPtr = std::unique_ptr<sp::SerializableMessage<CommandFactory>>;
} // namespace protocol } // namespace protocol
} // namespace td } // namespace td

View File

@@ -43,8 +43,5 @@ sp::DataBuffer& operator>>(sp::DataBuffer& a_Buffer, TeamCastle& a_Castle);
sp::DataBuffer& operator<<(sp::DataBuffer& a_Buffer, const ChunkPtr& a_Chunk); sp::DataBuffer& operator<<(sp::DataBuffer& a_Buffer, const ChunkPtr& a_Chunk);
sp::DataBuffer& operator>>(sp::DataBuffer& a_Buffer, ChunkPtr& a_Chunk); sp::DataBuffer& operator>>(sp::DataBuffer& a_Buffer, ChunkPtr& a_Chunk);
sp::DataBuffer& operator<<(sp::DataBuffer& buffer, const TilePtr& tile);
sp::DataBuffer& operator>>(sp::DataBuffer& buffer, TilePtr& tile);
} // namespace game } // namespace game
} // namespace td } // namespace td

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <td/game/WorldTypes.h> #include <td/game/WorldTypes.h>
#include <td/game/Mobs.h>
namespace td { namespace td {
namespace sim { namespace sim {

View File

@@ -13,7 +13,6 @@
#include <sp/common/DataBuffer.h> #include <sp/common/DataBuffer.h>
#include <sp/extensions/Compress.h> #include <sp/extensions/Compress.h>
#include <sp/io/MessageStream.h> #include <sp/io/MessageStream.h>
#include <sp/io/MessageSerialize.h>
#include <sp/io/StdIo.h> #include <sp/io/StdIo.h>
class WorldApply : public td::protocol::PacketHandler { class WorldApply : public td::protocol::PacketHandler {

View File

@@ -5,27 +5,39 @@
namespace td { namespace td {
namespace game { namespace game {
class ColorTileVisitor : public TileHandler {
private:
const World& m_World;
const Color* m_Result;
public:
ColorTileVisitor(const World& a_World) : m_World(a_World), m_Result(nullptr) {}
virtual void Handle(const EmptyTile& a_Tile) override {}
virtual void Handle(const TowerTile& a_Tile) override {
m_Result = &m_World.GetTowerTileColorPalette()[a_Tile->m_ColorPaletteRef];
}
virtual void Handle(const WalkableTile& a_Tile) override {
m_Result = &m_World.GetWalkableTileColor();
}
virtual void Handle(const DecorationTile& a_Tile) override {
m_Result = &m_World.GetDecorationPalette()[a_Tile->m_ColorPaletteRef];
}
const Color* GetResult() {
return m_Result;
}
};
World::World() : m_CurrentState(std::make_shared<sim::WorldSnapshot>()), m_NextState(m_CurrentState) {} World::World() : m_CurrentState(std::make_shared<sim::WorldSnapshot>()), m_NextState(m_CurrentState) {}
const Color* World::GetTileColor(const TilePtr& tile) const { const Color* World::GetTileColor(const TilePtr& tile) const {
switch (tile->GetType()) { ColorTileVisitor visitor(*this);
case TileType::Tower: { tile->Dispatch(visitor);
TowerTile* towerTile = dynamic_cast<TowerTile*>(tile.get()); return visitor.GetResult();
return &m_TowerPlacePalette[towerTile->color_palette_ref];
}
case TileType::Walk: {
return &m_WalkablePalette;
}
case TileType::Decoration: {
DecorationTile* towerTile = dynamic_cast<DecorationTile*>(tile.get());
return &m_DecorationPalette[towerTile->color_palette_ref];
break;
}
default: {
return nullptr;
}
}
return nullptr;
} }
bool World::LoadMap(const protocol::pdata::WorldHeader& a_WorldHeader) { bool World::LoadMap(const protocol::pdata::WorldHeader& a_WorldHeader) {

View File

@@ -1,7 +1,5 @@
#include <td/game/WorldTypes.h> #include <td/game/WorldTypes.h>
#include <sp/common/DataBuffer.h>
namespace td { namespace td {
namespace game { namespace game {

View File

@@ -15,63 +15,5 @@ sp::DataBuffer& operator>>(sp::DataBuffer& a_Buffer, TeamCastle& a_Castle) {
return a_Buffer; return a_Buffer;
} }
sp::DataBuffer& operator<<(sp::DataBuffer& buffer, const TilePtr& tile) {
buffer << tile->GetType();
switch (tile->GetType()) {
case game::TileType::Tower: {
const game::TowerTile* towerTile = dynamic_cast<const game::TowerTile*>(tile.get());
buffer << towerTile->color_palette_ref << towerTile->team_owner;
break;
}
case game::TileType::Walk: {
const game::WalkableTile* walkTile = dynamic_cast<const game::WalkableTile*>(tile.get());
buffer << walkTile->direction;
break;
}
case game::TileType::Decoration: {
const game::DecorationTile* decoTile = dynamic_cast<const game::DecorationTile*>(tile.get());
buffer << decoTile->color_palette_ref;
break;
}
default:
break;
}
return buffer;
}
sp::DataBuffer& operator>>(sp::DataBuffer& buffer, TilePtr& tile) {
game::TileType tileType;
buffer >> tileType;
switch (tileType) {
case game::TileType::Tower: {
auto tilePtr = std::make_shared<game::TowerTile>();
buffer >> tilePtr->color_palette_ref >> tilePtr->team_owner;
tile = tilePtr;
break;
}
case game::TileType::Walk: {
auto tilePtr = std::make_shared<game::WalkableTile>();
buffer >> tilePtr->direction;
tile = tilePtr;
break;
}
case game::TileType::Decoration: {
auto tilePtr = std::make_shared<game::DecorationTile>();
buffer >> tilePtr->color_palette_ref;
tile = tilePtr;
break;
}
default:
break;
}
return buffer;
}
} // namespace game } // namespace game
} // namespace td } // namespace td

View File

@@ -3,7 +3,7 @@ add_rules("mode.debug", "mode.release")
add_repositories("persson-repo https://git.ale-pri.com/Persson-dev/xmake-repo.git") add_repositories("persson-repo https://git.ale-pri.com/Persson-dev/xmake-repo.git")
add_requires("imgui 1.92.0", {configs = {sdl3 = true, opengl3 = true}}) add_requires("imgui 1.92.0", {configs = {sdl3 = true, opengl3 = true}})
add_requires("splib 2.0.2", "zlib") add_requires("splib 2.1.0", "zlib")
add_requires("libsdl3 3.2.16", "glew", "fpm", "enet6") add_requires("libsdl3 3.2.16", "glew", "fpm", "enet6")
set_languages("c++17") set_languages("c++17")