游戏引擎插件系统实现优化求助:现有代码简化方案探讨
Github仓库
插件系统大致工作机制说明
Plugin trait实现了build()方法,该方法会在插件加载时被调用。build()方法接收App结构体,App即应用程序核心结构。
目前我的代码实现较为繁琐,现咨询是否存在其他更优的实现方案?
pub trait Component { fn start(&mut self); fn update(&mut self); } pub struct App { runners: Vec<Box<dyn Fn(&mut App)>>, components: Vec<Box<dyn Component>>, }
&mut App方案
最初,build()方法接收&mut App参数,但无法实现如下代码:
impl Plugin for WinitWSIPlugin { fn build(&self, app: &mut App) { app.set_runner(move || { // 此处报错 app.open_window(...); }); } }
据我理解,编译器不允许此操作的原因是传递的App结构体引用可能会失效。
Rc<RefCell<App>>方案
后续实现中,我改为传递Rc<RefCell<App>>,但调用borrow_mut()以执行open_window(...)时出现panic,尽管我此前并未手动调用过borrow_mut()。
impl Plugin for WinitWSIPlugin { fn build(&self, app: Rc<RefCell<App>>) { app.clone().borrow().set_runner(move || { let AppSystem::Windowed { info } = app.borrow().system(); let mut winit_windows = WinitWindows::default(); let event_loop = winit::event_loop::EventLoop::new(); /*===== 此处触发panic =====*/ app.borrow_mut().open_window(winit_windows.create_window( &event_loop, app.borrow().id(), &info, )); }); } }
当前采用的最终版本
在App结构体中供插件使用的字段上使用Mutex,这样即使需要修改值也无需调用borrow_mut(),只需调用borrow()即可。
impl Plugin for WinitWSIPlugin { fn build(&self, app: Rc<RefCell<App>>) { app.clone().borrow().set_runner(move || { let AppSystem::Windowed { info } = app.borrow().system(); let mut winit_windows = WinitWindows::default(); let event_loop = winit::event_loop::EventLoop::new(); app.borrow().open_window(winit_windows.create_window( &event_loop, app.borrow().id(), &info, )); for component in app.borrow().components().borrow_mut().iter_mut() { component.init(app.clone()); } let app = app.clone(); event_loop.run(move |event, _, control_flow| { control_flow.set_wait(); for component in app.borrow().components().borrow_mut().iter_mut() { component.update(app.clone()); } match event { winit::event::Event::WindowEvent { window_id: _, event, } => match event { winit::event::WindowEvent::CloseRequested => control_flow.set_exit(), _ => (), }, _ => (), } }); }); } }
内容的提问来源于stack exchange,提问作者Dmitry Klementiev
相关产品推荐
相关产品推荐

