Skip to content

Commit 86ff9dd

Browse files
Allow actions from the ui, and setting recipes
1 parent 3d7a0cf commit 86ff9dd

File tree

8 files changed

+128
-49
lines changed

8 files changed

+128
-49
lines changed

src/data.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ enum RawEntity {
311311
pub struct DataStore<ItemIdxType: WeakIdxTrait, RecipeIdxType: WeakIdxTrait> {
312312
pub checksum: String,
313313

314+
pub recipe_names: Vec<String>,
315+
314316
pub recipe_num_ing_lookup: Vec<usize>,
315317
pub recipe_num_out_lookup: Vec<usize>,
316318
pub recipe_to_ing_out_combo_idx: Vec<usize>,
@@ -743,6 +745,12 @@ impl RawDataStore {
743745
DataStore {
744746
checksum,
745747

748+
recipe_names: self
749+
.recipes
750+
.iter()
751+
.map(|r| r.display_name.clone())
752+
.collect(),
753+
746754
recipe_num_ing_lookup,
747755
recipe_num_out_lookup,
748756
recipe_to_ing_out_combo_idx,

src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,15 @@ fn run_integrated_server(
164164
.unwrap_or_else(|| GameState::new(&data_store)),
165165
));
166166

167+
let (ui_sender, ui_recv) = channel();
168+
167169
let mut game = Game::new(GameInitData::IntegratedServer {
168170
game_state: game_state.clone(),
169171
tick_counter: tick_counter.clone(),
170172
info: ServerInfo { connections },
171173
action_state_machine: state_machine.clone(),
172174
inputs: recv,
175+
ui_actions: ui_recv,
173176
})
174177
.unwrap();
175178

@@ -183,6 +186,7 @@ fn run_integrated_server(
183186
state: game_state,
184187
state_machine,
185188
data_store,
189+
ui_action_sender: ui_sender,
186190
}),
187191
tick_counter,
188192
send,
@@ -216,6 +220,8 @@ fn run_client(start_game_info: StartGameInfo) -> (LoadedGame, Arc<AtomicU64>, Se
216220
.unwrap_or_else(|| GameState::new(&data_store)),
217221
));
218222

223+
let (ui_sender, ui_recv) = channel();
224+
219225
let mut game = Game::new(GameInitData::Client {
220226
game_state: game_state.clone(),
221227
action_state_machine: state_machine.clone(),
@@ -225,6 +231,7 @@ fn run_client(start_game_info: StartGameInfo) -> (LoadedGame, Arc<AtomicU64>, Se
225231
ip: IpAddr::V4(Ipv4Addr::LOCALHOST),
226232
port: 8080,
227233
},
234+
ui_actions: ui_recv,
228235
})
229236
.unwrap();
230237

@@ -238,6 +245,7 @@ fn run_client(start_game_info: StartGameInfo) -> (LoadedGame, Arc<AtomicU64>, Se
238245
state: game_state,
239246
state_machine,
240247
data_store,
248+
ui_action_sender: ui_sender,
241249
}),
242250
tick_counter,
243251
send,

src/multiplayer/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ pub enum GameInitData<ItemIdxType: WeakIdxTrait, RecipeIdxType: WeakIdxTrait> {
6464
game_state: Arc<Mutex<GameState<ItemIdxType, RecipeIdxType>>>,
6565
action_state_machine: Arc<Mutex<ActionStateMachine<ItemIdxType, RecipeIdxType>>>,
6666
inputs: Receiver<Input>,
67+
ui_actions: Receiver<ActionType<ItemIdxType, RecipeIdxType>>,
6768
tick_counter: Arc<AtomicU64>,
6869
info: ClientConnectionInfo,
6970
},
@@ -72,6 +73,7 @@ pub enum GameInitData<ItemIdxType: WeakIdxTrait, RecipeIdxType: WeakIdxTrait> {
7273
game_state: Arc<Mutex<GameState<ItemIdxType, RecipeIdxType>>>,
7374
action_state_machine: Arc<Mutex<ActionStateMachine<ItemIdxType, RecipeIdxType>>>,
7475
inputs: Receiver<Input>,
76+
ui_actions: Receiver<ActionType<ItemIdxType, RecipeIdxType>>,
7577
tick_counter: Arc<AtomicU64>,
7678
info: ServerInfo,
7779
},
@@ -91,6 +93,7 @@ impl<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait> Game<ItemIdxType, RecipeIdx
9193
inputs,
9294
tick_counter,
9395
info,
96+
ui_actions,
9497
} => {
9598
let stream = std::net::TcpStream::connect((info.ip, info.port))?;
9699
Ok(Self::Client(
@@ -99,6 +102,7 @@ impl<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait> Game<ItemIdxType, RecipeIdx
99102
local_actions: action_state_machine,
100103
local_input: inputs,
101104
server_connection: stream,
105+
ui_actions,
102106
}),
103107
tick_counter,
104108
))
@@ -113,12 +117,14 @@ impl<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait> Game<ItemIdxType, RecipeIdx
113117
info,
114118
action_state_machine,
115119
inputs,
120+
ui_actions,
116121
} => Ok(Self::IntegratedServer(
117122
game_state,
118123
GameStateUpdateHandler::new(IntegratedServer {
119124
local_actions: action_state_machine,
120125
local_input: inputs,
121126
server: Server::new(info),
127+
ui_actions,
122128
}),
123129
tick_counter,
124130
)),

