r-type  0.0.0
R-Type main
Loading...
Searching...
No Matches
PlayerControllerMulti.hpp
Go to the documentation of this file.
1///
2/// @file PlayerControllerMulti.hpp
3/// @brief Multiplayer player controller system for R-Type client
4/// @details This file contains the player controller system for multiplayer mode.
5/// It handles local player input, sends input commands to the server,
6/// and manages client-side prediction for smooth gameplay.
7/// The system implements input throttling and sequence numbering for
8/// reliable input transmission over the network.
9/// @namespace gme
10/// @author R-Type Team
11/// @date 2025
12///
13
14#pragma once
15
16#include <deque>
17
19#include "ECS/Registry.hpp"
21#include "Utils/Common.hpp"
22#include "Utils/EventBus.hpp"
23
24namespace gme
25{
26 ///
27 /// @class PlayerControllerMulti
28 /// @brief Manages local player input and network communication for multiplayer
29 /// @details This system handles:
30 /// - Capturing and processing player keyboard input
31 /// - Sending input commands to the game server
32 /// - Client-side prediction for responsive controls
33 /// - Input throttling to reduce network bandwidth
34 /// - Sequence numbering for input acknowledgment
35 ///
36 /// The controller sends input updates to the server at a maximum rate
37 /// of 144 Hz and maintains a history of pending inputs for reconciliation.
38 ///
39 /// @namespace gme
40 ///
42 {
43 public:
44 ///
45 /// @brief Constructor
46 /// @param renderer Shared pointer to the renderer interface
47 /// @param sessionId Player's network session ID
48 /// @details Initializes the controller and registers with the event bus
49 ///
50 explicit PlayerControllerMulti(const std::shared_ptr<eng::IRenderer> &renderer, uint32_t sessionId)
51 : m_renderer(renderer), m_playerEntity(0), m_eventBus(utl::EventBus::getInstance())
52 {
53 m_componentId = 11;
54 m_eventBus.registerComponent(m_componentId, "PlayerControllerMulti");
55 }
56
57 ///
58 /// @brief Destructor
59 ///
60 ~PlayerControllerMulti() override = default;
61
62 ///
63 /// @brief Deleted copy constructor (non-copyable)
64 ///
66
67 ///
68 /// @brief Deleted copy assignment operator (non-copyable)
69 ///
71
72 ///
73 /// @brief Deleted move constructor (non-movable)
74 ///
76
77 ///
78 /// @brief Deleted move assignment operator (non-movable)
79 ///
81
82 ///
83 /// @brief Update the player controller system (called each frame)
84 /// @param registry ECS registry containing all entities and components
85 /// @param dt Delta time since last frame (in seconds)
86 /// @details Processes input state and sends updates to server if inputs changed
87 ///
88 void update(ecs::Registry &registry, float dt) override;
89
90 ///
91 /// @brief Handle input events from the window
92 /// @param registry ECS registry
93 /// @param event Input event (keyboard press/release)
94 /// @details Updates internal key state for the player's controls
95 ///
96 void handleInput(ecs::Registry &registry, const eng::Event &event);
97
98 ///
99 /// @brief Create the local player entity
100 /// @param registry ECS registry to create entity in
101 /// @param x Initial X position
102 /// @param y Initial Y position
103 /// @return Created player entity ID
104 /// @details Creates a player entity with all necessary components for gameplay
105 ///
106 ecs::Entity createPlayer(ecs::Registry &registry, float x, float y);
107
108 ///
109 /// @brief Check if space bar is currently pressed
110 /// @return True if space is pressed (shooting)
111 ///
112 bool isSpacePressed() const;
113
114 private:
115 ///
116 /// @brief Send input command to server via event bus
117 /// @param up Move up key pressed
118 /// @param down Move down key pressed
119 /// @param left Move left key pressed
120 /// @param right Move right key pressed
121 /// @param shoot Shoot key pressed
122 /// @details Serializes input state and sends to server as INPUT event
123 ///
124 void sendInputToServer(bool up, bool down, bool left, bool right, bool shoot) const;
125
126 ///
127 /// @brief Send input update if state has changed
128 /// @details Only sends updates when input state changes to reduce network traffic
129 ///
130 void sendInputsIfChanged();
131
132 const std::shared_ptr<eng::IRenderer> &m_renderer; ///< Renderer interface reference
133 std::unordered_map<eng::Key, bool> m_keysPressed; ///< Current state of all keys
134 ecs::Entity m_playerEntity; ///< Local player entity ID
135 uint32_t m_componentId; ///< Event bus component ID
136 utl::EventBus &m_eventBus; ///< Event bus reference
137
138 const float INPUT_THROTTLE_INTERVAL = 1.0f / 144.0f; ///< Maximum input send rate (144 Hz)
139
140 uint32_t m_nextSeqId = 1; ///< Next sequence ID for input packets
141 uint32_t m_lastAckSeqId = 0; ///< Last acknowledged sequence ID from server
142
143 ///
144 /// @struct PendingInput
145 /// @brief Represents an input command awaiting server acknowledgment
146 /// @details Used for client-side prediction and reconciliation
147 ///
149 {
150 uint32_t seqId; ///< Sequence number of this input
151 std::vector<uint8_t> inputData; ///< Serialized input data
152 float dt; ///< Delta time when input was sent
153 };
154 }; // class PlayerControllerMulti
155} // namespace gme
Thread-safe event bus implementation for inter-component communication.
This file contains the IRenderer class declaration.
This file contains the interface for systems.
This file contains the Registry class declaration.
Abstract class for system.
Definition ISystems.hpp:34
Class for managing entities and their components.
Definition Registry.hpp:25
Manages local player input and network communication for multiplayer.
uint32_t m_nextSeqId
Next sequence ID for input packets.
uint32_t m_componentId
Event bus component ID.
PlayerControllerMulti(const PlayerControllerMulti &)=delete
Deleted copy constructor (non-copyable)
~PlayerControllerMulti() override=default
Destructor.
std::unordered_map< eng::Key, bool > m_keysPressed
Current state of all keys.
bool isSpacePressed() const
Check if space bar is currently pressed.
PlayerControllerMulti & operator=(PlayerControllerMulti &&)=delete
Deleted move assignment operator (non-movable)
void sendInputToServer(bool up, bool down, bool left, bool right, bool shoot) const
Send input command to server via event bus.
void sendInputsIfChanged()
Send input update if state has changed.
PlayerControllerMulti & operator=(const PlayerControllerMulti &)=delete
Deleted copy assignment operator (non-copyable)
uint32_t m_lastAckSeqId
Last acknowledged sequence ID from server.
ecs::Entity m_playerEntity
Local player entity ID.
void handleInput(ecs::Registry &registry, const eng::Event &event)
Handle input events from the window.
const float INPUT_THROTTLE_INTERVAL
Maximum input send rate (144 Hz)
PlayerControllerMulti(PlayerControllerMulti &&)=delete
Deleted move constructor (non-movable)
ecs::Entity createPlayer(ecs::Registry &registry, float x, float y)
Create the local player entity.
const std::shared_ptr< eng::IRenderer > & m_renderer
Renderer interface reference.
PlayerControllerMulti(const std::shared_ptr< eng::IRenderer > &renderer, uint32_t sessionId)
Constructor.
utl::EventBus & m_eventBus
Event bus reference.
void update(ecs::Registry &registry, float dt) override
Update the player controller system (called each frame)
Thread-safe event bus for decoupled component communication.
Definition EventBus.hpp:31
void registerComponent(std::uint32_t componentId, const std::string &name)
Register component name for better debugging.
Definition EventBus.hpp:423
This file contains common definitions and constants.
std::uint32_t Entity
Definition Entity.hpp:13
Represents an input command awaiting server acknowledgment.
uint32_t seqId
Sequence number of this input.
std::vector< uint8_t > inputData
Serialized input data.
float dt
Delta time when input was sent.