Add support for emitting signals for nodejs and the interpreter

This also enables the property and signal accessor test case for js.
This commit is contained in:
Simon Hausmann 2020-06-12 10:35:26 +02:00
parent ef9d3963e4
commit 84d8eaa130
4 changed files with 61 additions and 4 deletions

View file

@ -24,6 +24,12 @@ require.extensions['.60'] =
enumerable: true, enumerable: true,
}) })
}); });
c.signals().forEach(x => {
Object.defineProperty(ret, x, {
get() { return function () { comp.emit_signal(x); } },
enumerable: true,
})
});
return ret; return ret;
} }
} }

View file

@ -180,9 +180,25 @@ declare_types! {
let ct = ct.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?; let ct = ct.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?;
let properties = ct.properties(); let properties = ct.properties();
let array = JsArray::new(&mut cx, properties.len() as u32); let array = JsArray::new(&mut cx, properties.len() as u32);
for (i, (p, _)) in properties.iter().enumerate() { let mut len: u32 = 0;
for (p, _) in properties.iter().filter(|(_, prop_type)| prop_type.is_property_type()) {
let prop_name = JsString::new(&mut cx, p); let prop_name = JsString::new(&mut cx, p);
array.set(&mut cx, i as u32, prop_name)?; array.set(&mut cx, len, prop_name)?;
len = len + 1;
}
Ok(array.as_value(&mut cx))
}
method signals(mut cx) {
let this = cx.this();
let ct = cx.borrow(&this, |x| x.0.clone());
let ct = ct.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?;
let properties = ct.properties();
let array = JsArray::new(&mut cx, properties.len() as u32);
let mut len: u32 = 0;
for (p, _) in properties.iter().filter(|(_, prop_type)| **prop_type == Type::Signal) {
let prop_name = JsString::new(&mut cx, p);
array.set(&mut cx, len, prop_name)?;
len = len + 1;
} }
Ok(array.as_value(&mut cx)) Ok(array.as_value(&mut cx))
} }
@ -232,6 +248,26 @@ declare_types! {
Ok(JsUndefined::new().as_value(&mut cx)) Ok(JsUndefined::new().as_value(&mut cx))
} }
method emit_signal(mut cx) {
let signal_name = cx.argument::<JsString>(0)?.value();
let this = cx.this();
let lock = cx.lock();
let x = this.borrow(&lock).0.clone();
let (component, component_ty) = x.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?;
let ty = component_ty.properties()
.get(&signal_name)
.ok_or(())
.or_else(|()| {
cx.throw_error(format!("Signal {} not found in the component", signal_name))
})?
.clone();
component_ty
.emit_signal(component.borrow(), signal_name.as_str())
.or_else(|_| cx.throw_error(format!("Cannot emit signal")))?;
Ok(JsUndefined::new().as_value(&mut cx))
}
} }
} }

View file

@ -95,7 +95,7 @@ impl ComponentDescription {
/// Sets an handler for a signal /// Sets an handler for a signal
/// ///
/// Returns an error if the component is not an instance corresponding to this ComponentDescription, /// Returns an error if the component is not an instance corresponding to this ComponentDescription,
/// or if the property wit this name does not exist in this dociment /// or if the property with this name does not exist in this component
pub fn set_signal_handler( pub fn set_signal_handler(
&self, &self,
component: ComponentRefMut, component: ComponentRefMut,
@ -110,4 +110,19 @@ impl ComponentDescription {
sig.set_handler(handler); sig.set_handler(handler);
Ok(()) Ok(())
} }
/// Emits the specified signal
///
/// Returns an error if the component is not an instance corresponding to this ComponentDescription,
/// or if the signal with this name does not exist in this component
pub fn emit_signal(&self, component: ComponentRef, name: &str) -> Result<(), ()> {
if !core::ptr::eq((&self.ct) as *const _, component.get_vtable() as *const _) {
return Err(());
}
let x = self.custom_signals.get(name).ok_or(())?;
let sig = unsafe { &mut *(component.as_ptr().add(*x) as *mut Signal<()>) };
let eval_context = EvaluationContext { component };
sig.emit(&eval_context, ());
Ok(())
}
} }

View file

@ -21,7 +21,7 @@ instance.emit_test_signal();
assert_eq!(instance.get_signal_emission_count(), 1); assert_eq!(instance.get_signal_emission_count(), 1);
``` ```
```not-working-yet:js ```js
var instance = new sixtyfps.TestCase({}); var instance = new sixtyfps.TestCase({});
instance.signal_emission_count = 0; instance.signal_emission_count = 0;
assert.equal(instance.signal_emission_count, 0); assert.equal(instance.signal_emission_count, 0);