-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Description
Monolith Overview, https://crates.io/crates/yunfengzh_monolith
I'm glad to introduce my project -- monolith which is a framework based on tokio and bevy. Later
pseudo-code gives an overview:
async sprite::run() {
sprite_in_village();
...
sprite_enter_dungeon();
loop {
match evt = from_bevy().await {
GameEvent::MoveLeft => {
self.pos.translation.x -= 1.0;
to_bevy().send(Task::SyncEntity, self.entity, self.pos);
}
...
}
}
...
}
- Sprite::run should be based on sprite state machine rather than being split to fit with ECS.
- Sprite::run hardcodes GameEvent (logic event).
- Monolith treats bevy as a display and event-dispatched library -- from_bevy and to_bevy.
- Monolith supports tokio, that is, you can run time-cost algorithm in coroutine context.
Unfortunately, I face some problem during the monolith, I hope bevy team to support.
Accelerate to_bevy().send
Currently, to_bevy().send is mainly
fn exclusive_system(world: &mut World) {
...
world.run_system_once_with(task.user_defined_system, task.param);
...
}
Since world.run_system_once_with run sequentially, so it's low performance.
Rare System
Some system is rare system such as NewEntity, I hope later API
let cmdqueue = App::get_commands(); // New API
cmdqueue.run_system_cached_with(mysystem, param);
The reason is exclusive_system runs every Update schedule, it's totally unnecessary.
Frequent System
Some system is frequent system such as SyncEntity, I hope later API
#[derive(Event)]
struct ToBevyTask(...);
let ew = App::get_event_writer<ToBevyTask>(); // New API, get EventWriter from bevy.
app.add_systems(Update, user_defined_system.run_if(on_event::<ToBevyTask>()));
Event Dispatch System, from_bevy()
To get keyboard event from bevy, currently later system is used
fn keyboard_system(er: EventReader<KeyboardInput>) {
....
}
I hope later API so I can deal with events in coroutine rather than bevy system.
let er = App::get_event_reader<ToBevyTask>(); // New API, get EventReader from bevy.
er.receive().await; // er should be tokio channel.
ECS crate
ECS which bring an innovation idea that split the fields of a struct into components. Put all
components close to each other to improve cache hit rate. But it can be done manually in tokio.
Sprite { ... } -> SpritePos -> Vec<SpritePos>.- run algorithm in coroutine.
- Optionally, update original objects.
Here, I hope ECS crate can be public. So ECS component can be used in mygame.
#[derive(component)]
struct MapUnit{ ... };
get_base_address() -> *mut MapUnit
get_entity(*const MapUnit) -> Entity
get_entity_by_offset(Entity, map_width) -> Entity
And to fit with function paradigm, I need sum up multiple results to target component.
let target = ECS::get_component(index);
let a_mut_copy = target.get_mut_clone();
// above line can be run several times, so multiple coroutine can be executed in parallel
sum_up(iterator_of_mut_clones(target), target);