mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
refactored plugin structure
- removed PluginConstructor
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
//! Executor is a small wrapper that manages plugins and scripts for your game.
|
||||
|
||||
use crate::plugin::Plugin;
|
||||
use crate::{
|
||||
asset::manager::ResourceManager,
|
||||
core::{
|
||||
@@ -11,7 +12,6 @@ use crate::{
|
||||
},
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
|
||||
plugin::PluginConstructor,
|
||||
utils::translate_event,
|
||||
window::WindowAttributes,
|
||||
};
|
||||
@@ -124,12 +124,12 @@ impl Executor {
|
||||
self.desired_update_rate
|
||||
}
|
||||
|
||||
/// Adds new plugin constructor to the executor, the plugin will be enabled only on [`Executor::run`].
|
||||
pub fn add_plugin_constructor<P>(&mut self, plugin: P)
|
||||
/// Adds new plugin to the executor, the plugin will be enabled only on [`Executor::run`].
|
||||
pub fn add_plugin<P>(&mut self, plugin: P)
|
||||
where
|
||||
P: PluginConstructor + 'static,
|
||||
P: Plugin + 'static,
|
||||
{
|
||||
self.engine.add_plugin_constructor(plugin)
|
||||
self.engine.add_plugin(plugin)
|
||||
}
|
||||
|
||||
/// Runs the executor - starts your game.
|
||||
|
||||
@@ -31,7 +31,7 @@ use crate::{
|
||||
shader::{loader::ShaderLoader, Shader, ShaderResource, ShaderResourceExtension},
|
||||
Material,
|
||||
},
|
||||
plugin::{Plugin, PluginConstructor, PluginContext, PluginRegistrationContext},
|
||||
plugin::{Plugin, PluginContext, PluginRegistrationContext},
|
||||
renderer::{framework::error::FrameworkError, framework::state::GlKind, Renderer},
|
||||
resource::{
|
||||
curve::{loader::CurveLoader, CurveResourceState},
|
||||
@@ -218,23 +218,11 @@ struct SceneLoadingOptions {
|
||||
/// ```rust
|
||||
/// use fyrox_impl::{
|
||||
/// core::{color::Color, log::Log, pool::Handle},
|
||||
/// plugin::{Plugin, PluginConstructor, PluginContext},
|
||||
/// plugin::{Plugin, PluginContext},
|
||||
/// scene::Scene,
|
||||
/// };
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// struct GameConstructor;
|
||||
///
|
||||
/// impl PluginConstructor for GameConstructor {
|
||||
/// fn create_instance(
|
||||
/// &self,
|
||||
/// scene_path: Option<&str>,
|
||||
/// context: PluginContext,
|
||||
/// ) -> Box<dyn Plugin> {
|
||||
/// Box::new(MyGame::new(scene_path, context))
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// struct MyGame {
|
||||
/// scene: Handle<Scene>,
|
||||
/// }
|
||||
@@ -433,9 +421,6 @@ pub struct Engine {
|
||||
#[allow(dead_code)] // Keep engine instance alive.
|
||||
sound_engine: SoundEngine,
|
||||
|
||||
// A set of plugin constructors.
|
||||
plugin_constructors: Vec<Box<dyn PluginConstructor>>,
|
||||
|
||||
// A set of plugins used by the engine.
|
||||
plugins: Vec<Box<dyn Plugin>>,
|
||||
|
||||
@@ -1288,7 +1273,6 @@ impl Engine {
|
||||
serialization_context,
|
||||
script_processor: Default::default(),
|
||||
plugins_enabled: false,
|
||||
plugin_constructors: Default::default(),
|
||||
elapsed_time: 0.0,
|
||||
task_pool: TaskPoolHandler::new(task_pool),
|
||||
})
|
||||
@@ -2266,8 +2250,8 @@ impl Engine {
|
||||
|
||||
if self.plugins_enabled {
|
||||
// Create and initialize instances.
|
||||
for constructor in self.plugin_constructors.iter() {
|
||||
self.plugins.push(constructor.create_instance(
|
||||
for plugin in self.plugins.iter_mut() {
|
||||
plugin.init(
|
||||
scene_path,
|
||||
PluginContext {
|
||||
scenes: &mut self.scenes,
|
||||
@@ -2284,7 +2268,7 @@ impl Engine {
|
||||
window_target,
|
||||
task_pool: &mut self.task_pool,
|
||||
},
|
||||
));
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.handle_scripts(0.0);
|
||||
@@ -2312,16 +2296,16 @@ impl Engine {
|
||||
}
|
||||
|
||||
/// Adds new plugin plugin constructor.
|
||||
pub fn add_plugin_constructor<P>(&mut self, constructor: P)
|
||||
pub fn add_plugin<P>(&mut self, plugin: P)
|
||||
where
|
||||
P: PluginConstructor + 'static,
|
||||
P: Plugin + 'static,
|
||||
{
|
||||
constructor.register(PluginRegistrationContext {
|
||||
plugin.register(PluginRegistrationContext {
|
||||
serialization_context: &self.serialization_context,
|
||||
resource_manager: &self.resource_manager,
|
||||
});
|
||||
|
||||
self.plugin_constructors.push(Box::new(constructor));
|
||||
self.plugins.push(Box::new(plugin));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,20 +76,8 @@ impl TaskPoolHandler {
|
||||
/// ## Example
|
||||
///
|
||||
/// ```rust ,no_run
|
||||
/// # use fyrox_impl::plugin::{Plugin, PluginConstructor, PluginContext};
|
||||
/// # use fyrox_impl::plugin::{Plugin, PluginContext};
|
||||
/// # use std::{fs::File, io::Read};
|
||||
/// #
|
||||
/// struct MyGameConstructor;
|
||||
///
|
||||
/// impl PluginConstructor for MyGameConstructor {
|
||||
/// fn create_instance(
|
||||
/// &self,
|
||||
/// _scene_path: Option<&str>,
|
||||
/// context: PluginContext,
|
||||
/// ) -> Box<dyn Plugin> {
|
||||
/// Box::new(MyGame::new(context))
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// struct MyGame {
|
||||
/// data: Option<Vec<u8>>,
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
//! Dynamic plugins with hot-reloading ability.
|
||||
|
||||
use crate::plugin::PluginConstructor;
|
||||
use crate::plugin::Plugin;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
/// Dynamic plugin, that is loaded from a dynamic library. Usually it is used for hot reloading,
|
||||
/// it is strongly advised not to use it in production builds, because it is slower than statically
|
||||
/// linked plugins and it could be unsafe if different compiler versions are used.
|
||||
pub struct DynamicPlugin {
|
||||
pub constructor: Box<dyn PluginConstructor>,
|
||||
/// Loaded plugin.
|
||||
pub plugin: Box<dyn Plugin>,
|
||||
// Keep the library loaded.
|
||||
// Must be last!
|
||||
#[allow(dead_code)]
|
||||
lib: libloading::Library,
|
||||
}
|
||||
|
||||
pub type PluginEntryPoint = fn() -> Box<dyn PluginConstructor>;
|
||||
type PluginEntryPoint = fn() -> Box<dyn Plugin>;
|
||||
|
||||
impl DynamicPlugin {
|
||||
/// Tries to load a plugin from a dynamic library (*.dll on Windows, *.so on Unix).
|
||||
pub fn load<P>(path: P) -> Result<Self, String>
|
||||
where
|
||||
P: AsRef<OsStr>,
|
||||
@@ -26,7 +31,7 @@ impl DynamicPlugin {
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
Ok(Self {
|
||||
constructor: entry(),
|
||||
plugin: entry(),
|
||||
lib,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,46 +4,20 @@
|
||||
|
||||
pub mod dynamic;
|
||||
|
||||
use crate::engine::task::TaskPoolHandler;
|
||||
use crate::{
|
||||
asset::manager::ResourceManager,
|
||||
core::pool::Handle,
|
||||
core::{pool::Handle, visitor::VisitError},
|
||||
engine::{
|
||||
AsyncSceneLoader, GraphicsContext, PerformanceStatistics, ScriptProcessor,
|
||||
SerializationContext,
|
||||
task::TaskPoolHandler, AsyncSceneLoader, GraphicsContext, PerformanceStatistics,
|
||||
ScriptProcessor, SerializationContext,
|
||||
},
|
||||
event::Event,
|
||||
gui::{message::UiMessage, UserInterface},
|
||||
scene::{Scene, SceneContainer},
|
||||
};
|
||||
use fyrox_core::visitor::VisitError;
|
||||
use std::{any::Any, path::Path, sync::Arc};
|
||||
use winit::event_loop::EventLoopWindowTarget;
|
||||
|
||||
/// Plugin constructor is a first step of 2-stage plugin initialization. It is responsible for plugin script
|
||||
/// registration and for creating actual plugin instance.
|
||||
///
|
||||
/// # Details
|
||||
///
|
||||
/// Why there is a need in 2-state initialization? The editor requires it, it is interested only in plugin
|
||||
/// scripts so editor does not create any plugin instances, it just uses [Self::register] to obtain information
|
||||
/// about scripts.
|
||||
pub trait PluginConstructor {
|
||||
/// The method is called when the plugin constructor was just registered in the engine. The main use of the
|
||||
/// method is to register scripts and custom scene graph nodes in [`SerializationContext`].
|
||||
fn register(&self, #[allow(unused_variables)] context: PluginRegistrationContext) {}
|
||||
|
||||
/// The method is called when the engine creates plugin instances. It allows to create initialized plugin
|
||||
/// instance.
|
||||
///
|
||||
/// ## Arguments
|
||||
///
|
||||
/// `scene_path` argument tells you that there's already a scene specified. It is used primarily
|
||||
/// by the editor, to run your game with a scene you have current opened in the editor. Typical
|
||||
/// usage would be: `scene_path.unwrap_or("a/path/to/my/default/scene.rgs")`
|
||||
fn create_instance(&self, scene_path: Option<&str>, context: PluginContext) -> Box<dyn Plugin>;
|
||||
}
|
||||
|
||||
/// Contains plugin environment for the registration stage.
|
||||
pub struct PluginRegistrationContext<'a> {
|
||||
/// A reference to serialization context of the engine. See [`SerializationContext`] for more
|
||||
@@ -191,6 +165,18 @@ impl dyn Plugin {
|
||||
/// }
|
||||
/// ```
|
||||
pub trait Plugin: BasePlugin {
|
||||
/// The method is called when the plugin constructor was just registered in the engine. The main
|
||||
/// use of this method is to register scripts and custom scene graph nodes in [`SerializationContext`].
|
||||
fn register(&self, #[allow(unused_variables)] context: PluginRegistrationContext) {}
|
||||
|
||||
/// This method is used to initialize your plugin.
|
||||
fn init(
|
||||
&mut self,
|
||||
#[allow(unused_variables)] scene_path: Option<&str>,
|
||||
#[allow(unused_variables)] context: PluginContext,
|
||||
) {
|
||||
}
|
||||
|
||||
/// The method is called before plugin will be disabled. It should be used for clean up, or some
|
||||
/// additional actions.
|
||||
fn on_deinit(&mut self, #[allow(unused_variables)] context: PluginContext) {}
|
||||
|
||||
Binary file not shown.
@@ -1,55 +0,0 @@
|
||||
__ROOT__[Fields=0, Children=1]:
|
||||
Tree[Fields=0, Children=2]:
|
||||
Nodes[Fields=0, Children=2]:
|
||||
Records[Fields=1, Children=6]: Length<u32 = 6>,
|
||||
Item0[Fields=0, Children=1]:
|
||||
ItemData[Fields=1, Children=1]: Generation<u32 = 1>,
|
||||
Payload[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=1]: Id<u32 = 1>,
|
||||
0[Fields=0, Children=1]:
|
||||
Child[Fields=2, Children=0]: Index<u32 = 5>, Generation<u32 = 1>,
|
||||
Item1[Fields=0, Children=1]:
|
||||
ItemData[Fields=1, Children=1]: Generation<u32 = 1>,
|
||||
Payload[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=1]: Id<u32 = 3>,
|
||||
0[Fields=0, Children=1]:
|
||||
Behavior[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=0]: Id<u32 = 1>,
|
||||
Item2[Fields=0, Children=1]:
|
||||
ItemData[Fields=1, Children=1]: Generation<u32 = 1>,
|
||||
Payload[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=1]: Id<u32 = 3>,
|
||||
0[Fields=0, Children=1]:
|
||||
Behavior[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=0]: Id<u32 = 2>,
|
||||
Item3[Fields=0, Children=1]:
|
||||
ItemData[Fields=1, Children=1]: Generation<u32 = 1>,
|
||||
Payload[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=1]: Id<u32 = 3>,
|
||||
0[Fields=0, Children=1]:
|
||||
Behavior[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=0]: Id<u32 = 3>,
|
||||
Item4[Fields=0, Children=1]:
|
||||
ItemData[Fields=1, Children=1]: Generation<u32 = 1>,
|
||||
Payload[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=1]: Id<u32 = 3>,
|
||||
0[Fields=0, Children=1]:
|
||||
Behavior[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=0]: Id<u32 = 4>,
|
||||
Item5[Fields=0, Children=1]:
|
||||
ItemData[Fields=1, Children=1]: Generation<u32 = 1>,
|
||||
Payload[Fields=1, Children=1]: IsSome<u8 = 1>,
|
||||
Data[Fields=1, Children=1]: Id<u32 = 2>,
|
||||
0[Fields=0, Children=2]:
|
||||
Children[Fields=1, Children=4]: Length<u32 = 4>,
|
||||
Item0[Fields=0, Children=1]:
|
||||
ItemData[Fields=2, Children=0]: Index<u32 = 1>, Generation<u32 = 1>,
|
||||
Item1[Fields=0, Children=1]:
|
||||
ItemData[Fields=2, Children=0]: Index<u32 = 2>, Generation<u32 = 1>,
|
||||
Item2[Fields=0, Children=1]:
|
||||
ItemData[Fields=2, Children=0]: Index<u32 = 3>, Generation<u32 = 1>,
|
||||
Item3[Fields=0, Children=1]:
|
||||
ItemData[Fields=2, Children=0]: Index<u32 = 4>, Generation<u32 = 1>,
|
||||
Kind[Fields=1, Children=0]: Id<u32 = 0>,
|
||||
FreeStack[Fields=1, Children=0]: Length<u32 = 0>,
|
||||
Root[Fields=2, Children=0]: Index<u32 = 0>, Generation<u32 = 1>,
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user