rewin123 / space_editor

bevy prefab editor
MIT License
387 stars 49 forks source link

Automatically Register Bevy Events #159

Open ncomendant opened 10 months ago

ncomendant commented 10 months ago

Once issue #158 is resolved, SpaceEditorPlugin should register all of Bevy's events using App::editor_registry_event(). This is similar to how it is done for components.

naomijub commented 10 months ago

This can be an issue due to dependency on Resource.

Dependency on Resource is due to the fact that we need a way to store the event so we can manage it

ncomendant commented 10 months ago

I made some progress by wrapping the events into structs that implemented the needed traits. Other changes regarding registration were made, but here's an example for bevy::input::gamepad::GamepadEvent:

use std::any::TypeId;

use bevy::{
    input::gamepad::{GamepadConnection, GamepadConnectionEvent, GamepadEvent},
    prelude::*,
    reflect::GetTypeRegistration,
};

use crate::prelude::EditorRegistryBevyExt;

pub(crate) trait BevyEvent:
    Event + Default + Resource + Reflect + Send + Clone + 'static + GetTypeRegistration
{
    type T: Event + Clone;

    fn inner_event(&self) -> &Self::T;

    fn inner_path() -> String {
        std::any::type_name::<Self::T>().to_string()
    }

    fn inner_type_id() -> TypeId {
        TypeId::of::<Self::T>()
    }
}

#[derive(Event, Resource, Reflect, Clone)]
pub(crate) struct WrappedGamepadEvent(GamepadEvent);

impl Default for WrappedGamepadEvent {
    fn default() -> Self {
        Self(GamepadEvent::Connection(GamepadConnectionEvent {
            gamepad: Gamepad::new(0),
            connection: GamepadConnection::Disconnected,
        }))
    }
}

impl BevyEvent for WrappedGamepadEvent {
    type T = GamepadEvent;

    fn inner_event(&self) -> &Self::T {
        &self.0
    }
}

pub(crate) fn register_events(app: &mut App) -> &mut App {
    app.editor_registry_bevy_event::<WrappedGamepadEvent>()
        .register_type::<GamepadEvent>()
        .register_type::<GamepadConnectionEvent>()
}

And I was able to get this (with working dispatch!): image image

However, I'm struggling to change some of the values: image

naomijub commented 10 months ago

However, I'm struggling to change some of the values:

I think you might need to wrap the subtypes as well or this type depends on something else that is not available (like GamepadButtonChangedEvent)

naomijub commented 10 months ago

This is the way I thought about doing it as well and how we did with XPBD

ncomendant commented 10 months ago

You're probably right. I have this right now:

pub(crate) fn register_events(app: &mut App) -> &mut App {
    app.editor_registry_bevy_event::<WrappedGamepadEvent>()
        .register_type::<GamepadEvent>()
        .register_type::<GamepadConnection>()
        .register_type::<GamepadConnectionEvent>()
        .register_type::<GamepadButtonChangedEvent>()
        .register_type::<GamepadAxisChangedEvent>()
        .register_type::<GamepadInfo>()
}

But still no luck. I'll come back to this later.

ncomendant commented 10 months ago

Seems like all the subtypes need #[reflect(Default)] to work properly. Wrapping everything to accomplish this would be a very brittle solution. I also need a better understanding of how bevy_reflect works. I'll keep thinking about it, but it's best to unassign myself for now.

naomijub commented 10 months ago

Agreed to the brittleness, but that is the way I also thought about it. Sadly, every new bevy update would mean A LOT OF CHANGES

naomijub commented 10 months ago

@ncomendant can you merge your current work into this branch?

issue-159