Skip to main content

ecson_ecs/plugins/lobby/
mod.rs

1use crate::prelude::*;
2use bevy_ecs::prelude::*;
3use std::collections::HashMap;
4mod systems;
5use systems::*;
6
7// ============================================================================
8// リソース
9// ============================================================================
10
11/// 存在するロビーを管理するリソース
12#[derive(Resource, Default)]
13pub struct LobbyMap {
14    /// lobby_name → LobbyInfo
15    pub lobbies: HashMap<String, LobbyInfo>,
16}
17
18#[derive(Clone, Debug)]
19pub struct LobbyInfo {
20    pub name: String,
21    pub owner: u64,
22    pub members: Vec<u64>,
23    pub max_members: u32,
24    pub is_public: bool,
25}
26
27#[derive(Resource)]
28pub struct LobbyConfig {
29    pub default_max_members: u32,
30}
31
32// ============================================================================
33// コンポーネント
34// ============================================================================
35
36/// クライアントが参加中のロビー名
37#[derive(Component, Clone, Debug)]
38pub struct InLobby(pub String);
39
40// ============================================================================
41// イベント(コマンド)
42// ============================================================================
43
44#[derive(Message)]
45pub enum LobbyCommand {
46    /// ロビー作成
47    Create {
48        entity: Entity,
49        name: String,
50        max_members: u32,
51        is_public: bool,
52    },
53    /// ロビー参加
54    Join { entity: Entity, lobby_name: String },
55    /// ロビー退出
56    Leave { entity: Entity },
57    /// ロビー一覧取得
58    List { entity: Entity },
59    /// ロビー情報取得
60    Info { entity: Entity, lobby_name: String },
61}
62
63// ============================================================================
64// フックイベント(ユーザー向け)
65// ============================================================================
66
67#[derive(Message)]
68pub struct PlayerJoinedLobbyEvent {
69    pub client_id: u64,
70    pub lobby_name: String,
71}
72
73#[derive(Message)]
74pub struct PlayerLeftLobbyEvent {
75    pub client_id: u64,
76    pub lobby_name: String,
77}
78
79/// ロビーが規定人数に達してゲーム開始可能になった時に発火
80#[derive(Message)]
81pub struct LobbyReadyEvent {
82    pub lobby_name: String,
83    pub members: Vec<u64>,
84}
85
86// ============================================================================
87// プラグイン
88// ============================================================================
89
90pub struct LobbyPlugin {
91    pub default_max_members: u32,
92}
93
94impl Default for LobbyPlugin {
95    fn default() -> Self {
96        Self {
97            default_max_members: 4,
98        }
99    }
100}
101
102impl LobbyPlugin {
103    pub fn new() -> Self {
104        Self::default()
105    }
106
107    pub fn default_max_members(mut self, n: u32) -> Self {
108        self.default_max_members = n;
109        self
110    }
111}
112
113impl Plugin for LobbyPlugin {
114    fn build(&self, app: &mut EcsonApp) {
115        // LobbyConfig(新規)
116        app.world.insert_resource(LobbyConfig {
117            default_max_members: self.default_max_members,
118        });
119
120        if !app.world.contains_resource::<LobbyMap>() {
121            app.world.insert_resource(LobbyMap::default());
122        }
123
124        // イベント登録(変更なし)
125        app.add_event::<LobbyCommand>();
126        app.add_event::<PlayerJoinedLobbyEvent>();
127        app.add_event::<PlayerLeftLobbyEvent>();
128        app.add_event::<LobbyReadyEvent>();
129
130        app.add_systems(
131            Update,
132            (
133                parse_lobby_messages_system,
134                handle_lobby_create_system,
135                handle_lobby_join_system,
136                handle_lobby_leave_system,
137                handle_lobby_list_system,
138                handle_lobby_disconnect_system,
139            )
140                .chain(),
141        );
142    }
143}