Skip to content

Commit bce89b1

Browse files
author
Emil Sjölander
committed
Implement new rust API for bindings and release v0.3
1 parent a149c6b commit bce89b1

File tree

35 files changed

+2664
-1739
lines changed

35 files changed

+2664
-1739
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "stretch"
3-
version = "0.2.2"
3+
version = "0.3.2"
44
authors = ["Emil Sjölander <[email protected]>"]
55
edition = "2018"
66
include = ["src/**/*", "Cargo.toml"]

README.md

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,36 @@ Stretch is built in Rust but comes with bindings to multiple languages and platf
3232
# Cargo.toml
3333

3434
[dependencies]
35-
stretch = "0.2.2"
35+
stretch = "0.3.2"
3636
```
3737

3838
```rust
3939
// main.rs
4040

41+
use stretch::geometry::Size;
4142
use stretch::style::*;
42-
use stretch::node::*;
43-
use stretch::result::*;
44-
45-
fn main() {
46-
let node = Node::new(
47-
Style {
48-
size: Size { width: Dimension::Points(100.0), height: Dimension::Points(100.0) },
49-
justify_content: JustifyContent::Center,
50-
..Default::default()
51-
},
52-
vec![&Node::new(
53-
Style { size: Size { width: Dimension::Percent(0.5), height: Dimension::Auto }, ..Default::default() },
54-
vec![],
55-
)],
56-
);
57-
58-
let layout = node.compute_layout(Size::undefined()).unwrap();
59-
dbg!(layout);
43+
44+
fn main() -> Result<(), stretch::Error> {
45+
let mut stretch = stretch::node::Stretch::new();
46+
47+
let child = stretch.new_node(
48+
Style { size: Size { width: Dimension::Percent(0.5), height: Dimension::Auto }, ..Default::default() },
49+
vec![],
50+
)?;
51+
52+
let node = stretch.new_node(
53+
Style {
54+
size: Size { width: Dimension::Points(100.0), height: Dimension::Points(100.0) },
55+
justify_content: JustifyContent::Center,
56+
..Default::default()
57+
},
58+
vec![child],
59+
)?;
60+
61+
stretch.compute_layout(node, Size::undefined())?;
62+
dbg!(stretch.layout(node)?);
6063
}
64+
6165
```
6266

6367
### Android
@@ -73,7 +77,7 @@ android {
7377
}
7478
7579
dependencies {
76-
implementation 'app.visly.stretch:stretch:0.2.2'
80+
implementation 'app.visly.stretch:stretch:0.3.2'
7781
}
7882
```
7983

@@ -94,7 +98,7 @@ Log.d(TAG, "width: ${layout.width}, height: ${layout.height}")
9498
```ruby
9599
# Podfile
96100

97-
pod 'StretchKit', '~> 0.2.2'
101+
pod 'StretchKit', '~> 0.3.2'
98102
```
99103

100104
```swift
@@ -118,10 +122,11 @@ print("width: \(layout.width), height: \(layout.height)")
118122
```javascript
119123
// index.js
120124

121-
import { Node, JustifyContent } from 'stretch-layout';
125+
import { Allocator, Node, JustifyContent } from 'stretch-layout';
122126

123-
const node = new Node({width: 100, height: 100, justifyContent: JustifyContent.Center});
124-
node.addChild(new Node({width: '50%', height: '50%'}));
127+
const allocator = new Allocator();
128+
const node = new Node(allocator, {width: 100, height: 100, justifyContent: JustifyContent.Center});
129+
node.addChild(new Node(allocator, {width: '50%', height: '50%'}));
125130
const layout = node.computeLayout();
126131

127132
console.log(layout.width, layout.height);

StretchKit.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'StretchKit'
3-
s.version = '0.2.2'
3+
s.version = '0.3.2'
44
s.summary = 'Swift bindings for the Stretch layout engine.'
55
s.description = "A high performance & cross-platform layout engine."
66
s.homepage = 'https://visly.app/stretch'

bindings/js/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "stretch-layout"
3-
version = "0.2.2"
3+
version = "0.3.2"
44
authors = ["Visly Inc. <[email protected]>"]
55
edition = "2018"
66

@@ -13,7 +13,7 @@ default = ["console_error_panic_hook"]
1313
[dependencies]
1414
wasm-bindgen = "0.2"
1515
js-sys = "0.3"
16-
stretch = "0.2.2"
16+
stretch = "0.3.2"
1717

1818
# The `console_error_panic_hook` crate provides better debugging of panics by
1919
# logging them with `console.error`. This is great for development, but requires

bindings/js/src/lib.rs

Lines changed: 80 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
mod utils;
44

5+
use std::cell::RefCell;
6+
use std::rc::Rc;
7+
58
use js_sys::Function;
69
use js_sys::Reflect;
710
use wasm_bindgen::prelude::*;
@@ -363,14 +366,18 @@ pub struct Layout {
363366

364367
#[wasm_bindgen]
365368
impl Layout {
366-
fn new(layout: stretch::result::Layout) -> Layout {
369+
fn new(allocator: &Allocator, node: stretch::node::Node) -> Layout {
370+
let stretch = allocator.stretch.borrow();
371+
let layout = stretch.layout(node).unwrap();
372+
let children = stretch.children(node).unwrap();
373+
367374
Layout {
368375
width: layout.size.width,
369376
height: layout.size.height,
370377
x: layout.location.x,
371378
y: layout.location.y,
372-
childCount: layout.children.len(),
373-
children: layout.children.into_iter().map(Layout::new).collect(),
379+
childCount: children.len(),
380+
children: children.into_iter().map(|child| Layout::new(allocator, child)).collect(),
374381
}
375382
}
376383

@@ -380,8 +387,23 @@ impl Layout {
380387
}
381388
}
382389

390+
#[wasm_bindgen]
391+
#[derive(Clone)]
392+
pub struct Allocator {
393+
stretch: Rc<RefCell<stretch::node::Stretch>>,
394+
}
395+
396+
#[wasm_bindgen]
397+
impl Allocator {
398+
#[wasm_bindgen(constructor)]
399+
pub fn new() -> Allocator {
400+
Allocator { stretch: Rc::new(RefCell::new(stretch::node::Stretch::new())) }
401+
}
402+
}
403+
383404
#[wasm_bindgen]
384405
pub struct Node {
406+
allocator: Allocator,
385407
node: stretch::node::Node,
386408
style: JsValue,
387409

@@ -392,60 +414,72 @@ pub struct Node {
392414
#[wasm_bindgen]
393415
impl Node {
394416
#[wasm_bindgen(constructor)]
395-
pub fn new(style: &JsValue) -> Node {
396-
Node { node: stretch::node::Node::new(parse_style(&style), vec![]), style: style.clone(), childCount: 0 }
417+
pub fn new(allocator: &Allocator, style: &JsValue) -> Node {
418+
Node {
419+
allocator: allocator.clone(),
420+
node: allocator.stretch.borrow_mut().new_node(parse_style(&style), vec![]).unwrap(),
421+
style: style.clone(),
422+
childCount: 0,
423+
}
397424
}
398425

399426
#[wasm_bindgen(js_name = setMeasure)]
400427
pub fn set_measure(&mut self, measure: &JsValue) {
401428
let measure = Function::from(measure.clone());
402429

403-
self.node.set_measure(Some(Box::new(move |constraints| {
404-
let widthConstraint = if let stretch::number::Number::Defined(val) = constraints.width {
405-
val.into()
406-
} else {
407-
JsValue::UNDEFINED
408-
};
409-
410-
let heightConstaint = if let stretch::number::Number::Defined(val) = constraints.height {
411-
val.into()
412-
} else {
413-
JsValue::UNDEFINED
414-
};
415-
416-
if let Ok(result) = measure.call2(&JsValue::UNDEFINED, &widthConstraint, &heightConstaint) {
417-
let width = get_f32(&result, "width");
418-
let height = get_f32(&result, "height");
419-
420-
if width.is_some() && height.is_some() {
421-
return Ok(stretch::geometry::Size { width: width.unwrap(), height: height.unwrap() });
422-
}
423-
}
430+
self.allocator
431+
.stretch
432+
.borrow_mut()
433+
.set_measure(
434+
self.node,
435+
Some(Box::new(move |constraints| {
436+
let widthConstraint = if let stretch::number::Number::Defined(val) = constraints.width {
437+
val.into()
438+
} else {
439+
JsValue::UNDEFINED
440+
};
441+
442+
let heightConstaint = if let stretch::number::Number::Defined(val) = constraints.height {
443+
val.into()
444+
} else {
445+
JsValue::UNDEFINED
446+
};
447+
448+
if let Ok(result) = measure.call2(&JsValue::UNDEFINED, &widthConstraint, &heightConstaint) {
449+
let width = get_f32(&result, "width");
450+
let height = get_f32(&result, "height");
451+
452+
if width.is_some() && height.is_some() {
453+
return Ok(stretch::geometry::Size { width: width.unwrap(), height: height.unwrap() });
454+
}
455+
}
424456

425-
Err(Box::new("Failed in javascript"))
426-
})));
457+
Err(Box::new("Failed in javascript"))
458+
})),
459+
)
460+
.unwrap();
427461
}
428462

429463
#[wasm_bindgen(js_name = addChild)]
430464
pub fn add_child(&mut self, child: &Node) {
431-
self.node.add_child(&child.node);
465+
self.allocator.stretch.borrow_mut().add_child(self.node, child.node).unwrap();
432466
self.childCount += 1;
433467
}
434468

435469
#[wasm_bindgen(js_name = removeChild)]
436470
pub fn remove_child(&mut self, child: &Node) {
437-
self.node.remove_child(&child.node);
471+
self.allocator.stretch.borrow_mut().remove_child(self.node, child.node).unwrap();
438472
self.childCount -= 1;
439473
}
440474

441475
#[wasm_bindgen(js_name = replaceChildAtIndex)]
442476
pub fn replace_child_at_index(&mut self, index: usize, child: &Node) {
443-
self.node.replace_child_at_index(index, &child.node);
477+
self.allocator.stretch.borrow_mut().replace_child_at_index(self.node, index, child.node).unwrap();
444478
}
445479

446480
#[wasm_bindgen(js_name = removeChildAtIndex)]
447481
pub fn remove_child_at_index(&mut self, index: usize) {
448-
self.node.remove_child_at_index(index);
482+
self.allocator.stretch.borrow_mut().remove_child_at_index(self.node, index).unwrap();
449483
self.childCount -= 1;
450484
}
451485

@@ -456,25 +490,28 @@ impl Node {
456490

457491
#[wasm_bindgen(js_name = setStyle)]
458492
pub fn set_style(&mut self, style: &JsValue) {
459-
self.node.set_style(parse_style(style));
493+
self.allocator.stretch.borrow_mut().set_style(self.node, parse_style(style)).unwrap();
460494
self.style = style.clone();
461495
}
462496

463497
#[wasm_bindgen(js_name = markDirty)]
464498
pub fn mark_dirty(&mut self) {
465-
self.node.mark_dirty()
499+
self.allocator.stretch.borrow_mut().mark_dirty(self.node).unwrap()
466500
}
467501

468502
#[wasm_bindgen(js_name = isDirty)]
469503
pub fn is_dirty(&self) -> bool {
470-
self.node.dirty()
504+
self.allocator.stretch.borrow().dirty(self.node).unwrap()
471505
}
472506

473507
#[wasm_bindgen(js_name = computeLayout)]
474-
pub fn compute_layout(&self, size: &JsValue) -> Layout {
475-
Layout::new(
476-
self.node
477-
.compute_layout(stretch::geometry::Size {
508+
pub fn compute_layout(&mut self, size: &JsValue) -> Layout {
509+
self.allocator
510+
.stretch
511+
.borrow_mut()
512+
.compute_layout(
513+
self.node,
514+
stretch::geometry::Size {
478515
width: if let Some(val) = get_f32(size, "width") {
479516
stretch::number::Number::Defined(val)
480517
} else {
@@ -485,9 +522,10 @@ impl Node {
485522
} else {
486523
stretch::number::Number::Undefined
487524
},
488-
})
489-
.unwrap(),
490-
)
525+
},
526+
)
527+
.unwrap();
528+
Layout::new(&self.allocator, self.node)
491529
}
492530
}
493531

0 commit comments

Comments
 (0)