store rendered tile as entity rather than raw Paragraph

This commit is contained in:
Tao Tien 2026-01-13 03:32:08 -08:00
parent 9b99dad50b
commit 4112edbf2a
12 changed files with 63 additions and 47 deletions

View file

@ -2,7 +2,7 @@ use bevy::{ecs::relationship::RelationshipSourceCollection, prelude::*};
use crate::{ use crate::{
game::{player::Player /* wall::WallTiles */}, game::{player::Player /* wall::WallTiles */},
tiles::Tile, tile::Tile,
}; };
#[derive(Component)] #[derive(Component)]

View file

@ -6,7 +6,7 @@ use crate::{
player::{MainPlayer, Player}, player::{MainPlayer, Player},
wall::Wall, wall::Wall,
}, },
tiles::{self, *}, tile::{self, *},
}; };
pub mod hand; pub mod hand;
@ -31,7 +31,7 @@ impl Plugin for Riichi {
.init_state::<GameState>() .init_state::<GameState>()
.init_resource::<round::MatchSettings>() .init_resource::<round::MatchSettings>()
.init_resource::<round::Compass>() .init_resource::<round::Compass>()
.add_systems(Startup, tiles::init_tiles) .add_systems(Startup, tile::init_tiles)
.add_systems(OnEnter(GameState::Setup), setup) .add_systems(OnEnter(GameState::Setup), setup)
.add_systems(OnEnter(GameState::Deal), shuffle_deal) .add_systems(OnEnter(GameState::Deal), shuffle_deal)
.add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play))) .add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play)))

View file

@ -1,6 +1,6 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::tiles::*; use crate::tile::*;
#[derive(Component)] #[derive(Component)]
pub(crate) struct Dice(u8, u8); pub(crate) struct Dice(u8, u8);

View file

@ -1,7 +1,7 @@
use bevy::prelude::*; use bevy::prelude::*;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use crate::tiles::Tile; use crate::tile::Tile;
#[derive(Component)] #[derive(Component)]
pub struct Wall; pub struct Wall;

View file

@ -1,5 +1,5 @@
#![allow(unused)] #![allow(unused)]
pub mod game; pub mod game;
pub mod tiles; pub mod tile;
pub mod yakus; pub mod yakus;

View file

@ -66,7 +66,7 @@ impl Plugin for RiichiTui {
// gaming // gaming
.init_resource::<render::hand::RenderedHand>() .init_resource::<render::hand::RenderedHand>()
.add_systems(Update, render::hand::render_hand.run_if(in_state(InGame).and(in_state(GameState::Play)))) .add_systems(PostUpdate, render::hand::render_hands.run_if(in_state(InGame).and(in_state(GameState::Play))))
.add_systems(PostUpdate, render::ingame::draw_ingame.run_if(in_state(InGame))) .add_systems(PostUpdate, render::ingame::draw_ingame.run_if(in_state(InGame)))
// semicolon stopper // semicolon stopper

View file

@ -3,19 +3,21 @@ use ratatui::widgets::Paragraph;
use jong::{ use jong::{
game::{hand::Hand, player::Player}, game::{hand::Hand, player::Player},
tiles::Tile, tile::Tile,
}; };
use crate::tui::render::tiles; use crate::tui::render::tile::{self, RenderedTile};
#[derive(Resource, Default)] #[derive(Resource, Default)]
pub(crate) struct RenderedHand(pub(crate) HashMap<Entity, Vec<Paragraph<'static>>>); pub(crate) struct RenderedHand(pub(crate) HashMap<Entity, Vec<Entity>>);
pub(crate) fn render_hand( #[allow(clippy::type_complexity)]
pub(crate) fn render_hands(
mut commands: Commands,
mut rendered_hand: ResMut<RenderedHand>,
tiles: Populated<&Tile>, tiles: Populated<&Tile>,
player_hands: Populated<(Entity, &Children), (With<Player>, Changed<Hand>)>, player_hands: Populated<(Entity, &Children), (With<Player>, Changed<Hand>)>,
hands: Populated<&Children, (Changed<Hand>, Without<Player>)>, hands: Populated<&Children, (Changed<Hand>, Without<Player>)>,
mut target: ResMut<RenderedHand>,
) -> Result { ) -> Result {
let mut rendered = HashMap::new(); let mut rendered = HashMap::new();
@ -24,12 +26,21 @@ pub(crate) fn render_hand(
let tiles = hands let tiles = hands
.get(hand)? .get(hand)?
.iter() .iter()
.map(|it| tiles.get(it).map(tiles::draw_tile).unwrap()) .map(|it| {
tiles
.get(it)
// .inspect(|t| debug!("{t:?}"))
.map(tile::draw_tile)
.map(|p| commands.spawn(RenderedTile(p)).id())
// .inspect(|e| debug!("{e:?}"))
.unwrap()
})
.collect(); .collect();
rendered.insert(player_ent, tiles); rendered.insert(player_ent, tiles);
} }
target.0 = rendered; rendered_hand.0 = rendered;
trace!("render_hands");
Ok(()) Ok(())
} }

View file

@ -2,10 +2,11 @@ use bevy::prelude::*;
use bevy_ratatui::RatatuiContext; use bevy_ratatui::RatatuiContext;
use jong::game::player::{MainPlayer, Player}; use jong::game::player::{MainPlayer, Player};
use crate::tui::render::hand; use crate::tui::render::{hand, tile::RenderedTile};
pub(crate) fn draw_ingame( pub(crate) fn draw_ingame(
rendered_hand: Res<hand::RenderedHand>, rendered_hand: Res<hand::RenderedHand>,
rendered_tiles: Populated<&RenderedTile>,
main_player: Single<Entity, (With<Player>, With<MainPlayer>)>, main_player: Single<Entity, (With<Player>, With<MainPlayer>)>,
mut tui_ctx: ResMut<RatatuiContext>, mut tui_ctx: ResMut<RatatuiContext>,
) -> Result { ) -> Result {
@ -22,7 +23,7 @@ pub(crate) fn draw_ingame(
// if let Some(hand) = rendered_hand.0.get(&*main_player) { // if let Some(hand) = rendered_hand.0.get(&*main_player) {
if let Some(hand) = rendered_hand.0.get(&*main_player) { if let Some(hand) = rendered_hand.0.get(&*main_player) {
for (tile, area) in hand.iter().zip(areas.iter()) { for (tile, area) in hand.iter().zip(areas.iter()) {
frame.render_widget(tile, *area); frame.render_widget(&rendered_tiles.get(*tile).unwrap().0, *area);
} }
} }
})?; })?;

