Prepare the path element setup in the run-time for extensibility

Make the anonymous struct for the LineTo variant in the PathElement enum
as separate structure, which can be introspected using rtto::FieldInfo.
This commit is contained in:
Simon Hausmann 2020-07-07 10:47:13 +02:00
parent 9d9779ecde
commit 1ab71b8ca3
8 changed files with 39 additions and 22 deletions

View file

@ -6,6 +6,7 @@
namespace sixtyfps { namespace sixtyfps {
using internal::types::PathElement; using internal::types::PathElement;
using internal::types::PathLineTo;
struct PathElements struct PathElements
{ {

View file

@ -1,7 +1,7 @@
use core::cell::RefCell; use core::cell::RefCell;
use neon::prelude::*; use neon::prelude::*;
use sixtyfps_compilerlib::typeregister::Type; use sixtyfps_compilerlib::typeregister::Type;
use sixtyfps_corelib::abi::datastructures::{PathElement, Resource}; use sixtyfps_corelib::abi::datastructures::{PathElement, PathLineTo, Resource};
use sixtyfps_corelib::{ComponentRefPin, EvaluationContext}; use sixtyfps_corelib::{ComponentRefPin, EvaluationContext};
use std::rc::Rc; use std::rc::Rc;
@ -161,7 +161,7 @@ fn to_js_value<'cx>(
let element_object = JsObject::new(cx); let element_object = JsObject::new(cx);
match element { match element {
PathElement::LineTo { x, y } => { PathElement::LineTo(PathLineTo { x, y }) => {
let x = JsNumber::new(cx, *x); let x = JsNumber::new(cx, *x);
let x = x.as_value(cx); let x = x.as_value(cx);
element_object.set(cx, "x", x)?; element_object.set(cx, "x", x)?;

View file

@ -1,6 +1,6 @@
use cgmath::{Matrix4, SquareMatrix, Vector3}; use cgmath::{Matrix4, SquareMatrix, Vector3};
use sixtyfps_corelib::abi::datastructures::{ use sixtyfps_corelib::abi::datastructures::{
Color, PathElement, PathElements, RenderingPrimitive, Resource, Color, PathElement, PathElements, PathLineTo, RenderingPrimitive, Resource,
}; };
use sixtyfps_corelib::graphics::{ use sixtyfps_corelib::graphics::{
Frame, GraphicsBackend, RenderingCache, RenderingPrimitivesBuilder, Frame, GraphicsBackend, RenderingCache, RenderingPrimitivesBuilder,
@ -65,8 +65,10 @@ fn main() {
render_cache.allocate_entry(image_primitive) render_cache.allocate_entry(image_primitive)
}; };
const TRIANGLE_PATH: &'static [PathElement] = const TRIANGLE_PATH: &'static [PathElement] = &[
&[PathElement::LineTo { x: 100., y: 50. }, PathElement::LineTo { x: 0., y: 100. }]; PathElement::LineTo(PathLineTo { x: 100., y: 50. }),
PathElement::LineTo(PathLineTo { x: 0., y: 100. }),
];
let path_node = { let path_node = {
let path_primitive = rendering_primitives_builder.create(RenderingPrimitive::Path { let path_primitive = rendering_primitives_builder.create(RenderingPrimitive::Path {
x: 50., x: 50.,

View file

@ -823,7 +823,7 @@ fn compile_expression(e: &crate::expression_tree::Expression, component: &Rc<Com
.iter() .iter()
.map(|element| match element { .map(|element| match element {
crate::expression_tree::PathElement::LineTo { x, y } => format!( crate::expression_tree::PathElement::LineTo { x, y } => format!(
"sixtyfps::PathElement::LineTo({}, {})", "sixtyfps::PathElement::LineTo(sixtyfps::PathLineTo{{{}, {}}})",
compile_expression(x, component), compile_expression(x, component),
compile_expression(y, component) compile_expression(y, component)
), ),

View file

@ -684,7 +684,7 @@ fn compile_expression(e: &Expression, component: &Rc<Component>) -> TokenStream
crate::expression_tree::PathElement::LineTo { x, y } => { crate::expression_tree::PathElement::LineTo { x, y } => {
let x = compile_expression(x, component); let x = compile_expression(x, component);
let y = compile_expression(y, component); let y = compile_expression(y, component);
quote!(PathElement::LineTo { x: #x as _, y: #y as _}) quote!(PathElement::LineTo(PathLineTo { x: #x as _, y: #y as _} ))
} }
}) })
.collect(); .collect();

View file

@ -6,6 +6,11 @@ use core::pin::Pin;
use std::cell::Cell; use std::cell::Cell;
use vtable::*; use vtable::*;
#[cfg(feature = "rtti")]
use crate::rtti::{BuiltinItem, FieldInfo, FieldOffset, PropertyInfo, ValueType};
use const_field_offset::FieldOffsets;
use corelib_macro::*;
/// 2D Rectangle /// 2D Rectangle
pub type Rect = euclid::default::Rect<f32>; pub type Rect = euclid::default::Rect<f32>;
/// 2D Point /// 2D Point
@ -247,18 +252,26 @@ impl Default for Resource {
} }
} }
#[repr(C)]
#[derive(FieldOffsets, Default, BuiltinItem, Clone, Debug, PartialEq)]
#[pin]
/// PathLineTo describes the event of moving the cursor on the path to the specified location
/// along a straight line.
pub struct PathLineTo {
#[rtti_field]
/// The x coordinate where the line should go to.
pub x: f32,
#[rtti_field]
/// The y coordinate where the line should go to.
pub y: f32,
}
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
/// PathElement describes a single element on a path, such as move-to, line-to, etc. /// PathElement describes a single element on a path, such as move-to, line-to, etc.
pub enum PathElement { pub enum PathElement {
/// Line to describes the event of moving the cursor on the path to the specified location /// The LineTo variant describes a line.
/// along a straight line. LineTo(PathLineTo),
LineTo {
/// The x coordinate where the line should go to.
x: f32,
/// The y coordinate where the line should go to.
y: f32,
},
} }
#[repr(C)] #[repr(C)]

View file

@ -4,8 +4,9 @@ use sixtyfps_compilerlib::expression_tree::{Expression, NamedReference, PathElem
use sixtyfps_compilerlib::{object_tree::ElementRc, typeregister::Type}; use sixtyfps_compilerlib::{object_tree::ElementRc, typeregister::Type};
use sixtyfps_corelib as corelib; use sixtyfps_corelib as corelib;
use sixtyfps_corelib::{ use sixtyfps_corelib::{
abi::datastructures::ItemRef, abi::primitives::PropertyAnimation, Color, EvaluationContext, abi::datastructures::ItemRef, abi::datastructures::PathLineTo,
PathElements, Resource, SharedString, abi::primitives::PropertyAnimation, Color, EvaluationContext, PathElements, Resource,
SharedString,
}; };
use std::{collections::HashMap, rc::Rc}; use std::{collections::HashMap, rc::Rc};
@ -325,14 +326,14 @@ pub fn eval_expression(
>::from_iter( >::from_iter(
elements.iter().map(|element| match element { elements.iter().map(|element| match element {
PathElement::LineTo { x, y } => { PathElement::LineTo { x, y } => {
sixtyfps_corelib::abi::datastructures::PathElement::LineTo { sixtyfps_corelib::abi::datastructures::PathElement::LineTo(PathLineTo {
x: eval_expression(&x, component_type, eval_context) x: eval_expression(&x, component_type, eval_context)
.try_into() .try_into()
.unwrap(), .unwrap(),
y: eval_expression(&y, component_type, eval_context) y: eval_expression(&y, component_type, eval_context)
.try_into() .try_into()
.unwrap(), .unwrap(),
} })
} }
}), }),
))) )))

View file

@ -5,8 +5,8 @@ use itertools::Itertools;
use lyon::tessellation::geometry_builder::{BuffersBuilder, VertexBuffers}; use lyon::tessellation::geometry_builder::{BuffersBuilder, VertexBuffers};
use lyon::tessellation::{FillAttributes, FillOptions, FillTessellator}; use lyon::tessellation::{FillAttributes, FillOptions, FillTessellator};
use sixtyfps_corelib::abi::datastructures::{ use sixtyfps_corelib::abi::datastructures::{
Color, ComponentWindow, ComponentWindowOpaque, PathElement, Point, Rect, RenderingPrimitive, Color, ComponentWindow, ComponentWindowOpaque, PathElement, PathLineTo, Point, Rect,
Resource, Size, RenderingPrimitive, Resource, Size,
}; };
use sixtyfps_corelib::graphics::{ use sixtyfps_corelib::graphics::{
FillStyle, Frame as GraphicsFrame, GraphicsBackend, GraphicsWindow, HasRenderingPrimitive, FillStyle, Frame as GraphicsFrame, GraphicsBackend, GraphicsWindow, HasRenderingPrimitive,
@ -342,7 +342,7 @@ impl RenderingPrimitivesBuilder for GLRenderingPrimitivesBuilder {
let mut path_builder = lyon::path::Path::builder().with_svg(); let mut path_builder = lyon::path::Path::builder().with_svg();
for element in elements.iter() { for element in elements.iter() {
match element { match element {
PathElement::LineTo { x, y } => { PathElement::LineTo(PathLineTo { x, y }) => {
path_builder.line_to(Point::new(*x, *y)) path_builder.line_to(Point::new(*x, *y))
} }
} }