o3 refactor

This commit is contained in:
reo 2025-07-22 21:12:05 +03:00
parent 341d531db3
commit 049f522bb1
19 changed files with 508 additions and 214 deletions

View file

@ -2,3 +2,11 @@
name = "raidillon_core"
version = "0.1.0"
edition = "2021"
[dependencies]
glam = "0.30.4"
hecs = "0.10.5"
raidillon_render = { path = "../raidillon_render" }
glium = { version = "0.35.0", features = ["glutin_backend", "simple_window_builder"] }
raidillon_ecs = { path = "../raidillon_ecs" }
anyhow = "1.0.98"

View file

@ -0,0 +1,42 @@
use std::collections::HashMap;
use raidillon_render::model::Model;
use glium::glutin::surface::WindowSurface;
use glium::Display;
use raidillon_render::gltf_loader;
use raidillon_ecs::ModelId;
use raidillon_render::render_system::ModelProvider;
use anyhow::Result;
pub struct AssetManager {
models: Vec<Model>,
model_cache: HashMap<String, ModelId>,
}
impl AssetManager {
pub fn new() -> Self {
Self { models: Vec::new(), model_cache: HashMap::new() }
}
/// Load or retrieve a cached model, returning its `ModelId`.
pub fn load_model<P: AsRef<str>>(&mut self, path: P, display: &Display<WindowSurface>) -> Result<ModelId> {
let path_str = path.as_ref();
if let Some(&id) = self.model_cache.get(path_str) {
return Ok(id);
}
let model = gltf_loader::load_gltf(path_str, display)?;
let id = ModelId(self.models.len());
self.models.push(model);
self.model_cache.insert(path_str.to_string(), id);
Ok(id)
}
pub fn get_model(&self, id: ModelId) -> Option<&Model> {
self.models.get(id.0)
}
}
impl ModelProvider for AssetManager {
fn get_model(&self, id: ModelId) -> Option<&Model> {
self.get_model(id)
}
}

View file

@ -0,0 +1,59 @@
use std::any::TypeId;
use std::collections::HashMap;
/// Core event enumeration.
/// Generic over the `Action` type to keep the engine agnostic to concrete
/// game-specific input enumerations.
#[derive(Debug, Clone)]
pub enum GameEvent<A> {
InputAction(A),
CameraMove { position: glam::Vec3, front: glam::Vec3 },
WindowResize { width: u32, height: u32 },
EntitySpawned(hecs::Entity),
}
pub trait EventHandler<A>: 'static {
fn handle(&mut self, event: &GameEvent<A>);
}
pub struct EventBus<A> {
events: Vec<GameEvent<A>>,
subscribers: HashMap<TypeId, Vec<Box<dyn EventHandler<A>>>>,
}
impl<A: 'static + Clone> EventBus<A> {
pub fn new() -> Self {
Self {
events: Vec::new(),
subscribers: HashMap::new(),
}
}
pub fn subscribe<H: EventHandler<A> + 'static>(&mut self, handler: H) {
self.subscribers
.entry(TypeId::of::<H>())
.or_default()
.push(Box::new(handler));
}
pub fn emit(&mut self, event: GameEvent<A>) {
self.events.push(event);
}
/// Process all queued events, dispatching them to every registered
/// subscriber.
pub fn process(&mut self) {
let events = std::mem::take(&mut self.events);
for ev in &events {
for subs in self.subscribers.values_mut() {
for h in subs {
h.handle(ev);
}
}
}
}
pub fn drain(&mut self) -> Vec<GameEvent<A>> {
std::mem::take(&mut self.events)
}
}

View file

@ -1,3 +1,14 @@
pub mod time;
pub use time::Time;
pub mod events;
pub use events::{EventBus, GameEvent, EventHandler};
pub mod assets;
pub use assets::AssetManager;
pub mod systems;
pub use systems::{System, SystemRegistry};

View file

@ -0,0 +1,33 @@
use hecs::World;
use crate::{AssetManager, EventBus};
/// A game/engine system that updates every frame.
pub trait System<A> {
/// Update the system for the current frame.
///
/// * `world` mutable ECS world
/// * `assets` read-only resource manager
/// * `events` event bus for publishing/consuming game events
/// * `dt` time delta in seconds
fn update(&mut self, world: &mut World, assets: &AssetManager, events: &mut EventBus<A>, dt: f32);
}
/// Stores and updates a collection of boxed systems.
pub struct SystemRegistry<A> {
systems: Vec<Box<dyn System<A>>>,
}
impl<A> SystemRegistry<A> {
pub fn new() -> Self { Self { systems: Vec::new() } }
pub fn add_system<S: System<A> + 'static>(&mut self, sys: S) {
self.systems.push(Box::new(sys));
}
pub fn update_all(&mut self, world: &mut World, assets: &AssetManager, events: &mut EventBus<A>, dt: f32) {
for s in &mut self.systems {
s.update(world, assets, events, dt);
}
}
}