src/multiplayer/plumbing.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub(super) struct Client<ItemIdxType: WeakIdxTrait, RecipeIdxType: WeakIdxTrait>
3030
pub(super) local_input: Receiver<Input>,
3131
pub(super) local_actions: Arc<Mutex<ActionStateMachine<ItemIdxType, RecipeIdxType>>>,
3232
pub(super) server_connection: TcpStream,
33+
pub(super) ui_actions: Receiver<ActionType<ItemIdxType, RecipeIdxType>>,
3334
}
3435

3536
pub(super) struct Server<ItemIdxType: WeakIdxTrait, RecipeIdxType: WeakIdxTrait> {
@@ -52,13 +53,13 @@ impl<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait> Server<ItemIdxType, RecipeI
5253
impl<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait> ActionSource<ItemIdxType, RecipeIdxType>
5354
for Client<ItemIdxType, RecipeIdxType>
5455
{
55-
fn get(
56-
&self,
56+
fn get<'a>(
57+
&'a self,
5758
current_tick: u64,
5859
world: &World<ItemIdxType, RecipeIdxType>,
5960
data_store: &DataStore<ItemIdxType, RecipeIdxType>,
60-
) -> impl IntoIterator<Item = ActionType<ItemIdxType, RecipeIdxType>> + use<ItemIdxType, RecipeIdxType>
61-
{
61+
) -> impl IntoIterator<Item = ActionType<ItemIdxType, RecipeIdxType>>
62+
+ use<'a, ItemIdxType, RecipeIdxType> {
6263
// This will block (?) if we did not yet recieve the actions from the server for this tick
6364
// TODO: This could introduce hitches which might be noticeable.
6465
// This could be solved either by introducing some fixed delay on all actions (i.e. just running the client a couple ticks in the past compared to the server)
@@ -83,6 +84,8 @@ impl<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait> ActionSource<ItemIdxType, R
8384
postcard::from_io((&self.server_connection, &mut buffer)).unwrap();
8485

8586
recieved_actions
87+
.into_iter()
88+
.chain(self.ui_actions.try_iter())
8689
}
8790
}
8891

@@ -174,6 +177,7 @@ pub(super) struct IntegratedServer<ItemIdxType: WeakIdxTrait, RecipeIdxType: Wea
174177
pub(super) local_actions: Arc<Mutex<ActionStateMachine<ItemIdxType, RecipeIdxType>>>,
175178
pub(super) local_input: Receiver<Input>,
176179
pub(super) server: Server<ItemIdxType, RecipeIdxType>,
180+
pub(super) ui_actions: Receiver<ActionType<ItemIdxType, RecipeIdxType>>,
177181
}
178182

179183
impl<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait> ActionSource<ItemIdxType, RecipeIdxType>
@@ -215,7 +219,8 @@ impl<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait> ActionSource<ItemIdxType, R
215219
if start.elapsed() > Duration::from_millis(1) {
216220
error!("server.get {:?}", start.elapsed());
217221
}
218-
ret
222+
223+
ret.into_iter().chain(self.ui_actions.try_iter())
219224
}
220225
}
221226

src/power/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ use crate::{
1515
tile::{AssemblerID, MachineID},
1616
Position,
1717
},
18-
inserter::Storage,
19-
item::{IdxTrait, Item, WeakIdxTrait},
18+
item::{IdxTrait, WeakIdxTrait},
2019
TICKS_PER_SECOND_LOGIC,
2120
};
2221

