Successfull export/clear/importgit add .; git commit Tadagit add .; git commit

main
Elijah Voigt 2 years ago
parent 5952ee5608
commit 0e643965f4

736
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -39,6 +39,10 @@ path = "bin/editor.rs"
name = "chars" name = "chars"
path = "bin/chars.rs" path = "bin/chars.rs"
[[bin]]
name = "serialize-wtf"
path = "bin/serialize-wtf.rs"
[dependencies] [dependencies]
bevy = "0.11" bevy = "0.11"

@ -0,0 +1,108 @@
(
resources: {},
entities: {
4: (
components: {
"bevy_transform::components::transform::Transform": (
translation: (
x: 0.0,
y: 0.0,
z: 0.0,
),
rotation: (0.0, 0.0, 0.0, 1.0),
scale: (
x: 1.0,
y: 1.0,
z: 1.0,
),
),
"bevy_transform::components::global_transform::GlobalTransform": ((
matrix3: (
x_axis: (
x: 1.0,
y: 0.0,
z: 0.0,
),
y_axis: (
x: 0.0,
y: 1.0,
z: 0.0,
),
z_axis: (
x: 0.0,
y: 0.0,
z: 1.0,
),
),
translation: (
x: 0.0,
y: 0.0,
z: 0.0,
),
)),
"bevy_render::view::visibility::Visibility": Inherited,
"bevy_hierarchy::components::children::Children": ([
5,
6,
]),
},
),
5: (
components: {
"bevy_hierarchy::components::parent::Parent": (4),
"bevy_asset::handle::Handle<bevy_audio::audio_source::AudioSource>": (
id: AssetPathId(((5718828327369153735), (8823233378563626002))),
),
},
),
6: (
components: {
"bevy_transform::components::transform::Transform": (
translation: (
x: 0.0,
y: 0.0,
z: 0.0,
),
rotation: (0.0, 0.0, 0.0, 1.0),
scale: (
x: 1.0,
y: 1.0,
z: 1.0,
),
),
"bevy_transform::components::global_transform::GlobalTransform": ((
matrix3: (
x_axis: (
x: 1.0,
y: 0.0,
z: 0.0,
),
y_axis: (
x: 0.0,
y: 1.0,
z: 0.0,
),
z_axis: (
x: 0.0,
y: 0.0,
z: 1.0,
),
),
translation: (
x: 0.0,
y: 0.0,
z: 0.0,
),
)),
"bevy_render::view::visibility::Visibility": Inherited,
"bevy_hierarchy::components::parent::Parent": (4),
"bevy_hierarchy::components::children::Children": ([
16,
]),
"bevy_asset::handle::Handle<bevy_scene::scene::Scene>": (
id: AssetPathId(((8329447081204006281), (13531267934229906755))),
),
},
),
},
)