View file

@ -1,3 +1,3 @@
pub(crate) mod hand; pub(crate) mod hand;
pub(crate) mod ingame; pub(crate) mod ingame;
mod tiles; pub(crate) mod tile;

34
src/tui/render/tile.rs Normal file
View file

@ -0,0 +1,34 @@
use bevy::prelude::*;
use ratatui::widgets::Paragraph;
use jong::tile::Tile;
#[derive(Component)]
pub(crate) struct RenderedTile(pub(crate) Paragraph<'static>);
pub(crate) fn draw_tile(tile: &Tile) -> Paragraph<'static> {
use ratatui::prelude::*;
let block = ratatui::widgets::Block::bordered();
Paragraph::new(match &tile.suit {
jong::tile::Suit::Pin(rank) => format!("{}\np", rank.0),
jong::tile::Suit::Sou(rank) => format!("{}\ns", rank.0),
jong::tile::Suit::Man(rank) => format!("{}\nm", rank.0),
jong::tile::Suit::Wind(wind) => (match wind {
jong::tile::Wind::Ton => "e\nw",
jong::tile::Wind::Nan => "s\nw",
jong::tile::Wind::Shaa => "w\nw",
jong::tile::Wind::Pei => "n\nw",
})
.into(),
jong::tile::Suit::Dragon(dragon) => (match dragon {
jong::tile::Dragon::Haku => "w\nd",
jong::tile::Dragon::Hatsu => "g\nd",
jong::tile::Dragon::Chun => "r\nd",
})
.into(),
})
.block(block)
.centered()
}

View file

@ -1,30 +0,0 @@
use ratatui::widgets::Paragraph;
use jong::tiles::Tile;
pub(crate) fn draw_tile(tile: &Tile) -> Paragraph<'static> {
use ratatui::prelude::*;
let block = ratatui::widgets::Block::bordered();
Paragraph::new(match &tile.suit {
jong::tiles::Suit::Pin(rank) => format!("{}\np", rank.0),
jong::tiles::Suit::Sou(rank) => format!("{}\ns", rank.0),
jong::tiles::Suit::Man(rank) => format!("{}\nm", rank.0),
jong::tiles::Suit::Wind(wind) => (match wind {
jong::tiles::Wind::Ton => "e\nw",
jong::tiles::Wind::Nan => "s\nw",
jong::tiles::Wind::Shaa => "w\nw",
jong::tiles::Wind::Pei => "n\nw",
})
.into(),
jong::tiles::Suit::Dragon(dragon) => (match dragon {
jong::tiles::Dragon::Haku => "w\nd",
jong::tiles::Dragon::Hatsu => "g\nd",
jong::tiles::Dragon::Chun => "r\nd",
})
.into(),
})
.block(block)
.centered()
}