21 Room::Room(
const std::string &
id,
const std::string &name,
size_t maxPlayers,
bool isPrivate,
22 float gameSpeedMultiplier, std::shared_ptr<EventBus> eventBus)
24 _name(name.empty() ? id : name),
26 _maxPlayers(maxPlayers),
27 _isPrivate(isPrivate),
28 _gameSpeedMultiplier(gameSpeedMultiplier),
30 _gameStartSent(false) {
33 _eventBus = eventBus ? eventBus : std::make_shared<EventBus>();
34 std::shared_ptr<ecs::wrapper::ECSWorld> ecsWorld = std::make_shared<ecs::wrapper::ECSWorld>();
35 std::shared_ptr<ThreadPool> threadPool = std::make_shared<ThreadPool>(4);
37 std::unique_ptr<IGameLogic> gameLogic = std::make_unique<GameLogic>(ecsWorld, threadPool,
_eventBus);
41 LOG_ERROR(
"Failed to initialize game loop for room ",
_id);
42 throw std::runtime_error(
"Failed to initialize game loop for room " +
_id);
50 " players, Private: ", (
_isPrivate ?
"Yes" :
"No"),
"] with dedicated GameLoop");
54 std::lock_guard<std::mutex> lock(
_mutex);
57 LOG_WARNING(
"Player ", playerId,
" cannot join room ",
_id,
" - room is full");
62 LOG_WARNING(
"Player ", playerId,
" cannot join room ",
_id,
" - game already in progress");
73 LOG_INFO(
"Player ", playerId,
" is host of room ",
_id);
81 std::lock_guard<std::mutex> lock(
_mutex);
94 std::lock_guard<std::mutex> lock(
_mutex);
111 LOG_INFO(
"Room ",
_id,
" reset to WAITING (no players left)");
122 " spectators remaining)");
131 const char *stateNames[] = {
"WAITING",
"STARTING",
"IN_PROGRESS",
"FINISHED"};
133 stateNames[
static_cast<int>(state)]);
139 std::lock_guard<std::mutex> lock(
_mutex);
144 std::lock_guard<std::mutex> lock(
_mutex);
149 std::lock_guard<std::mutex> lock(
_mutex);
162 std::lock_guard<std::mutex> lock(
_mutex);
168 std::lock_guard<std::mutex> lock(
_mutex);
171 LOG_WARNING(
"Cannot start game in room ",
_id,
" - invalid state");
182 LOG_ERROR(
"Failed to initialize game logic for room ",
_id);
189 auto gameLogicPtr = std::dynamic_pointer_cast<GameLogic>(
_gameLogic);
191 gameLogicPtr->onGameStart();
193 LOG_ERROR(
"Failed to cast IGameLogic to GameLogic for room ",
_id);
198 std::vector<uint32_t> failedPlayers;
199 for (uint32_t playerId :
_players) {
200 uint32_t entityId =
_gameLogic->spawnPlayer(playerId,
"Player" + std::to_string(playerId));
202 LOG_ERROR(
"Failed to spawn player ", playerId,
" in room ",
_id);
203 failedPlayers.push_back(playerId);
208 if (!failedPlayers.empty()) {
209 for (uint32_t playerId : failedPlayers) {
213 LOG_WARNING(
"Removed player ", playerId,
" from room ",
_id,
" due to spawn failure");
219 LOG_ERROR(
"No players left in room ",
_id,
" after spawn failures");
232 static uint32_t tick = 0;
245 LOG_INFO(
"Player ", playerId,
" is now host of room ",
_id);
257 std::lock_guard<std::mutex> lock(
_mutex);
266 const std::string &message) {
270 LOG_INFO(
"[Room ",
_id,
"] Chat from ", senderName,
" (", senderId,
"): ", message);
Interface for server-side game logic orchestration.
RoomInfo getInfo() const override
Get room information.
bool leave(uint32_t playerId) override
Remove a player from the room.
void broadcastChatMessage(uint32_t senderId, const std::string &senderName, const std::string &message)
Broadcast a chat message to all players in the room.
bool isFull() const override
Check if room is full.
bool tryMarkGameStartSent()
Atomically check and set GameStart sent flag (thread-safe)
std::shared_ptr< EventBus > _eventBus
std::vector< uint32_t > _spectators
bool join(uint32_t playerId) override
Join a player to the room.
void setState(RoomState state) override
Set the state of the room.
void requestStartGame()
Request to start the game (initiates countdown)
bool hasSpectator(uint32_t playerId) const override
Check if a spectator is in this room.
std::vector< uint32_t > _players
void setHost(uint32_t playerId)
Set the host player ID.
std::vector< uint32_t > getPlayers() const override
Get list of player IDs in this room.
std::unique_ptr< ServerLoop > _gameLoop
size_t getPlayerCount() const override
Get number of players currently in room.
float _gameSpeedMultiplier
std::shared_ptr< IGameLogic > _gameLogic
bool hasPlayer(uint32_t playerId) const override
Check if a player is in this room.
Room(const std::string &id, const std::string &name="", size_t maxPlayers=4, bool isPrivate=false, float gameSpeedMultiplier=1.0f, std::shared_ptr< EventBus > eventBus=nullptr)
Construct a room.
std::vector< uint32_t > getSpectators() const override
Get list of spectator IDs in this room.
void update(float deltaTime)
Update the room state (called by server loop)
bool startGame()
Start the game for this room.
bool joinAsSpectator(uint32_t playerId) override
Join a player to the room as a spectator.
RoomState
State of a game room.
Information about a room.