@ -3,19 +3,14 @@
// Editor for creating Monologue Trees levels // Editor for creating Monologue Trees levels
// //
// BUGS: // BUGS:
// * Not loading scenes with Active refactor
// * Not pause animations with Active refactor
// * Camera order ambiguity
// * Load new GLTF -> Despawn all level entities
// //
// TODO: // TODO:
// * Disable auto start/load
// * (hard) Harden Active Camera
// * (medium) Select Font -> "Default Font" Resource // * (medium) Select Font -> "Default Font" Resource
// * (medium) Pre-compute animation target entities // * (medium) Pre-compute animation target entities
// * Better handle hide/close monologue // * (hard) Harden Active Camera
// * (brutal) export level // * (brutal) export level
// * (hard) import level // * (hard) import level
// * (???) Better handle hide/close monologue
use bevy::{ use bevy::{
asset::{Asset, AssetLoader, Assets, ChangeWatcher, LoadContext, LoadedAsset}, asset::{Asset, AssetLoader, Assets, ChangeWatcher, LoadContext, LoadedAsset},
@ -56,7 +51,9 @@ fn main() {
..default() ..default()
}), }),
DebugInfoPlugin, DebugInfoPlugin,
ui::GameUiPlugin, ui::GameUiPlugin {
enable_alerts: true,
},
)) ))
.init_resource::<AssetRegistry>() .init_resource::<AssetRegistry>()
.add_asset::<Monologue>() .add_asset::<Monologue>()
@ -680,7 +677,6 @@ mod gltf {
} }
} }
// TODO: Mark loaded animation as active
use scenes::*; use scenes::*;
mod scenes { mod scenes {
use super::*; use super::*;
@ -774,8 +770,6 @@ mod scenes {
} }
} }
// TODO: Play all animations
// TODO: Mark playing animation as active
use animations::*; use animations::*;
mod animations { mod animations {
use super::*; use super::*;

@ -0,0 +1,297 @@
use std::{fs::File, io::Write};
use bevy::{audio::PlaybackMode, prelude::*, tasks::IoTaskPool};
use monologue_trees::{debug::*, ui};
fn main() {
App::new()
.init_resource::<AssetRegistry>()
.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
title: "Serialization WTF".into(),
resolution: (640., 480.).into(),
..default()
}),
..default()
}),
DebugInfoPlugin,
ui::GameUiPlugin { ..default() },
))
.add_systems(Startup, init)
.add_systems(
Update,
(
export.run_if(interaction_condition::<ExportAction>),
clear.run_if(interaction_condition::<ClearAction>),
import.run_if(interaction_condition::<ImportAction>),
rehydrate::<Visibility, ComputedVisibility>,
rehydrate::<Handle<AudioSource>, PlaybackSettings>,
inspect.run_if(interaction_condition::<InspectAction>),
fallback_camera.run_if(fallback_camera_condition),
),
)
.run();
}
#[derive(Debug, Component, Reflect, Default)]
#[reflect(Component)]
struct LevelRoot;
#[derive(Debug, Component)]
struct ExportAction;
#[derive(Debug, Component)]
struct ClearAction;
#[derive(Debug, Component)]
struct ImportAction;
#[derive(Debug, Component)]
struct InspectAction;
#[derive(Debug, Resource, Default)]
struct AssetRegistry {
handles: Vec<HandleUntyped>,
}
fn init(server: Res<AssetServer>, mut commands: Commands, mut registry: ResMut<AssetRegistry>) {
commands.spawn((
Camera2dBundle { ..default() },
UiCameraConfig { show_ui: true },
));
let audio_handle: Handle<AudioSource> = server.load("audio/Ambient/Lake Sound 1.ogg");
let scene_handle: Handle<Scene> = server.load("models/materials.glb#Scene0");
commands
.spawn((SpatialBundle { ..default() }, LevelRoot))
.with_children(|parent| {
parent.spawn(AudioSourceBundle {
source: audio_handle.clone(),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: false,
..default()
},
});
parent.spawn((SceneBundle {
scene: scene_handle.clone(),
..default()
},));
});
registry.handles.push(audio_handle.clone_untyped());
registry.handles.push(scene_handle.clone_untyped());
commands
.spawn((
NodeBundle {
style: Style {
top: Val::Px(0.0),
right: Val::Px(0.0),
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
position_type: PositionType::Absolute,
..default()
},
background_color: Color::WHITE.into(),
border_color: Color::BLACK.into(),
..default()
},
ui::Select::Action,
))
.with_children(|parent| {
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Export".into(),
..default()
},
ExportAction,
));
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Clear".into(),
..default()
},
ClearAction,
));
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Import".into(),
..default()
},
ImportAction,
));
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Inspect".into(),
..default()
},
InspectAction,
));
});
}
fn interaction_condition<T: Component>(
events: Query<&Interaction, (Changed<Interaction>, With<T>)>,
) -> bool {
events
.iter()
.find(|&interaction| *interaction == Interaction::Pressed)
.is_some()
}
fn rehydrate<W: Component, WO: Component + Default + std::fmt::Debug>(
events: Query<Entity, (Added<W>, Without<WO>)>,
mut commands: Commands,
) {
events.iter().for_each(|entity| {
info!("Rehydrating {:?}", WO::default());
commands.entity(entity).insert(WO::default());
});
}
fn ser(
root: &Query<Entity, With<LevelRoot>>,
children: &Query<&Children>,
world: &World,
) -> String {
let app_type_registry = world.resource::<AppTypeRegistry>().clone();
let mut builder = DynamicSceneBuilder::from_world(world.clone());
builder.deny_all_resources();
// builder.allow_all();
builder.deny::<ComputedVisibility>();
// Level administrivia
builder.allow::<LevelRoot>();
// Scene components
builder.allow::<Handle<Scene>>();
builder.allow::<Visibility>();
builder.allow::<Transform>();
builder.allow::<GlobalTransform>();
// Audio components
builder.allow::<Handle<AudioSource>>();
builder.allow::<PlaybackSettings>();
root.iter().for_each(|r| {
// Extract the level root
builder.extract_entity(r);
// Extract all level root children
builder.extract_entities(
children
.get(r)
.expect("Root has children")
.iter()
.map(|&entity| entity),
);
});
let scene = builder.build();
scene
.serialize_ron(&app_type_registry)
.expect("Serialize scene")
}
fn export(root: Query<Entity, With<LevelRoot>>, children: Query<&Children>, world: &World) {
info!("Export level");
let serialized = ser(&root, &children, world);
IoTaskPool::get()
.spawn(async move {
// Write the scene RON data to file
File::create(format!("assets/output.scn.ron"))
.and_then(|mut file| file.write(serialized.as_bytes()))
.expect("Error while writing scene to file");
})
.detach();
}
fn inspect(root: Query<Entity, With<LevelRoot>>, children: Query<&Children>, world: &World) {
info!("Inexpect level");
let serialized = ser(&root, &children, world);
print!("{}", serialized);
}
fn clear(root: Query<Entity, With<LevelRoot>>, mut commands: Commands) {
info!("Clearing level");
root.iter().for_each(|entity| {
commands.entity(entity).despawn_recursive();
});
}
fn import(mut commands: Commands, server: Res<AssetServer>) {
info!("Importing level");
let scene_handle: Handle<DynamicScene> = server.load("output.scn.ron");
commands.spawn((
LevelRoot,
DynamicSceneBundle {
scene: scene_handle.clone(),
..default()
},
));
}
fn fallback_camera_condition(
added: Query<Entity, Added<Camera>>,
mut removed: RemovedComponents<Camera>,
) -> bool {
added.iter().chain(removed.iter()).count() > 0
}
fn fallback_camera(
mut ui_camera: Query<&mut Camera, With<Camera2d>>,
cameras: Query<&mut Camera, Without<Camera2d>>,
) {
ui_camera.single_mut().is_active = cameras.iter().len() <= 0;
}

