migrate to emscripten

This commit is contained in:
Dmitry Ivakhnenko
2022-11-22 15:05:05 +03:00
parent 35f3335efc
commit 8d3e02f565
17 changed files with 311 additions and 895 deletions

View File

@@ -7,8 +7,6 @@
#pragma once
#include <nbind/api.h>
#include <nbind/BindDefiner.h>
#include <yoga/Yoga.h>
class Config {

View File

@@ -7,9 +7,6 @@
#pragma once
#include <nbind/api.h>
#include <nbind/BindDefiner.h>
struct Layout {
double left;
double right;
@@ -19,8 +16,5 @@ struct Layout {
double width;
double height;
void toJS(nbind::cbOutput expose) const {
expose(left, right, top, bottom, width, height);
}
};

View File

@@ -242,7 +242,7 @@ int Node::getPositionType(void) const {
Value Node::getPosition(int edge) const {
return Value::fromYGValue(
YGNodeStyleGetPosition(m_node, static_cast<YGEdge>(edge)));
YGNodeStyleGetPosition(m_node, static_cast<YGEdge>(edge)));
}
int Node::getAlignContent(void) const {
@@ -271,7 +271,7 @@ int Node::getJustifyContent(void) const {
Value Node::getMargin(int edge) const {
return Value::fromYGValue(
YGNodeStyleGetMargin(m_node, static_cast<YGEdge>(edge)));
YGNodeStyleGetMargin(m_node, static_cast<YGEdge>(edge)));
}
int Node::getOverflow(void) const {
@@ -328,12 +328,11 @@ double Node::getBorder(int edge) const {
Value Node::getPadding(int edge) const {
return Value::fromYGValue(
YGNodeStyleGetPadding(m_node, static_cast<YGEdge>(edge)));
YGNodeStyleGetPadding(m_node, static_cast<YGEdge>(edge)));
}
Value Node::getGap(int gutter, ) {
return Value::fromYGValue(
YGNodeStyleGetGap(m_node, static_cast<YGGutter>(gutter)));
float Node::getGap(int gutter) {
return YGNodeStyleGetGap(m_node, static_cast<YGGutter>(gutter));
}
bool Node::isReferenceBaseline() {
@@ -370,8 +369,8 @@ Node* Node::getChild(unsigned index) {
return Node::fromYGNode(nodePtr);
}
void Node::setMeasureFunc(nbind::cbFunction& measureFunc) {
m_measureFunc.reset(new nbind::cbFunction(measureFunc));
void Node::setMeasureFunc(MeasureCallback *measureFunc) {
m_measureFunc.reset(measureFunc);
YGNodeSetMeasureFunc(m_node, &globalMeasureFunc);
}
@@ -387,11 +386,11 @@ Size Node::callMeasureFunc(
int widthMode,
double height,
int heightMode) const {
return m_measureFunc->call<Size>(width, widthMode, height, heightMode);
return m_measureFunc->measure(width, widthMode, height, heightMode);
}
void Node::setDirtiedFunc(nbind::cbFunction& dirtiedFunc) {
m_dirtiedFunc.reset(new nbind::cbFunction(dirtiedFunc));
void Node::setDirtiedFunc(DirtiedCallback *dirtiedFunc) {
m_dirtiedFunc.reset(dirtiedFunc);
YGNodeSetDirtiedFunc(m_node, &globalDirtiedFunc);
}
@@ -403,7 +402,7 @@ void Node::unsetDirtiedFunc(void) {
}
void Node::callDirtiedFunc(void) const {
m_dirtiedFunc->call<void>();
m_dirtiedFunc->dirtied();
}
void Node::markDirty(void) {

View File

@@ -9,8 +9,7 @@
#include <memory>
#include <nbind/api.h>
#include <nbind/BindDefiner.h>
#include <emscripten/bind.h>
#include <yoga/Yoga.h>
#include "./Layout.hh"
@@ -18,6 +17,33 @@
#include "./Value.hh"
#include "./Config.hh"
struct MeasureCallback {
virtual Size measure(float width,
int widthMode,
float height,
int heightMode) = 0;
};
struct MeasureCallbackWrapper : public emscripten::wrapper<MeasureCallback> {
EMSCRIPTEN_WRAPPER(MeasureCallbackWrapper);
Size measure(float width, int widthMode, float height, int heightMode)
{
return call<Size>("measure", width, widthMode, height, heightMode);
}
};
struct DirtiedCallback {
virtual void dirtied() = 0;
};
struct DirtiedCallbackWrapper : public emscripten::wrapper<DirtiedCallback> {
EMSCRIPTEN_WRAPPER(DirtiedCallbackWrapper);
void dirtied()
{
return call<void>("dirtied");
}
};
class Node {
public:
@@ -131,8 +157,8 @@ public: // Style getters
double getBorder(int edge) const;
Value getPadding(int edge) const;
Value getGap(int gutter);
float getGap(int gutter);
public: // Tree hierarchy mutators
void insertChild(Node* child, unsigned index);
@@ -148,7 +174,7 @@ public: // Tree hierarchy inspectors
Node* getChild(unsigned index);
public: // Measure func mutators
void setMeasureFunc(nbind::cbFunction& measureFunc);
void setMeasureFunc(MeasureCallback *measureFunc);
void unsetMeasureFunc(void);
public: // Measure func inspectors
@@ -159,7 +185,7 @@ public: // Measure func inspectors
int heightMode) const;
public: // Dirtied func mutators
void setDirtiedFunc(nbind::cbFunction& dirtiedFunc);
void setDirtiedFunc(DirtiedCallback *dirtiedFunc);
void unsetDirtiedFunc(void);
public: // Dirtied func inspectors
@@ -194,6 +220,6 @@ public:
YGNodeRef m_node;
std::unique_ptr<nbind::cbFunction> m_measureFunc;
std::unique_ptr<nbind::cbFunction> m_dirtiedFunc;
std::unique_ptr<MeasureCallback> m_measureFunc;
std::unique_ptr<DirtiedCallback> m_dirtiedFunc;
};

View File

@@ -7,9 +7,6 @@
#pragma once
#include <nbind/api.h>
#include <nbind/BindDefiner.h>
struct Size {
double width;
double height;
@@ -17,6 +14,4 @@ struct Size {
Size(void) : width(0.0), height(0.0) {}
Size(double width, double height) : width(width), height(height) {}
void toJS(nbind::cbOutput expose) const { expose(width, height); }
};

View File

@@ -19,7 +19,5 @@ struct Value {
Value(void) : unit(YGUnitUndefined), value(0.0) {}
Value(int unit, double value) : unit(unit), value(value) {}
void toJS(nbind::cbOutput expose) const { expose(unit, value); }
Value(int unit, double value) : unit(unit), value(value) {}
};

View File

@@ -0,0 +1,188 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "./Node.hh"
#include "./Layout.hh"
#include "./Size.hh"
#include "./Value.hh"
#include "./Config.hh"
#include <yoga/Yoga.h>
#include <emscripten/bind.h>
using namespace emscripten;
EMSCRIPTEN_BINDINGS(YOGA_LAYOUT) {
class_<MeasureCallback>("MeasureCallback")
.function("measure", &MeasureCallback::measure, pure_virtual())
.allow_subclass<MeasureCallbackWrapper>("MeasureCallbackWrapper")
;
class_<DirtiedCallback>("DirtiedCallback")
.function("dirtied", &DirtiedCallback::dirtied, pure_virtual())
.allow_subclass<DirtiedCallbackWrapper>("DirtiedCallbackWrapper")
;
class_<Config>("Config")
.constructor<>(&Config::create, allow_raw_pointers())
.class_function<>("create", &Config::create, allow_raw_pointers())
.class_function<>("destroy", &Config::destroy, allow_raw_pointers())
.function("setExperimentalFeatureEnabled", &Config::setExperimentalFeatureEnabled)
.function("setPointScaleFactor", &Config::setPointScaleFactor)
.function("isExperimentalFeatureEnabled", &Config::isExperimentalFeatureEnabled)
;
value_object<Layout>("Layout")
.field("left", &Layout::left)
.field("right", &Layout::right)
.field("top", &Layout::top)
.field("bottom", &Layout::bottom)
.field("width", &Layout::width)
.field("height", &Layout::height)
;
value_object<Size>("Size")
.field("width", &Size::width)
.field("height", &Size::height)
;
value_object<Value>("Value")
.field("value", &Value::value)
.field("unit", &Value::unit)
;
class_<Node>("Node")
.constructor<>(&Node::createDefault, allow_raw_pointers())
.class_function<>("createDefault", &Node::createDefault, allow_raw_pointers())
.class_function<>("createWithConfig", &Node::createWithConfig, allow_raw_pointers())
.class_function<>("destroy", &Node::destroy, allow_raw_pointers())
.function("reset", &Node::reset)
.function("copyStyle", &Node::copyStyle)
.function("setPositionType", &Node::setPositionType)
.function("setPosition", &Node::setPosition)
.function("setPositionPercent", &Node::setPositionPercent)
.function("setAlignContent", &Node::setAlignContent)
.function("setAlignItems", &Node::setAlignItems)
.function("setAlignSelf", &Node::setAlignSelf)
.function("setFlexDirection", &Node::setFlexDirection)
.function("setFlexWrap", &Node::setFlexWrap)
.function("setJustifyContent", &Node::setJustifyContent)
.function("setMargin", &Node::setMargin)
.function("setMarginPercent", &Node::setMarginPercent)
.function("setMarginAuto", &Node::setMarginAuto)
.function("setOverflow", &Node::setOverflow)
.function("setDisplay", &Node::setDisplay)
.function("setFlex", &Node::setFlex)
.function("setFlexBasis", &Node::setFlexBasis)
.function("setFlexBasisPercent", &Node::setFlexBasisPercent)
.function("setFlexGrow", &Node::setFlexGrow)
.function("setFlexShrink", &Node::setFlexShrink)
.function("setWidth", &Node::setWidth)
.function("setWidthPercent", &Node::setWidthPercent)
.function("setWidthAuto", &Node::setWidthAuto)
.function("setHeight", &Node::setHeight)
.function("setHeightPercent", &Node::setHeightPercent)
.function("setHeightAuto", &Node::setHeightAuto)
.function("setMinWidth", &Node::setMinWidth)
.function("setMinWidthPercent", &Node::setMinWidthPercent)
.function("setMinHeight", &Node::setMinHeight)
.function("setMinHeightPercent", &Node::setMinHeightPercent)
.function("setMaxWidth", &Node::setMaxWidth)
.function("setMaxWidthPercent", &Node::setMaxWidthPercent)
.function("setMaxHeight", &Node::setMaxHeight)
.function("setMaxHeightPercent", &Node::setMaxHeightPercent)
.function("setAspectRatio", &Node::setAspectRatio)
.function("setBorder", &Node::setBorder)
.function("setPadding", &Node::setPadding)
.function("setPaddingPercent", &Node::setPaddingPercent)
.function("setGap", &Node::setGap)
.function("getPositionType", &Node::getPositionType)
.function("getPosition", &Node::getPosition)
.function("getAlignContent", &Node::getAlignContent)
.function("getAlignItems", &Node::getAlignItems)
.function("getAlignSelf", &Node::getAlignSelf)
.function("getFlexDirection", &Node::getFlexDirection)
.function("getFlexWrap", &Node::getFlexWrap)
.function("getJustifyContent", &Node::getJustifyContent)
.function("getMargin", &Node::getMargin)
.function("getFlexBasis", &Node::getFlexBasis)
.function("getFlexGrow", &Node::getFlexGrow)
.function("getFlexShrink", &Node::getFlexShrink)
.function("getWidth", &Node::getWidth)
.function("getHeight", &Node::getHeight)
.function("getMinWidth", &Node::getMinWidth)
.function("getMinHeight", &Node::getMinHeight)
.function("getMaxWidth", &Node::getMaxWidth)
.function("getMaxHeight", &Node::getMaxHeight)
.function("getAspectRatio", &Node::getAspectRatio)
.function("getBorder", &Node::getBorder)
.function("getOverflow", &Node::getOverflow)
.function("getDisplay", &Node::getDisplay)
.function("getPadding", &Node::getPadding)
.function("getGap", &Node::getGap)
.function("insertChild", &Node::insertChild, allow_raw_pointers())
.function("removeChild", &Node::removeChild, allow_raw_pointers())
.function("getChildCount", &Node::getChildCount)
.function("getParent", &Node::getParent, allow_raw_pointers())
.function("getChild", &Node::getChild, allow_raw_pointers())
.function("isReferenceBaseline", &Node::isReferenceBaseline)
.function("setIsReferenceBaseline", &Node::setIsReferenceBaseline)
.function("setMeasureFunc", &Node::setMeasureFunc, allow_raw_pointers())
.function("unsetMeasureFunc", &Node::unsetMeasureFunc)
.function("setDirtiedFunc", &Node::setDirtiedFunc, allow_raw_pointers())
.function("unsetDirtiedFunc", &Node::unsetDirtiedFunc)
.function("markDirty", &Node::markDirty)
.function("isDirty", &Node::isDirty)
.function("calculateLayout", &Node::calculateLayout)
.function("getComputedLeft", &Node::getComputedLeft)
.function("getComputedRight", &Node::getComputedRight)
.function("getComputedTop", &Node::getComputedTop)
.function("getComputedBottom", &Node::getComputedBottom)
.function("getComputedWidth", &Node::getComputedWidth)
.function("getComputedHeight", &Node::getComputedHeight)
.function("getComputedLayout", &Node::getComputedLayout)
.function("getComputedMargin", &Node::getComputedMargin)
.function("getComputedBorder", &Node::getComputedBorder)
.function("getComputedPadding", &Node::getComputedPadding)
;
}

View File

@@ -1,55 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
const Yoga = require('./entry-common');
const nbind = require('../build/Release/nbind.js');
let ran = false;
let ret = null;
nbind({}, function(err, result) {
if (ran) {
return;
}
ran = true;
if (err) {
throw err;
}
ret = result;
});
if (!ran) {
throw new Error(
"Failed to load the yoga module - it needed to be loaded synchronously, but didn't",
);
}
// $FlowFixMe ret will not be null here
module.exports = Yoga(ret.bind, ret.lib);
export type {
Yoga$Justify,
Yoga$Align,
Yoga$FlexDirection,
Yoga$Direction,
Yoga$Wrap,
Yoga$Gutter,
Yoga$Edge,
Yoga$Display,
Yoga$Unit,
Yoga$Overflow,
Yoga$PositionType,
Yoga$ExperimentalFeature,
} from './YGEnums.js';
export type {Yoga$Node, Yoga$Config} from './entry-common';

View File

@@ -234,7 +234,7 @@ type Yoga = {
...typeof CONSTANTS,
};
module.exports = (bind: any, lib: any): Yoga => {
module.exports = (lib: any): Yoga => {
function patch(prototype, name, fn) {
let original = prototype[name];
@@ -298,6 +298,22 @@ module.exports = (bind: any, lib: any): Yoga => {
});
}
function wrapMeasureFunction(measureFunction) {
return lib.MeasureCallback.implement({ measure: measureFunction })
}
patch(lib.Node.prototype, 'setMeasureFunc', function (original, measureFunc) {
original.call(this, wrapMeasureFunction(measureFunc))
})
function wrapDirtiedFunc(dirtiedFunction) {
return lib.DirtiedCallback.implement({ dirtied: dirtiedFunction })
}
patch(lib.Node.prototype, 'setDirtiedFunc', function (original, dirtiedFunc) {
original.call(this, wrapDirtiedFunc(dirtiedFunc))
})
patch(lib.Config.prototype, 'free', function() {
// Since we handle the memory allocation ourselves (via lib.Config.create),
// we also need to handle the deallocation
@@ -352,9 +368,9 @@ module.exports = (bind: any, lib: any): Yoga => {
return {
Config: lib.Config,
Node: lib.Node,
Layout: bind('Layout', Layout),
Size: bind('Size', Size),
Value: bind('Value', Value),
Layout: Layout,
Size: Size,
Value: Value,
...CONSTANTS,
};
};

View File

@@ -8,10 +8,12 @@
* @format
*/
const Yoga = require('./entry-common');
const nbind = require('nbind');
const {bind, lib} = nbind.init(__dirname + '/../');
module.exports = Yoga(bind, lib);
const entry = require('./entry');
const yoga = require('./asm');
// $FlowFixMe ret will not be null here
module.exports = entry(yoga());
export type {
Yoga$Justify,
Yoga$Align,
@@ -27,4 +29,4 @@ export type {
Yoga$ExperimentalFeature,
} from './YGEnums.js';
export type {Yoga$Node, Yoga$Config} from './entry-common';
export type {Yoga$Node, Yoga$Config} from './entry';

View File

@@ -1,175 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <yoga/Yoga.h>
#include "./Node.hh"
#include "./Layout.hh"
#include "./Size.hh"
#include "./Value.hh"
#include "./Config.hh"
#include <nbind/nbind.h>
NBIND_CLASS(Size) {
construct<>();
construct<double, double>();
}
NBIND_CLASS(Layout) {
construct<>();
}
NBIND_CLASS(Value) {
construct<>();
construct<int, double>();
}
NBIND_CLASS(Config) {
method(create);
method(destroy);
method(setExperimentalFeatureEnabled);
method(setPointScaleFactor);
method(isExperimentalFeatureEnabled);
}
NBIND_CLASS(Node) {
method(createDefault);
method(createWithConfig);
method(destroy);
method(reset);
method(copyStyle);
method(setPositionType);
method(setPosition);
method(setPositionPercent);
method(setAlignContent);
method(setAlignItems);
method(setAlignSelf);
method(setFlexDirection);
method(setFlexWrap);
method(setJustifyContent);
method(setMargin);
method(setMarginPercent);
method(setMarginAuto);
method(setOverflow);
method(setDisplay);
method(setFlex);
method(setFlexBasis);
method(setFlexBasisPercent);
method(setFlexBasisAuto);
method(setFlexGrow);
method(setFlexShrink);
method(setWidth);
method(setWidthPercent);
method(setWidthAuto);
method(setHeight);
method(setHeightPercent);
method(setHeightAuto);
method(setMinWidth);
method(setMinWidthPercent);
method(setMinHeight);
method(setMinHeightPercent);
method(setMaxWidth);
method(setMaxWidthPercent);
method(setMaxHeight);
method(setMaxHeightPercent);
method(setAspectRatio);
method(setBorder);
method(setPadding);
method(setPaddingPercent);
method(setGap);
method(getPositionType);
method(getPosition);
method(getAlignContent);
method(getAlignItems);
method(getAlignSelf);
method(getFlexDirection);
method(getFlexWrap);
method(getJustifyContent);
method(getMargin);
method(getFlexBasis);
method(getFlexGrow);
method(getFlexShrink);
method(getWidth);
method(getHeight);
method(getMinWidth);
method(getMinHeight);
method(getMaxWidth);
method(getMaxHeight);
method(getAspectRatio);
method(getBorder);
method(getOverflow);
method(getDisplay);
method(getPadding);
method(getGap);
method(insertChild);
method(removeChild);
method(getChildCount);
method(getParent);
method(getChild);
method(isReferenceBaseline);
method(setIsReferenceBaseline);
method(setMeasureFunc);
method(unsetMeasureFunc);
method(setDirtiedFunc);
method(unsetDirtiedFunc);
method(markDirty);
method(isDirty);
method(calculateLayout);
method(getComputedLeft);
method(getComputedRight);
method(getComputedTop);
method(getComputedBottom);
method(getComputedWidth);
method(getComputedHeight);
method(getComputedLayout);
method(getComputedMargin);
method(getComputedBorder);
method(getComputedPadding);
}