refactored plugin structure

- removed PluginConstructor
This commit is contained in:
Dmitry Stepanov
2024-03-17 11:45:14 +03:00
parent 14044764a3
commit bd5cc70032
14 changed files with 46 additions and 90 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
/fyrox-core/test.txt
/fyrox-resource/test.txt
/fyrox-core-derive/test_output
/test_output
/fyrox-impl/test_output
history.bin
settings.ron
+3 -3
View File
@@ -88,7 +88,6 @@ use crate::fyrox::{
shader::{ShaderResource, ShaderResourceExtension},
Material, MaterialResource, PropertyValue,
},
plugin::PluginConstructor,
resource::texture::{
CompressionOptions, TextureImportOptions, TextureKind, TextureMinificationFilter,
TextureResource, TextureResourceExtension,
@@ -144,6 +143,7 @@ use crate::{
utils::{doc::DocWindow, path_fixer::PathFixer, ragdoll::RagdollWizard},
world::{graph::menu::SceneNodeContextMenu, graph::EditorSceneWrapper, WorldViewer},
};
use fyrox::plugin::Plugin;
use std::{
cell::RefCell,
io::{BufRead, BufReader},
@@ -2456,9 +2456,9 @@ impl Editor {
pub fn add_game_plugin<P>(&mut self, plugin: P)
where
P: PluginConstructor + 'static,
P: Plugin + 'static,
{
self.engine.add_plugin_constructor(plugin)
self.engine.add_plugin(plugin)
}
pub fn add_editor_plugin<P>(&mut self, plugin: P)
+5 -5
View File
@@ -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.
+9 -25
View File
@@ -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));
}
}
+1 -13
View File
@@ -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>>,
+9 -4
View File
@@ -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,
})
}
+15 -29
View File
@@ -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) {}
+3 -10
View File
@@ -11,24 +11,17 @@ pub mod camera;
/// ```rust
/// # use fyrox::{
/// # core::pool::Handle,
/// # plugin::{Plugin, PluginConstructor, PluginContext, PluginRegistrationContext},
/// # plugin::{Plugin, PluginContext, PluginRegistrationContext},
/// # scene::Scene,
/// # };
/// #
/// # struct GameConstructor;
/// # struct Game;
/// #
/// # impl PluginConstructor for GameConstructor {
/// # impl Plugin for Game {
/// // This is PluginConstructor::register method of your GameConstructor.
/// fn register(&self, context: PluginRegistrationContext) {
/// fyrox_scripts::register(&context.serialization_context.script_constructors)
/// }
/// # fn create_instance(
/// # &self,
/// # _scene_path: Option<&str>,
/// # _context: PluginContext,
/// # ) -> Box<dyn Plugin> {
/// # unimplemented!()
/// # }
/// # }
/// ```
pub fn register(container: &ScriptConstructorContainer) {