Skip to content

Commit

Permalink
editor plugins container
Browse files Browse the repository at this point in the history
- adds some useful methods for plugins search
  • Loading branch information
mrDIMAS committed Oct 29, 2024
1 parent fd182e5 commit bdd00fc
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 13 deletions.
18 changes: 9 additions & 9 deletions editor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ use std::{
time::{Duration, Instant},
};

use crate::plugin::EditorPluginsContainer;
use crate::plugins::tilemap::TileMapEditorPlugin;
pub use message::Message;

Expand Down Expand Up @@ -523,7 +524,7 @@ pub struct Editor {
pub docking_manager: Handle<UiNode>,
pub node_removal_dialog: NodeRemovalDialog,
pub engine: Engine,
pub plugins: Vec<Option<Box<dyn EditorPlugin>>>,
pub plugins: EditorPluginsContainer,
pub focused: bool,
pub update_loop_state: UpdateLoopState,
pub is_suspended: bool,
Expand Down Expand Up @@ -856,10 +857,9 @@ impl Editor {
audio_preview_panel,
node_removal_dialog,
doc_window,
plugins: vec![
Some(Box::new(ColliderShapePlugin::default())),
Some(Box::new(TileMapEditorPlugin::default())),
],
plugins: EditorPluginsContainer::new()
.with(ColliderShapePlugin::default())
.with(TileMapEditorPlugin::default()),
// Apparently, some window managers (like Wayland), does not send `Focused` event after the window
// was created. So we must assume that the editor is focused by default, otherwise editor's thread
// will sleep forever and the window won't come up.
Expand Down Expand Up @@ -1827,11 +1827,11 @@ impl Editor {
pub fn is_in_preview_mode(&mut self) -> bool {
let mut is_any_plugin_in_preview_mode = false;
let mut i = 0;
while i < self.plugins.len() {
if let Some(plugin) = self.plugins.get_mut(i).and_then(|p| p.take()) {
while i < self.plugins.0.len() {
if let Some(plugin) = self.plugins.0.get_mut(i).and_then(|p| p.take()) {
is_any_plugin_in_preview_mode |= plugin.is_in_preview_mode(self);

if let Some(entry) = self.plugins.get_mut(i) {
if let Some(entry) = self.plugins.0.get_mut(i) {
*entry = Some(plugin);
}
}
Expand Down Expand Up @@ -2680,7 +2680,7 @@ impl Editor {
where
P: EditorPlugin + 'static,
{
self.plugins.push(Some(Box::new(plugin)));
self.plugins.add(plugin);
}

pub fn is_active(&self) -> bool {
Expand Down
64 changes: 60 additions & 4 deletions editor/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@

use crate::fyrox::gui::message::UiMessage;
use crate::{Editor, Message};
use std::any::Any;

pub trait BaseEditorPlugin: Any {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}

impl<T: EditorPlugin> BaseEditorPlugin for T {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}

/// Editor plugin allows you to extend editor functionality with custom tools. It provides a standard way of interaction
/// between your plugin and built-in editor's functionality.
Expand All @@ -40,7 +55,7 @@ use crate::{Editor, Message};
/// The editor usually operates on scenes (there could be multiple opened scenes, but only one active) and any modification of
/// their content **must** be done via _commands_. [Command](https://en.wikipedia.org/wiki/Command_pattern) is a standard
/// pattern that encapsulates an action. Command pattern is used for undo/redo functionality.
pub trait EditorPlugin {
pub trait EditorPlugin: BaseEditorPlugin {
/// This method is called right after the editor was fully initialized. It is guaranteed to be called only once.
fn on_start(&mut self, #[allow(unused_variables)] editor: &mut Editor) {}

Expand Down Expand Up @@ -111,11 +126,11 @@ pub trait EditorPlugin {
macro_rules! for_each_plugin {
($container:expr => $func:ident($($param:expr),*)) => {{
let mut i = 0;
while i < $container.len() {
if let Some(mut plugin) = $container.get_mut(i).and_then(|p| p.take()) {
while i < $container.0.len() {
if let Some(mut plugin) = $container.0.get_mut(i).and_then(|p| p.take()) {
plugin.$func($($param),*);

if let Some(entry) = $container.get_mut(i) {
if let Some(entry) = $container.0.get_mut(i) {
*entry = Some(plugin);
}
}
Expand All @@ -124,3 +139,44 @@ macro_rules! for_each_plugin {
}
}};
}

#[derive(Default)]
pub struct EditorPluginsContainer(pub Vec<Option<Box<dyn EditorPlugin>>>);

impl EditorPluginsContainer {
pub fn new() -> Self {
Default::default()
}

pub fn with<T: EditorPlugin>(mut self, plugin: T) -> Self {
self.0.push(Some(Box::new(plugin)));
self
}

pub fn add<T: EditorPlugin>(&mut self, plugin: T) -> &mut Self {
self.0.push(Some(Box::new(plugin)));
self
}

pub fn get<T>(&self) -> Option<&T>
where
T: EditorPlugin,
{
self.0.iter().find_map(|container| {
container
.as_ref()
.and_then(|plugin| plugin.as_any().downcast_ref::<T>())
})
}

pub fn get_mut<T>(&mut self) -> Option<&mut T>
where
T: EditorPlugin,
{
self.0.iter_mut().find_map(|container| {
container
.as_mut()
.and_then(|plugin| plugin.as_any_mut().downcast_mut::<T>())
})
}
}

0 comments on commit bdd00fc

Please sign in to comment.