use std::collections::HashMap;
use nightshade_ecs::Entity;
use serde::{Deserialize, Serialize};
use super::components::Scene;
use crate::assets::asset::{AssetUuid, TypedPayload};
use crate::ecs::world::World;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum FieldKind {
Bool,
I32,
U32,
F32,
String,
Vec3,
Enum { variants: Vec<String> },
Color,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldDescriptor {
pub name: String,
pub kind: FieldKind,
#[serde(default)]
pub display_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComponentDescriptor {
pub name: String,
#[serde(default)]
pub display_name: Option<String>,
pub fields: Vec<FieldDescriptor>,
#[serde(default)]
pub persistence: Persistence,
}
#[derive(Debug, Clone, Default)]
pub struct ComponentTypeRegistry {
pub descriptors: HashMap<String, ComponentDescriptor>,
}
pub fn register_component_descriptor(world: &mut World, descriptor: ComponentDescriptor) {
world
.res_mut::<crate::assets::scene::typed::ComponentTypeRegistry>()
.descriptors
.insert(descriptor.name.clone(), descriptor);
}
pub fn component_descriptor<'a>(world: &'a World, name: &str) -> Option<&'a ComponentDescriptor> {
world
.res::<crate::assets::scene::typed::ComponentTypeRegistry>()
.descriptors
.get(name)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum Persistence {
Authored,
Runtime,
#[default]
Both,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TypedComponent {
pub name: String,
pub data: TypedPayload,
#[serde(default)]
pub persistence: Persistence,
#[serde(default)]
pub field_overrides: Vec<crate::assets::prefab::components::FieldOverride>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TypedResource {
pub name: String,
pub data: TypedPayload,
#[serde(default)]
pub persistence: Persistence,
}
pub fn apply_field_overrides(
base: &serde_json::Value,
overrides: &[crate::assets::prefab::components::FieldOverride],
) -> serde_json::Value {
let mut merged = base.clone();
if let serde_json::Value::Object(map) = &mut merged {
for entry in overrides {
map.insert(entry.field_name.clone(), entry.value.0.clone());
}
}
merged
}
pub trait SceneSerializer {
fn populate_scene(
&self,
world: &World,
entity_uuids: &HashMap<Entity, AssetUuid>,
scene: &mut Scene,
);
}
pub trait SceneDeserializer {
fn populate_world(
&mut self,
world: &mut World,
uuid_to_entity: &HashMap<AssetUuid, Entity>,
scene: &Scene,
);
}