Persistent Yoga
Summary: This is meant to show a possible route format for a persistent form of Yoga. Where previous layouts can remain intact while still taking advantage of incremental layout by reusing previous subtrees. ```c YGNodeRef YGNodeClone(const YGNodeRef node); ``` The core of this functionality is a new API to clone an existing node. This makes a new detached node with all the same values as the previous one. Conceptually this makes the original node "frozen" from that point on. It's now immutable. (This is not yet enforced at runtime in this PR but something we should add.) Since the original is frozen, we reuse the children set from the original node. Their parent pointers still point back to the original tree though. The cloned node is still mutable. It can have its styles updated, and nodes can be inserted or deleted. If an insertion/deletion happens on a cloned node whose children were reused, it'll first shallow clone its children automatically. As a convenience I also added an API to clear all children: ```c void YGNodeRemoveAllChildren(const YGNodeRef node); ``` During insert/delete, or as a result of layout a set of reused children may need to be first cloned. A kind of copy-on-write. When that happens, the host may want to respond. E.g. by updating the `context` such as by cloning any wrapper objects and attaching them to the new node. ```c typedef void (*YGNodeClonedFunc)(YGNodeRef oldNode, YGNodeRef newNode, YGNodeRef parent, int childIndex); void YGConfigSetNodeClonedFunc(YGConfigRef config, YGNodeClonedFunc callback); ``` This PR doesn't change any existing semantics for trees that are not first cloned. It's possible for a single node to exist in two trees at once and be used by multiple threads. Therefore it's not safe to recursively free a whole tree when you use persistence. To solve this, any user of the library has to manually manage ref counting or tracing GC. E.g. by replicating the tree structure in a wrapper. In a follow up we could consider moving ref counting into Yoga. Closes https://github.com/facebook/yoga/pull/636 Reviewed By: emilsjolander Differential Revision: D5941921 Pulled By: sebmarkbage fbshipit-source-id: c8e93421824c112d09c4773bed4e3141b6491ccf
This commit is contained in:
committed by
Facebook Github Bot
parent
be94a5ef8d
commit
4785e95a0c
@@ -60,6 +60,10 @@ typedef int (*YGLogger)(const YGConfigRef config,
|
||||
YGLogLevel level,
|
||||
const char *format,
|
||||
va_list args);
|
||||
typedef void (*YGNodeClonedFunc)(YGNodeRef oldNode,
|
||||
YGNodeRef newNode,
|
||||
YGNodeRef parent,
|
||||
int childIndex);
|
||||
|
||||
typedef void *(*YGMalloc)(size_t size);
|
||||
typedef void *(*YGCalloc)(size_t count, size_t size);
|
||||
@@ -69,6 +73,7 @@ typedef void (*YGFree)(void *ptr);
|
||||
// YGNode
|
||||
WIN_EXPORT YGNodeRef YGNodeNew(void);
|
||||
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config);
|
||||
WIN_EXPORT YGNodeRef YGNodeClone(const YGNodeRef node);
|
||||
WIN_EXPORT void YGNodeFree(const YGNodeRef node);
|
||||
WIN_EXPORT void YGNodeFreeRecursive(const YGNodeRef node);
|
||||
WIN_EXPORT void YGNodeReset(const YGNodeRef node);
|
||||
@@ -78,6 +83,7 @@ WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node,
|
||||
const YGNodeRef child,
|
||||
const uint32_t index);
|
||||
WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child);
|
||||
WIN_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef node);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node);
|
||||
WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node);
|
||||
@@ -264,6 +270,9 @@ WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config,
|
||||
WIN_EXPORT void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled);
|
||||
WIN_EXPORT bool YGConfigGetUseWebDefaults(const YGConfigRef config);
|
||||
|
||||
WIN_EXPORT void YGConfigSetNodeClonedFunc(const YGConfigRef config,
|
||||
const YGNodeClonedFunc callback);
|
||||
|
||||
// Export only for C#
|
||||
WIN_EXPORT YGConfigRef YGConfigGetDefault(void);
|
||||
|
||||
|
Reference in New Issue
Block a user