@ -1,9 +1,5 @@
/// TODO: /// TODO:
/// * Text box w/ "reset" button /// * Text box w/ "reset" button
/// * Generic Minimize/Close Components
/// * Title bar w/ min/close controls
/// * Notice/Warning/Error Popups
/// * Textbox (ReadOnly)
/// * Textbox (ReadWrite) /// * Textbox (ReadWrite)
/// * Move code to submodules /// * Move code to submodules
/// ///
@ -25,13 +21,15 @@ pub struct TargetEntity {
pub entity: Entity, pub entity: Entity,
} }
pub struct GameUiPlugin; /// UI Plugin
#[derive(Default)]
pub struct GameUiPlugin {
pub enable_alerts: bool,
}
impl Plugin for GameUiPlugin { impl Plugin for GameUiPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_event::<Alert>() app.add_systems(PreUpdate, create_titles)
.add_systems(Startup, init_alerts)
.add_systems(PreUpdate, create_titles)
.add_systems( .add_systems(
Update, Update,
( (
@ -44,10 +42,15 @@ impl Plugin for GameUiPlugin {
manage_collapse_active, manage_collapse_active,
show_child_number, show_child_number,
manage_sort, manage_sort,
spawn_alert,
), ),
) )
.add_systems(PostUpdate, close_window); .add_systems(PostUpdate, close_window);
if self.enable_alerts {
app.add_event::<Alert>()
.add_systems(Startup, init_alerts)
.add_systems(Update, spawn_alert);
}
} }
} }
@ -582,8 +585,8 @@ pub mod alert {
pub struct AlertsWidget; pub struct AlertsWidget;
pub fn init_alerts(mut commands: Commands) { pub fn init_alerts(mut commands: Commands) {
commands.spawn(( commands
NodeBundle { .spawn(NodeBundle {
style: Style { style: Style {
top: Val::Px(0.0), top: Val::Px(0.0),
right: Val::Px(0.0), right: Val::Px(0.0),
@ -598,9 +601,35 @@ pub mod alert {
}, },
border_color: Color::WHITE.into(), border_color: Color::WHITE.into(),
..default() ..default()
})
.with_children(|parent| {
let container = parent
.spawn((
NodeBundle {
style: Style {
padding: UiRect::all(Val::Px(1.0)),
margin: UiRect::all(Val::Px(1.0)),
border: UiRect::all(Val::Px(1.0)),
flex_direction: FlexDirection::Column,
justify_items: JustifyItems::Center,
..default()
},
border_color: Color::WHITE.into(),
..default()
}, },
AlertsWidget, AlertsWidget,
))
.id();
parent.spawn((
TitleBarBase::new(Color::WHITE).bundle(),
Title {
text: "Alerts".into(),
..default()
},
Minimize { target: container },
Sorting(0),
)); ));
});
} }
pub fn spawn_alert( pub fn spawn_alert(

Loading…
Cancel
Save