mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-17 00:13:17 +00:00
Fixed input update problem
This commit is contained in:
@@ -2,6 +2,7 @@ import { register_new_change, type InspectorDomChanged } from "@storyteller/stud
|
||||
|
||||
console.log("Hello, World!");
|
||||
|
||||
|
||||
function unpack_vnode(
|
||||
vnode: any
|
||||
) {
|
||||
@@ -29,7 +30,7 @@ function unpack_vnode(
|
||||
}
|
||||
//add onchange hook if input
|
||||
if (node_data["onchange"] == true) {
|
||||
element.onchange = (event: Event) => {
|
||||
element.oninput = (event: Event) => {
|
||||
var input = event.target as HTMLInputElement;
|
||||
const id = input.getAttribute("id");
|
||||
if (id != null) {
|
||||
@@ -75,6 +76,35 @@ function apply_muts(
|
||||
root.removeChild(root.firstChild);
|
||||
}
|
||||
root.appendChild(element);
|
||||
} else if (mut["SetAttibute"] != undefined) {
|
||||
let m = mut["SetAttibute"];
|
||||
let id = m["id"];
|
||||
let value = m["value"];
|
||||
let attribute = m["attribute"];
|
||||
let element = shadowroot?.getElementById(id);
|
||||
if (!element) {
|
||||
console.log("element not found", id);
|
||||
} else {
|
||||
if (attribute == "value") {
|
||||
var input = element as HTMLInputElement;
|
||||
if (input) {
|
||||
input.value = value;
|
||||
//update input value
|
||||
// Create a new 'input' event
|
||||
const event = new Event('input', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
|
||||
// Dispatch the event
|
||||
input.dispatchEvent(event);
|
||||
|
||||
console.log("input value updated", value);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
element.setAttribute(attribute, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,6 @@ fn show_selected(
|
||||
|
||||
let mut virtial_dom = cell.get_resource_mut::<VirtualDom>().unwrap();
|
||||
let app_type_registry = cell.get_resource::<AppTypeRegistry>().unwrap();
|
||||
let app_type_registry = app_type_registry.read();
|
||||
|
||||
let e = cell.get_entity(selected_entity).unwrap();
|
||||
|
||||
if let Some(changes) = super::utils::wasm::ONCHAGE_BUFFER.take_message() {
|
||||
@@ -92,7 +90,7 @@ fn show_selected(
|
||||
|
||||
let id = e.id();
|
||||
|
||||
let components = cell.components().clone();
|
||||
let components = cell.components();
|
||||
let element = Element::Component(super::utils::Component {
|
||||
tag: "div".to_string(),
|
||||
attributes: vec![
|
||||
|
||||
+102
-8
@@ -11,6 +11,7 @@ trait NodeProp : Clone + PartialEq {
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum Mutation {
|
||||
SetAttibute{id : String, attribute : String, value : String},
|
||||
ReplaceAll(VNode),
|
||||
RemoveAll
|
||||
}
|
||||
@@ -64,9 +65,9 @@ impl VirtualDom {
|
||||
|
||||
if let Some(element) = element {
|
||||
let node = self.recursive_unpack_element(&mut id_counter, element);
|
||||
return self.create_mutations(Some(node));
|
||||
return self.create_mutations(node);
|
||||
} else {
|
||||
return self.create_mutations(None);
|
||||
return self.create_mutations(VNode::Text("".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +87,7 @@ impl VirtualDom {
|
||||
|
||||
VNode::Component(VComponent {
|
||||
tag: component.tag,
|
||||
attributes: component.attributes,
|
||||
attributes: component.attributes.into_iter().collect(),
|
||||
id: Some(id),
|
||||
onchange: onchange_enabled,
|
||||
children: component.children.into_iter().map(|e| self.recursive_unpack_element(counter, e)).collect()
|
||||
@@ -95,12 +96,22 @@ impl VirtualDom {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_mutations(&mut self, node : Option<VNode>) -> Vec<Mutation> {
|
||||
if self.last_node == node {
|
||||
pub fn create_mutations(&mut self, node : VNode) -> Vec<Mutation> {
|
||||
if self.last_node == Some(node.clone()) {
|
||||
return vec![]
|
||||
} else {
|
||||
self.last_node = node.clone();
|
||||
return vec![Mutation::ReplaceAll(node.unwrap())]
|
||||
|
||||
if let Some(last_node) = &self.last_node {
|
||||
if last_node.is_same_structure(&node) {
|
||||
|
||||
let muts = node.get_same_structure_muts(&last_node);
|
||||
self.last_node = Some(node.clone());
|
||||
return muts;
|
||||
}
|
||||
}
|
||||
|
||||
self.last_node = Some(node.clone());
|
||||
return vec![Mutation::ReplaceAll(node)]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,6 +185,27 @@ impl WebEventExecutor for ReflectValueExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
struct EntityChangeExecutor {
|
||||
entity : Entity,
|
||||
func : Box<dyn Fn(&mut World, Entity, String) + Send + Sync>,
|
||||
}
|
||||
|
||||
impl WebEventExecutor for EntityChangeExecutor {
|
||||
fn execute(&mut self, world: &mut World, value: String) {
|
||||
(self.func)(world, self.entity, value);
|
||||
}
|
||||
}
|
||||
|
||||
impl EntityChangeExecutor {
|
||||
fn new(entity : Entity, func : impl Fn(&mut World, Entity, String) + Send + Sync + 'static) -> Self {
|
||||
EntityChangeExecutor { entity, func : Box::new(func) }
|
||||
}
|
||||
|
||||
fn new_boxed(entity : Entity, func : impl Fn(&mut World, Entity, String) + Send + Sync + 'static) -> Box<Self> {
|
||||
Box::new(EntityChangeExecutor::new(entity, func))
|
||||
}
|
||||
}
|
||||
|
||||
fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Element> {
|
||||
if let Some(name) = r.downcast_ref::<Name>() {
|
||||
Some(Element::Component(Component {
|
||||
@@ -214,7 +246,15 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
|
||||
("value".to_string(), euler.0.to_string()),
|
||||
],
|
||||
children: vec![],
|
||||
onchange: None
|
||||
onchange: Some(EntityChangeExecutor::new_boxed(
|
||||
onchange.entity_id,
|
||||
|world : &mut World, entity, value : String| {
|
||||
let mut e = world.get_entity_mut(entity).unwrap();
|
||||
let mut transform = e.get_mut::<Transform>().unwrap();
|
||||
let euler = transform.rotation.to_euler(EulerRot::XYZ);
|
||||
transform.rotation = Quat::from_euler(EulerRot::XYZ, value.parse().unwrap(), euler.1, euler.2);
|
||||
}
|
||||
))
|
||||
}),
|
||||
Element::Text("Y: ".to_string()),
|
||||
Element::Component(Component {
|
||||
@@ -382,6 +422,60 @@ pub enum VNode {
|
||||
Component(VComponent),
|
||||
}
|
||||
|
||||
impl VNode {
|
||||
pub fn is_same_structure(&self, other : &VNode) -> bool {
|
||||
match (self, other) {
|
||||
(VNode::Text(s1), VNode::Text(s2)) => s1 == s2,
|
||||
(VNode::Text(_), VNode::Component(_)) => false,
|
||||
(VNode::Component(_), VNode::Text(_)) => false,
|
||||
(VNode::Component(c1), VNode::Component(c2)) => {
|
||||
if c1.tag != c2.tag {
|
||||
return false
|
||||
} else if c1.children.len() != c2.children.len() {
|
||||
return false
|
||||
} else {
|
||||
for i in 0..c1.children.len() {
|
||||
if !c1.children[i].is_same_structure(&c2.children[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_same_structure_muts(&self, older : &VNode) -> Vec<Mutation> {
|
||||
let mut res = vec![];
|
||||
match (self, older) {
|
||||
(VNode::Text(s1), VNode::Text(s2)) => {
|
||||
res
|
||||
}
|
||||
(VNode::Text(_), VNode::Component(_)) => {
|
||||
res
|
||||
}
|
||||
(VNode::Component(_), VNode::Text(_)) => {
|
||||
res
|
||||
}
|
||||
(VNode::Component(new), VNode::Component(old)) => {
|
||||
for idx in 0..new.attributes.len() {
|
||||
if new.attributes.get(idx) != old.attributes.get(idx) {
|
||||
res.push(Mutation::SetAttibute {
|
||||
id: old.id.as_ref().unwrap().clone(),
|
||||
attribute: new.attributes[idx].0.clone(),
|
||||
value: new.attributes[idx].1.clone()
|
||||
});
|
||||
}
|
||||
}
|
||||
for i in 0..new.children.len() {
|
||||
res.append(&mut new.children[i].get_same_structure_muts(&old.children[i]));
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InspectedEntity {
|
||||
pub id: Option<Entity>,
|
||||
pub components: Vec<Box<dyn Reflect>>,
|
||||
|
||||
Reference in New Issue
Block a user