diff --git a/.gitignore b/.gitignore index 1ed27df02..28a01435a 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/editor/src/lib.rs b/editor/src/lib.rs index 266ae75cb..8f5c91611 100644 --- a/editor/src/lib.rs +++ b/editor/src/lib.rs @@ -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

(&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

(&mut self, plugin: P) diff --git a/fyrox-impl/src/engine/executor.rs b/fyrox-impl/src/engine/executor.rs index 38e660921..435a7f530 100644 --- a/fyrox-impl/src/engine/executor.rs +++ b/fyrox-impl/src/engine/executor.rs @@ -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

(&mut self, plugin: P) + /// Adds new plugin to the executor, the plugin will be enabled only on [`Executor::run`]. + pub fn add_plugin

(&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. diff --git a/fyrox-impl/src/engine/mod.rs b/fyrox-impl/src/engine/mod.rs index 8cc675932..d0890076f 100644 --- a/fyrox-impl/src/engine/mod.rs +++ b/fyrox-impl/src/engine/mod.rs @@ -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 { -/// Box::new(MyGame::new(scene_path, context)) -/// } -/// } -/// /// struct MyGame { /// scene: Handle, /// } @@ -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>, - // A set of plugins used by the engine. plugins: Vec>, @@ -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

(&mut self, constructor: P) + pub fn add_plugin

(&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)); } } diff --git a/fyrox-impl/src/engine/task.rs b/fyrox-impl/src/engine/task.rs index dbe483794..9a49ac7c4 100644 --- a/fyrox-impl/src/engine/task.rs +++ b/fyrox-impl/src/engine/task.rs @@ -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 { - /// Box::new(MyGame::new(context)) - /// } - /// } /// /// struct MyGame { /// data: Option>, diff --git a/fyrox-impl/src/plugin/dynamic.rs b/fyrox-impl/src/plugin/dynamic.rs index c067646e2..c86533849 100644 --- a/fyrox-impl/src/plugin/dynamic.rs +++ b/fyrox-impl/src/plugin/dynamic.rs @@ -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, + /// Loaded plugin. + pub plugin: Box, // Keep the library loaded. // Must be last! #[allow(dead_code)] lib: libloading::Library, } -pub type PluginEntryPoint = fn() -> Box; +type PluginEntryPoint = fn() -> Box; impl DynamicPlugin { + /// Tries to load a plugin from a dynamic library (*.dll on Windows, *.so on Unix). pub fn load

(path: P) -> Result where P: AsRef, @@ -26,7 +31,7 @@ impl DynamicPlugin { .map_err(|e| e.to_string())?; Ok(Self { - constructor: entry(), + plugin: entry(), lib, }) } diff --git a/fyrox-impl/src/plugin/mod.rs b/fyrox-impl/src/plugin/mod.rs index a518476d2..15e939177 100644 --- a/fyrox-impl/src/plugin/mod.rs +++ b/fyrox-impl/src/plugin/mod.rs @@ -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; -} - /// 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) {} diff --git a/fyrox-scripts/src/lib.rs b/fyrox-scripts/src/lib.rs index 4273e7b76..d7af62ea8 100644 --- a/fyrox-scripts/src/lib.rs +++ b/fyrox-scripts/src/lib.rs @@ -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 { -/// # unimplemented!() -/// # } /// # } /// ``` pub fn register(container: &ScriptConstructorContainer) { diff --git a/fyrox-impl/test_output/behavior_save_load.bin b/test_output/behavior_save_load.bin similarity index 100% rename from fyrox-impl/test_output/behavior_save_load.bin rename to test_output/behavior_save_load.bin diff --git a/fyrox-impl/test_output/behavior_save_load.txt b/test_output/behavior_save_load.txt similarity index 100% rename from fyrox-impl/test_output/behavior_save_load.txt rename to test_output/behavior_save_load.txt diff --git a/fyrox-impl/test_output/derived.rgs b/test_output/derived.rgs similarity index 91% rename from fyrox-impl/test_output/derived.rgs rename to test_output/derived.rgs index b9ba0460f..312b03353 100644 Binary files a/fyrox-impl/test_output/derived.rgs and b/test_output/derived.rgs differ diff --git a/fyrox-impl/test_output/derived2.rgs b/test_output/derived2.rgs similarity index 90% rename from fyrox-impl/test_output/derived2.rgs rename to test_output/derived2.rgs index f5af391a2..a50c0e0cd 100644 Binary files a/fyrox-impl/test_output/derived2.rgs and b/test_output/derived2.rgs differ diff --git a/fyrox-impl/test_output/root.rgs b/test_output/root.rgs similarity index 97% rename from fyrox-impl/test_output/root.rgs rename to test_output/root.rgs index 9426ed151..90bb64671 100644 Binary files a/fyrox-impl/test_output/root.rgs and b/test_output/root.rgs differ diff --git a/fyrox-impl/test_output/root2.rgs b/test_output/root2.rgs similarity index 97% rename from fyrox-impl/test_output/root2.rgs rename to test_output/root2.rgs index 666ef8e74..24740b57b 100644 Binary files a/fyrox-impl/test_output/root2.rgs and b/test_output/root2.rgs differ