pub mod proxies;
mod registry;
pub use proxies::{
AabbProxy, ColorLoadOpProxy, DepthLoadOpProxy, GpuMaterialProxy, GpuMeshProxy,
GpuRenderPipelineProxy, InputEventsProxy, Mat4Proxy, Mat4VecProxy, QuatProxy,
StencilLoadOpProxy, Vec3Proxy, Vec4Proxy,
};
pub use unlit_ecs::reflect::{
ComponentEntry, ComponentError, contains, current_partial, default_partial, encode_json,
entries, entry, names, push, push_json, set, set_json,
};
use crate::input::InputEvent;
pub fn decode_events(text: &str) -> Result<Vec<InputEvent>, facet_json::DeserializeError> {
facet_json::from_str(text)
}
#[cfg(test)]
mod tests {
use facet::Facet;
use glam::{Mat4, Quat, Vec3, Vec4};
use unlit_ecs::{Entity, EntityProxy, bundle};
use super::*;
use crate::components::{Camera, MorphBinding, MorphWeights, SkinBinding, SkinPose, Transform};
#[test]
fn a_proxy_round_trips_its_value() {
let vector = Vec3::new(1.0, 2.0, 3.0);
assert_eq!(Vec3::from(Vec3Proxy::from(&vector)), vector);
let color = Vec4::new(0.1, 0.2, 0.3, 0.4);
assert_eq!(Vec4::from(Vec4Proxy::from(&color)), color);
let rotation = Quat::from_rotation_y(1.5);
assert_eq!(Quat::from(QuatProxy::from(&rotation)), rotation);
let matrix = Mat4::from_scale(Vec3::splat(2.0));
assert_eq!(Mat4::from(Mat4Proxy::from(&matrix)), matrix);
let matrices = vec![Mat4::IDENTITY, matrix];
assert_eq!(Vec::<Mat4>::from(Mat4VecProxy::from(&matrices)), matrices);
let entity = Entity::from_raw(7, 3);
assert_eq!(Entity::from(EntityProxy::from(&entity)), entity);
}
#[test]
fn the_components_derive_their_reflection() {
assert_eq!(Transform::SHAPE.type_identifier, "Transform");
assert_eq!(Camera::SHAPE.type_identifier, "Camera");
assert_eq!(SkinPose::SHAPE.type_identifier, "SkinPose");
assert_eq!(MorphWeights::SHAPE.type_identifier, "MorphWeights");
assert_eq!(SkinBinding::SHAPE.type_identifier, "SkinBinding");
assert_eq!(MorphBinding::SHAPE.type_identifier, "MorphBinding");
assert_eq!(
crate::components::ZSortedDrawing::SHAPE.type_identifier,
"ZSortedDrawing"
);
assert_eq!(
crate::components::InstanceVisibility::SHAPE.type_identifier,
"InstanceVisibility"
);
assert_eq!(
crate::unlit::InstanceColor::SHAPE.type_identifier,
"InstanceColor"
);
assert_eq!(
crate::unlit::InstanceCutoff::SHAPE.type_identifier,
"InstanceCutoff"
);
}
#[test]
fn a_buffer_reflects_its_events_and_the_state_they_left() {
use crate::input::{InputEvent, InputEvents, InputWriter, Key, KeyEvent, Modifiers};
let key = InputEvent::Key(KeyEvent {
key: Key::A,
pressed: true,
repeat: false,
modifiers: Modifiers::default(),
});
let writer = InputWriter::new();
let mut world = unlit_ecs::World::new();
let entity = world.root_scope_mut().spawn(bundle![writer.subscribe()]);
writer.push(key.clone());
writer.push(InputEvent::FocusChanged(false));
world
.root_scope()
.query_one::<&InputEvents>(entity)
.expect("the buffer spawned")
.refresh();
let encoded =
encode_json(&world.root_scope(), entity, "InputEvents").expect("the buffer encodes");
let decoded: InputEventsProxy =
facet_json::from_str(&encoded).expect("the encoding is JSON");
assert_eq!(decoded.events, vec![key, InputEvent::FocusChanged(false)]);
assert!(!decoded.focused, "the state the events left is read too");
}
#[test]
fn the_events_decode_through_their_reflection() {
use crate::input::{Key, KeyEvent, MouseEvent, TouchPhase, WheelUnit};
let events = decode_events(
r#"[{"Key":{"key":"A","pressed":true}},{"Mouse":{"Wheel":{"delta":[1.0,2.0]}}}]"#,
)
.expect("the events decode");
assert_eq!(
events,
vec![
InputEvent::Key(KeyEvent {
key: Key::A,
pressed: true,
repeat: false,
modifiers: Default::default(),
}),
InputEvent::Mouse(MouseEvent::Wheel {
delta: [1.0, 2.0],
unit: WheelUnit::Pixel,
phase: TouchPhase::Moved,
modifiers: Default::default(),
}),
]
);
}
#[test]
fn the_reflection_names_the_defining_module() {
let shape = Transform::SHAPE;
assert_eq!(shape.module_path, Some("unlit3d::components"));
assert_eq!(
format!(
"{}::{}",
shape.module_path.expect("a module"),
shape.type_identifier
),
"unlit3d::components::Transform"
);
}
}