Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
/*
|
|
|
|
* 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 <memory>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <benchmark/TreeDeserialization.h>
|
|
|
|
#include <capture/CaptureTree.h>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#include <yoga/Yoga.h>
|
|
|
|
|
|
|
|
namespace facebook::yoga {
|
|
|
|
|
|
|
|
using namespace nlohmann;
|
|
|
|
|
|
|
|
static inline bool isAuto(json& j) {
|
|
|
|
return j.is_string() && j == "auto";
|
|
|
|
}
|
|
|
|
|
2024-04-05 14:01:54 -07:00
|
|
|
static inline bool isUndefined(json& j) {
|
|
|
|
return j.is_string() && j == "undefined";
|
|
|
|
}
|
|
|
|
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
static inline std::string invalidArgumentMessage(
|
2024-03-04 02:28:02 -08:00
|
|
|
const std::string& arg,
|
|
|
|
const std::string& enumName) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
return arg + " does not represent any " + enumName + " values";
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline float floatFromJson(json& j) {
|
|
|
|
float result = YGUndefined;
|
|
|
|
if (!j.is_null()) {
|
|
|
|
result = j;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGFlexDirection flexDirectionFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "row") {
|
|
|
|
return YGFlexDirectionRow;
|
|
|
|
} else if (str == "row-reverse") {
|
|
|
|
return YGFlexDirectionRowReverse;
|
|
|
|
} else if (str == "column") {
|
|
|
|
return YGFlexDirectionColumn;
|
|
|
|
} else if (str == "column-reverse") {
|
|
|
|
return YGFlexDirectionColumnReverse;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGFlexDirection"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGJustify justifyContentFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "flex-start") {
|
|
|
|
return YGJustifyFlexStart;
|
|
|
|
} else if (str == "center") {
|
|
|
|
return YGJustifyCenter;
|
|
|
|
} else if (str == "flex-end") {
|
|
|
|
return YGJustifyFlexEnd;
|
|
|
|
} else if (str == "space-between") {
|
|
|
|
return YGJustifySpaceBetween;
|
|
|
|
} else if (str == "space-around") {
|
|
|
|
return YGJustifySpaceAround;
|
|
|
|
} else if (str == "space-evenly") {
|
|
|
|
return YGJustifySpaceEvenly;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGJustify"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGAlign alignFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "auto") {
|
|
|
|
return YGAlignAuto;
|
|
|
|
} else if (str == "flex-start") {
|
|
|
|
return YGAlignFlexStart;
|
|
|
|
} else if (str == "center") {
|
|
|
|
return YGAlignCenter;
|
|
|
|
} else if (str == "flex-end") {
|
|
|
|
return YGAlignFlexEnd;
|
|
|
|
} else if (str == "stretch") {
|
|
|
|
return YGAlignStretch;
|
|
|
|
} else if (str == "baseline") {
|
|
|
|
return YGAlignBaseline;
|
|
|
|
} else if (str == "space-between") {
|
|
|
|
return YGAlignSpaceBetween;
|
|
|
|
} else if (str == "space-around") {
|
|
|
|
return YGAlignSpaceAround;
|
|
|
|
} else if (str == "space-evenly") {
|
|
|
|
return YGAlignSpaceEvenly;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGWrap wrapFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "no-wrap") {
|
|
|
|
return YGWrapNoWrap;
|
|
|
|
} else if (str == "wrap") {
|
|
|
|
return YGWrapWrap;
|
|
|
|
} else if (str == "wrap-reverse") {
|
|
|
|
return YGWrapWrapReverse;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGOverflow overflowFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "visible") {
|
|
|
|
return YGOverflowVisible;
|
|
|
|
} else if (str == "hidden") {
|
|
|
|
return YGOverflowHidden;
|
|
|
|
} else if (str == "scroll") {
|
|
|
|
return YGOverflowScroll;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGDisplay displayFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "flex") {
|
|
|
|
return YGDisplayFlex;
|
|
|
|
} else if (str == "none") {
|
|
|
|
return YGDisplayNone;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGPositionType positionTypeFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "static") {
|
|
|
|
return YGPositionTypeStatic;
|
|
|
|
} else if (str == "relative") {
|
|
|
|
return YGPositionTypeRelative;
|
|
|
|
} else if (str == "absolute") {
|
|
|
|
return YGPositionTypeAbsolute;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
YGUnit unitFromJson(json& j) {
|
|
|
|
if (isAuto(j)) {
|
|
|
|
return YGUnitAuto;
|
|
|
|
}
|
2024-04-05 14:01:54 -07:00
|
|
|
if (isUndefined(j)) {
|
|
|
|
return YGUnitUndefined;
|
|
|
|
}
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
|
|
|
|
std::string unit = j["unit"];
|
|
|
|
if (unit == "px") {
|
|
|
|
return YGUnitPoint;
|
|
|
|
} else if (unit == "pct") {
|
|
|
|
return YGUnitPercent;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(unit, "YGUnit"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGEdge edgeFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "left") {
|
|
|
|
return YGEdgeLeft;
|
|
|
|
} else if (str == "top") {
|
|
|
|
return YGEdgeTop;
|
|
|
|
} else if (str == "right") {
|
|
|
|
return YGEdgeRight;
|
|
|
|
} else if (str == "bottom") {
|
|
|
|
return YGEdgeBottom;
|
|
|
|
} else if (str == "start") {
|
|
|
|
return YGEdgeStart;
|
|
|
|
} else if (str == "end") {
|
|
|
|
return YGEdgeEnd;
|
|
|
|
} else if (str == "horizontal") {
|
|
|
|
return YGEdgeHorizontal;
|
|
|
|
} else if (str == "vertical") {
|
|
|
|
return YGEdgeVertical;
|
|
|
|
} else if (str == "all") {
|
|
|
|
return YGEdgeAll;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGEdge"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGErrata errataFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "none") {
|
|
|
|
return YGErrataNone;
|
|
|
|
} else if (str == "all") {
|
|
|
|
return YGErrataAll;
|
|
|
|
} else if (str == "classic") {
|
|
|
|
return YGErrataClassic;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGErrata"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGExperimentalFeature experimentalFeatureFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "web-flex-basis") {
|
|
|
|
return YGExperimentalFeatureWebFlexBasis;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(
|
|
|
|
invalidArgumentMessage(str, "YGExperimentalFeature"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string edgeStringFromPropertyName(
|
2024-03-04 02:28:02 -08:00
|
|
|
const json::iterator& it,
|
|
|
|
const std::string& propertyName) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
return it.key().substr(propertyName.length() + 1);
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGDirection directionFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "ltr") {
|
|
|
|
return YGDirectionLTR;
|
|
|
|
} else if (str == "rtl") {
|
|
|
|
return YGDirectionRTL;
|
|
|
|
} else if (str == "inherit") {
|
|
|
|
return YGDirectionInherit;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGDirection"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGMeasureMode measureModeFromString(const std::string& str) {
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
if (str == "at-most") {
|
|
|
|
return YGMeasureModeAtMost;
|
|
|
|
} else if (str == "exactly") {
|
|
|
|
return YGMeasureModeExactly;
|
|
|
|
} else if (str == "undefined") {
|
|
|
|
return YGMeasureModeUndefined;
|
|
|
|
} else {
|
|
|
|
throw std::invalid_argument(invalidArgumentMessage(str, "YGMeasureMode"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-21 18:02:58 -08:00
|
|
|
SerializedMeasureFunc serializedMeasureFuncFromJson(json& j) {
|
|
|
|
return SerializedMeasureFunc{
|
|
|
|
floatFromJson(j["width"]),
|
|
|
|
measureModeFromString(j["width-mode"]),
|
|
|
|
floatFromJson(j["height"]),
|
|
|
|
measureModeFromString(j["height-mode"]),
|
|
|
|
floatFromJson(j["output-width"]),
|
|
|
|
floatFromJson(j["output-height"]),
|
|
|
|
j["duration-ns"]};
|
Support for (de)serializing measure funcs
Summary:
In addition to all the state that gets set on the node that is easy to serialize - like floats, enums, bools, etc - we also need to serialize measure functions. This is because these functions take a nontrivial amount of time up during layout and we should capture that. Also, they are important to the ability to truly replay layout as it was captured as the results of the measure functions determine many of the steps the layout algorithm takes.
Capturing this is rather tricky however, but I think I found a solution that is relatively simple and non-error prone. Essentially, since we are capturing the entire tree and virtually every input that goes into the flexbox algorithm, we *should* be able to replay layout exactly as it was captured. This means that the order in which measure functions are called *should* be the same. If this is the case, then all we need to do to capture the measure functions is store their input, output, and duration in a big array. During deserialization we just keep track of an index and use that to determine which measure function we should call. That is the premise behind what happens in this diff. In theory the algorithm could change and the capture would be wrong but it is easy enough to recapture again. Additionally we need to dirty the tree so that we get rid of caching which might omit some measure func calls
In order to capture you need to insert a method exposed by CaptureTree.h into the client measure func, which is kind of annoying but not that bad. In future diffs I will put a macro in place to make this even easier.
I also add our first capture! Which is of a large react native desktop app
Reviewed By: NickGerleman
Differential Revision: D53581121
fbshipit-source-id: 876a230208d67f0ecf76844a4f1b80048353aae2
2024-02-13 17:22:08 -08:00
|
|
|
}
|
|
|
|
} // namespace facebook::yoga
|