Skip to content

Commit 525709d

Browse files
committed
refactor(wip)! use u8 as underlying consolebuffer storage
This changes the ConsoleBuffer to use a VecDeque of u8 instead of a VecDeque of char. This allows us to more easily convert to and from string slices, and allows for tighter control of memory allocation.
1 parent e1b196f commit 525709d

File tree

14 files changed

+417
-246
lines changed

14 files changed

+417
-246
lines changed

crates/cmd_prompt/src/actions/actions/basic_input.rs

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ use crate::prelude::*;
44

55
pub fn delete_char(
66
input: In<ConsoleActionSystemInput>,
7-
mut console_q: Query<&mut ConsoleInputText>,
7+
mut console_q: Query<(&mut ConsoleInputText, &mut ConsoleBuffer)>,
88
) {
9-
if let Ok(mut input) = console_q.get_mut(input.console_id) {
10-
let popped = input.text.pop();
11-
if let Some(popped) = popped {
12-
input.move_cursor(-(popped.len_utf8() as isize));
13-
}
9+
if let Ok((mut input, mut buffer)) = console_q.get_mut(input.console_id) {
10+
let len = buffer.pop_front().map(|c| c.len_utf8()).unwrap_or_default();
11+
input.move_cursor(-(len as isize));
1412
} else {
1513
error!(
1614
"Could not delete char from console with id {}",
@@ -23,9 +21,10 @@ pub fn delete_word(
2321
mut console_q: Query<&mut ConsoleInputText>,
2422
) {
2523
if let Ok(mut input) = console_q.get_mut(input.console_id) {
26-
let last_ws = input.text.rfind(char::is_whitespace).unwrap_or_default();
27-
input.text.truncate(last_ws);
28-
input.set_cursor(last_ws);
24+
// TODO
25+
// let last_ws = input.text.rfind(char::is_whitespace).unwrap_or_default();
26+
// input.text.truncate(last_ws);
27+
// input.set_cursor(last_ws)
2928
} else {
3029
error!(
3130
"Could not delete word from console with id {}",
@@ -39,22 +38,31 @@ pub fn write_char(
3938
mut commands: Commands,
4039
) {
4140
if let Ok(mut input_text) = console_q.get_mut(input.console_id) {
42-
let pos = input_text.cursor();
4341
for key in input.matched_logical_keys() {
4442
match key {
4543
Key::Character(c) => {
46-
input_text.text.insert_str(pos, c.as_str());
44+
commands.write_message(ConsoleWriteMsg {
45+
message: c.to_string(),
46+
console_id: input.console_id,
47+
pos: input_text.anchor + input_text.cursor(),
48+
});
4749
input_text.move_cursor(c.len() as isize);
4850
}
4951
Key::Space => {
50-
input_text.text.insert(pos, ' ');
52+
commands.write_message(ConsoleWriteMsg {
53+
message: " ".to_string(),
54+
console_id: input.console_id,
55+
pos: input_text.anchor + input_text.cursor(),
56+
});
5157
input_text.move_cursor(1);
5258
}
5359
Key::Enter => {
54-
if input_text.cursor() == input_text.text.len() {
55-
input_text.text.insert(pos, '\n');
56-
}
57-
input_text.text.push('\n');
60+
commands.write_message(ConsoleWriteMsg {
61+
message: "\n".to_string(),
62+
console_id: input.console_id,
63+
pos: input_text.anchor + input_text.cursor(),
64+
});
65+
input_text.move_cursor(1);
5866
}
5967
_ => {}
6068
}
@@ -70,32 +78,32 @@ pub fn write_char(
7078

7179
pub fn submit(
7280
input: In<ConsoleActionSystemInput>,
73-
mut query: Query<(&mut ConsoleInputText, &ConsoleAssetHandle<ConsoleHistory>)>,
81+
mut query: Query<(
82+
&mut ConsoleInputText,
83+
&ConsoleAssetHandle<ConsoleHistory>,
84+
&ConsoleBuffer,
85+
)>,
7486
mut assets: ResMut<Assets<ConsoleHistory>>,
7587
mut commands: Commands,
7688
) {
77-
if let Ok((mut input_text, history_handle)) = query.get_mut(input.console_id) {
89+
if let Ok((mut input_text, history_handle, buffer)) = query.get_mut(input.console_id) {
7890
let history = assets.get_mut(history_handle.as_asset_id());
7991
if history.is_none() {
8092
error!("Failed to get console history!");
8193
return;
8294
}
8395
let history = history.unwrap();
84-
commands.write_message(ConsoleWriteMsg {
85-
message: "\n".to_string(),
86-
console_id: input.console_id,
87-
});
88-
if let Some(event) = SubmitEvent::new(input.console_id, input_text.text.clone()) {
96+
let command = buffer.range(input_text.anchor, buffer.len() - input_text.anchor);
97+
if let Some(event) = SubmitEvent::new(input.console_id, command.clone()) {
8998
commands.trigger(event);
9099
} else {
91-
commands.write_message(ConsoleWriteMsg {
92-
message: "Invalid shell expression\n".into(),
93-
console_id: input.console_id,
94-
});
100+
commands.trigger(ConsolePrintln::new(
101+
input.console_id,
102+
"Invalid shell expression".to_string(),
103+
));
95104
}
96-
let history_value = std::mem::take(&mut input_text.text);
97105
input_text.set_cursor(0);
98-
history.push(history_value);
106+
history.push(command);
99107
} else {
100108
error!("Could not submit from console with id {}", input.console_id);
101109
}
@@ -110,9 +118,15 @@ fn clear(input: In<ConsoleActionSystemInput>, mut commands: Commands) {
110118
commands.run_system_cached_with(clear_buffer, input.console_id);
111119
}
112120

113-
fn clear_input(input: In<ConsoleActionSystemInput>, mut query: Query<&mut ConsoleInputText>) {
114-
let mut input = query.get_mut(input.console_id).unwrap();
115-
input.text.clear();
121+
fn clear_input(
122+
input: In<ConsoleActionSystemInput>,
123+
mut query: Query<(&mut ConsoleInputText, &mut ConsoleBuffer)>,
124+
) {
125+
// TODO: Don't edit buffer directly! Use a message
126+
let (mut input, mut buffer) = query.get_mut(input.console_id).unwrap();
127+
for _ in 0..(buffer.len() - input.anchor) {
128+
buffer.pop_front();
129+
}
116130
input.set_cursor(0);
117131
}
118132

crates/cmd_prompt/src/actions/actions/history.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn set_from_history(
3232
.get_mut(handle.id())
3333
.expect("History asset should exist");
3434
if filtered_history.is_none() {
35-
*original_value = Some(std::mem::take(&mut input_text.text));
35+
// *original_value = Some(std::mem::take(&mut input_text.text));
3636
let f = history
3737
.iter()
3838
.enumerate()
@@ -44,13 +44,14 @@ pub fn set_from_history(
4444
let ov = original_value.as_ref().unwrap();
4545
*history_idx = history_idx.saturating_add_signed(value).min(fh.len());
4646
if *history_idx == 0 {
47-
input_text.text = ov.clone();
47+
// TODO: ConsoleBuffer::replace / splice from text input anchor till end
48+
// input_text.text = ov.clone();
4849
} else {
4950
let idx = fh[fh.len().saturating_sub(*history_idx)];
50-
input_text.text = history[idx].clone();
51+
// input_text.text = history[idx].clone();
5152
}
52-
let end = input_text.text.len();
53-
input_text.set_cursor(end);
53+
// let end = input_text.text.len();
54+
// input_text.set_cursor(end);
5455
}
5556
}
5657

@@ -93,7 +94,7 @@ mod test {
9394
.query::<&ConsoleInputText>()
9495
.single_mut(world)
9596
.unwrap();
96-
assert_eq!(input.text, $value);
97+
// assert_eq!(input.text, $value);
9798
world.write_message(key_input(KeyCode::$key, Key::$key, ButtonState::Pressed));
9899
world.write_message(key_input(KeyCode::$key, Key::$key, ButtonState::Released));
99100
world.resource_mut::<NextState<Step>>().set(Step($step + 1));
@@ -119,7 +120,7 @@ mod test {
119120
mut commands: Commands,
120121
mut next_step: ResMut<NextState<Step>>| {
121122
if let Ok(mut input) = q.single_mut() {
122-
input.text = step.to_string();
123+
// input.text = step.to_string();
123124
commands.write_message(key_input(
124125
KeyCode::Enter,
125126
Key::Enter,
@@ -177,7 +178,7 @@ mod test {
177178
.query::<&ConsoleInputText>()
178179
.single_mut(world)
179180
.unwrap();
180-
assert_eq!(input.text, "1");
181+
// assert_eq!(input.text, "1");
181182
world.write_message(AppExit::Success);
182183
});
183184
app.run();

crates/cmd_prompt/src/commands/app_ext.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ fn dispatch_cmd<T: ConsoleCommand>(
3535
Ok(())
3636
})();
3737
if let Err(e) = res {
38-
commands.write_message(ConsoleWriteMsg {
39-
message: e + "\n",
40-
console_id: input.console_id(),
41-
});
38+
commands.trigger(ConsolePrintln::new(input.console_id(), e));
4239
}
4340
}

crates/cmd_prompt/src/commands/commands/clear.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pub fn clear_buffer(
1414
let (mut buffer, mut input_text) = console_q.get_mut(*id).unwrap();
1515
buffer.clear();
1616
commands.write_message(ConsoleViewMsg::jump_to_bottom(*id));
17-
input_text.text.clear();
1817
input_text.anchor = 0;
1918
}
2019

crates/cmd_prompt/src/commands/commands/echo.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,16 @@ fn process_escapes(s: &str) -> String {
6161
result
6262
}
6363

64-
fn inner(input: In<CommandMsg<EchoCmd>>, world: &mut World) {
65-
let (cmd, console_id) = (input.0.command, input.0.console_id);
66-
let text = cmd.text.join(" ");
67-
let message = if cmd.enable_escapes && !cmd.disable_escapes {
68-
process_escapes(&text)
69-
} else {
70-
text
71-
};
72-
world.commands().write_message(ConsoleWriteMsg {
73-
message: message + "\n",
74-
console_id,
75-
});
76-
}
77-
7864
fn on_find_msg(mut reader: MessageReader<CommandMsg<EchoCmd>>, mut commands: Commands) {
7965
for msg in reader.read() {
80-
commands.run_system_cached_with(inner, msg.clone());
66+
let cmd = &msg.command;
67+
let text = cmd.text.join(" ");
68+
let message = if cmd.enable_escapes && !cmd.disable_escapes {
69+
process_escapes(&text)
70+
} else {
71+
text
72+
};
73+
commands.trigger(ConsolePrintln::new(msg.console_id, message));
8174
}
8275
}
8376

crates/cmd_prompt/src/commands/data.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ pub struct CommandMsg<T: ConsoleCommand> {
5050
}
5151
impl<T: ConsoleCommand> CommandMsg<T> {
5252
pub fn println(&self, commands: &mut Commands, message: String) {
53-
commands.write_message(ConsoleWriteMsg {
54-
message: message + "\n",
55-
console_id: self.console_id,
56-
});
53+
commands.trigger(ConsolePrintln::new(self.console_id, message));
5754
}
5855
}

crates/cmd_prompt/src/commands/events.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ fn on_submit(trigger: On<SubmitEvent>, cmds: Res<ConsoleCommands>, mut commands:
55
if let Some(cmd) = cmds.get(name) {
66
commands.run_system_with(cmd.dispatch, trigger.event().clone());
77
} else {
8-
commands.write_message(ConsoleWriteMsg {
9-
message: format!("Unknown command '{name}'\n"),
10-
console_id: trigger.console_id,
11-
});
8+
commands.trigger(ConsolePrintln::new(
9+
trigger.console_id,
10+
format!("Unknown command '{name}'"),
11+
));
1212
}
1313
}
1414

crates/cmd_prompt/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl Plugin for ConsolePlugin {
3535
(
3636
(
3737
handle_input.run_if(resource_exists::<InputFocus>),
38-
update_console_input_text,
38+
// update_console_input_text,
3939
clear_action_queue,
4040
clear_write_queue,
4141
clear_view_queue,

crates/cmd_prompt/src/systems.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub fn clear_write_queue(
8181
for item in reader.read() {
8282
let (mut buffer, mut input) = c!(buffer_q.get_mut(item.console_id));
8383
c!(buffer.write(&item.message));
84-
input.anchor = buffer.reset_write_anchor();
84+
input.anchor = buffer.len();
8585
}
8686
}
8787

0 commit comments

Comments
 (0)