src/rendering/eframe_app.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,20 @@ impl eframe::App for App {
118118

119119
self.last_rendered_update = tick;
120120

121-
render_ui(
121+
let render_actions = render_ui(
122122
ctx,
123123
&ui,
124124
&mut state_machine,
125125
&game_state,
126126
&loaded_game_sized.data_store,
127127
);
128+
129+
for action in render_actions {
130+
loaded_game_sized
131+
.ui_action_sender
132+
.send(action)
133+
.expect("Ui action channel died");
134+
}
128135
},
129136
LoadedGame::ItemU8RecipeU16(loaded_game_sized) => todo!(),
130137
LoadedGame::ItemU16RecipeU8(loaded_game_sized) => todo!(),

src/rendering/render_world.rs

Lines changed: 82 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,25 @@ use crate::{
55
belt::{belt::Belt, smart::SmartBelt, splitter::SPLITTER_BELT_LEN},
66
data::DataStore,
77
frontend::{
8-
action::action_state_machine::{ActionStateMachine, WIDTH_PER_LEVEL},
8+
action::{
9+
action_state_machine::{ActionStateMachine, WIDTH_PER_LEVEL},
10+
set_recipe::SetRecipeInfo,
11+
ActionType,
12+
},
913
world::tile::{
1014
AssemblerID, AssemblerInfo, BeltId, BeltTileId, Dir, Entity, BELT_LEN_PER_TILE,
1115
CHUNK_SIZE_FLOAT,
1216
},
1317
},
14-
item::{usize_from, IdxTrait, Item},
18+
item::{usize_from, IdxTrait, Item, Recipe},
1519
};
1620
use eframe::{
1721
egui::{
18-
self, Align2, CentralPanel, Color32, Context, CornerRadius, Pos2, ProgressBar, Rect, Shape,
19-
SidePanel, TopBottomPanel, Ui, Window,
22+
self, Align2, CentralPanel, Color32, ComboBox, Context, CornerRadius, Pos2, ProgressBar,
23+
Rect, Shape, SidePanel, TopBottomPanel, Ui, Window,
2024
},
2125
epaint::text::Row,
26+
wgpu::hal::auxil::db,
2227
};
2328
use egui_extras::{Column, TableBuilder};
2429
use log::{info, warn};
@@ -547,7 +552,9 @@ pub fn render_ui<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait>(
547552
state_machine: &mut ActionStateMachine<ItemIdxType, RecipeIdxType>,
548553
game_state: &GameState<ItemIdxType, RecipeIdxType>,
549554
data_store: &DataStore<ItemIdxType, RecipeIdxType>,
550-
) {
555+
) -> impl IntoIterator<Item = ActionType<ItemIdxType, RecipeIdxType>> {
556+
let mut actions = vec![];
557+
551558
match &state_machine.state {
552559
crate::frontend::action::action_state_machine::ActionStateMachineState::Idle => {},
553560
crate::frontend::action::action_state_machine::ActionStateMachineState::Holding(
@@ -565,45 +572,78 @@ pub fn render_ui<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait>(
565572

566573
if let Some(entity) = entity {
567574
match entity {
568-
crate::frontend::world::tile::Entity::Assembler { pos, info } => match info {
569-
crate::frontend::world::tile::AssemblerInfo::UnpoweredNoRecipe => {
570-
ui.label("Assembler");
571-
},
572-
crate::frontend::world::tile::AssemblerInfo::Unpowered(recipe) => {
573-
ui.label("Assembler");
574-
},
575-
crate::frontend::world::tile::AssemblerInfo::PoweredNoRecipe(grid) => {
576-
ui.label("Assembler");
577-
},
578-
crate::frontend::world::tile::AssemblerInfo::Powered {
579-
id,
580-
pole_position
581-
} => {
582-
ui.label("Assembler");
575+
crate::frontend::world::tile::Entity::Assembler { pos, info } => {
576+
let mut goal_recipe: Option<Recipe<RecipeIdxType>> = match info {
577+
AssemblerInfo::UnpoweredNoRecipe => None,
578+
AssemblerInfo::Unpowered(recipe) => Some(*recipe),
579+
AssemblerInfo::PoweredNoRecipe(position) => None,
580+
AssemblerInfo::Powered { id, pole_position } => Some(id.recipe),
581+
};
583582

584-
// TODO:
585-
// ui.label(data_store.recipe_names[usize_from(assembler_id.recipe.id)]);
583+
ComboBox::new("Recipe list", "Recipes").selected_text(goal_recipe.map(|recipe| data_store.recipe_names[usize_from(recipe.id)].as_str()).unwrap_or("Choose a recipe!")).show_ui(ui, |ui| {
584+
data_store.recipe_names.iter().enumerate().for_each(|(i, recipe_name)| {
585+
ui.selectable_value(&mut goal_recipe, Some(Recipe {id: i.try_into().unwrap()}), recipe_name);
586+
});
587+
});
586588

587-
let assembler = game_state
588-
.simulation_state
589-
.factory
590-
.power_grids
591-
.get_assembler_info(*id, data_store);
592-
593-
let pb = ProgressBar::new(assembler.timer_percentage).show_percentage().corner_radius(CornerRadius::ZERO);
594-
ui.add(pb);
595-
596-
TableBuilder::new(ui).columns(Column::auto().resizable(false), assembler.inputs.len() + assembler.outputs.len()).body(|mut body| {
597-
body.row(5.0, |mut row| {
598-
for (item, count) in assembler.inputs.iter().chain(assembler.outputs.iter()) {
599-
row.col(|ui| {
600-
ui.label(&data_store.item_names[usize_from(item.id)]);
601-
ui.label(format!("{}", *count));
602-
});
589+
590+
match info {
591+
crate::frontend::world::tile::AssemblerInfo::UnpoweredNoRecipe => {
592+
ui.label("Assembler");
593+
if let Some(goal_recipe) = goal_recipe {
594+
actions.push(ActionType::SetRecipe(SetRecipeInfo { pos: *pos, recipe: goal_recipe }));
595+
}
596+
},
597+
crate::frontend::world::tile::AssemblerInfo::Unpowered(recipe) => {
598+
ui.label("Assembler");
599+
if let Some(goal_recipe) = goal_recipe {
600+
if goal_recipe != *recipe {
601+
actions.push(ActionType::SetRecipe(SetRecipeInfo { pos: *pos, recipe: goal_recipe }));
603602
}
603+
}
604+
},
605+
crate::frontend::world::tile::AssemblerInfo::PoweredNoRecipe(grid) => {
606+
ui.label("Assembler");
607+
if let Some(goal_recipe) = goal_recipe {
608+
actions.push(ActionType::SetRecipe(SetRecipeInfo { pos: *pos, recipe: goal_recipe }));
609+
}
610+
},
611+
crate::frontend::world::tile::AssemblerInfo::Powered {
612+
id,
613+
pole_position
614+
} => {
615+
ui.label("Assembler");
616+
617+
if let Some(goal_recipe) = goal_recipe {
618+
if goal_recipe != id.recipe {
619+
actions.push(ActionType::SetRecipe(SetRecipeInfo { pos: *pos, recipe: goal_recipe }));
620+
}
621+
}
622+
623+
// TODO:
624+
// ui.label(data_store.recipe_names[usize_from(assembler_id.recipe.id)]);
625+
626+
let assembler = game_state
627+
.simulation_state
628+
.factory
629+
.power_grids
630+
.get_assembler_info(*id, data_store);
631+
632+
let pb = ProgressBar::new(assembler.timer_percentage).show_percentage().corner_radius(CornerRadius::ZERO);
633+
ui.add(pb);
634+
635+
TableBuilder::new(ui).columns(Column::auto().resizable(false), assembler.inputs.len() + assembler.outputs.len()).body(|mut body| {
636+
body.row(5.0, |mut row| {
637+
for (item, count) in assembler.inputs.iter().chain(assembler.outputs.iter()) {
638+
row.col(|ui| {
639+
ui.label(&data_store.item_names[usize_from(item.id)]);
640+
ui.label(format!("{}", *count));
641+
});
642+
}
643+
});
604644
});
605-
});
606-
},
645+
}
646+
}
607647
},
608648
crate::frontend::world::tile::Entity::PowerPole {
609649
ty,
@@ -785,6 +825,8 @@ pub fn render_ui<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait>(
785825
});
786826
});
787827
});
828+
829+
actions
788830
}
789831

790832
fn render_items_straight<ItemIdxType: IdxTrait, RecipeIdxType: IdxTrait>(

src/rendering/window.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use std::{
55

66
use crate::{
77
data::DataStore,
8-
frontend::{action::action_state_machine::ActionStateMachine, input::Input},
8+
frontend::{
9+
action::{action_state_machine::ActionStateMachine, ActionType},
10+
input::Input,
11+
},
912
item::WeakIdxTrait,
1013
rendering::render_world::render_world,
1114
saving::save,
@@ -51,6 +54,7 @@ pub struct LoadedGameSized<ItemIdxType: WeakIdxTrait, RecipeIdxType: WeakIdxTrai
5154
pub state: Arc<Mutex<GameState<ItemIdxType, RecipeIdxType>>>,
5255
pub state_machine: Arc<Mutex<ActionStateMachine<ItemIdxType, RecipeIdxType>>>,
5356
pub data_store: Arc<DataStore<ItemIdxType, RecipeIdxType>>,
57+
pub ui_action_sender: Sender<ActionType<ItemIdxType, RecipeIdxType>>,
5458
}
5559

5660
pub struct Window {

0 commit comments

Comments
 (0)