Extend Yoga to be able clone Yoga Node with new children
Reviewed By: emilsjolander Differential Revision: D7245421 fbshipit-source-id: 72578c8261f29e4a12fc6c72a91f2f891cd58d48
This commit is contained in:
Родитель
29ff30c539
Коммит
5be4ff0261
|
@ -30,7 +30,7 @@ public class YogaNode implements Cloneable {
|
||||||
static native int jni_YGNodeGetInstanceCount();
|
static native int jni_YGNodeGetInstanceCount();
|
||||||
|
|
||||||
private YogaNode mOwner;
|
private YogaNode mOwner;
|
||||||
private List<YogaNode> mChildren;
|
@Nullable private List<YogaNode> mChildren;
|
||||||
private YogaMeasureFunction mMeasureFunction;
|
private YogaMeasureFunction mMeasureFunction;
|
||||||
private YogaBaselineFunction mBaselineFunction;
|
private YogaBaselineFunction mBaselineFunction;
|
||||||
private long mNativePointer;
|
private long mNativePointer;
|
||||||
|
@ -147,6 +147,9 @@ public class YogaNode implements Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public YogaNode getChildAt(int i) {
|
public YogaNode getChildAt(int i) {
|
||||||
|
if (mChildren == null) {
|
||||||
|
throw new IllegalStateException("YogaNode does not have children");
|
||||||
|
}
|
||||||
return mChildren.get(i);
|
return mChildren.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,21 +167,62 @@ public class YogaNode implements Cloneable {
|
||||||
jni_YGNodeInsertChild(mNativePointer, child.mNativePointer, i);
|
jni_YGNodeInsertChild(mNativePointer, child.mNativePointer, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native void jni_YGNodeInsertSharedChild(long nativePointer, long childPointer, int index);
|
||||||
|
|
||||||
|
public void addSharedChildAt(YogaNode child, int i) {
|
||||||
|
if (mChildren == null) {
|
||||||
|
mChildren = new ArrayList<>(4);
|
||||||
|
}
|
||||||
|
mChildren.add(i, child);
|
||||||
|
child.mOwner = null;
|
||||||
|
jni_YGNodeInsertSharedChild(mNativePointer, child.mNativePointer, i);
|
||||||
|
}
|
||||||
|
|
||||||
private native long jni_YGNodeClone(long nativePointer, Object newNode);
|
private native long jni_YGNodeClone(long nativePointer, Object newNode);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YogaNode clone() throws CloneNotSupportedException {
|
public YogaNode clone() {
|
||||||
YogaNode clonedYogaNode = (YogaNode) super.clone();
|
try {
|
||||||
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode);
|
YogaNode clonedYogaNode = (YogaNode) super.clone();
|
||||||
clonedYogaNode.mNativePointer = clonedNativePointer;
|
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode);
|
||||||
clonedYogaNode.mChildren =
|
clonedYogaNode.mNativePointer = clonedNativePointer;
|
||||||
mChildren != null ? (List<YogaNode>) ((ArrayList) mChildren).clone() : null;
|
clonedYogaNode.mOwner = null;
|
||||||
return clonedYogaNode;
|
clonedYogaNode.mChildren =
|
||||||
|
mChildren != null ? (List<YogaNode>) ((ArrayList) mChildren).clone() : null;
|
||||||
|
return clonedYogaNode;
|
||||||
|
} catch (CloneNotSupportedException ex) {
|
||||||
|
// This class implements Cloneable, this should not happen
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public YogaNode cloneWithNewChildren() {
|
||||||
|
try {
|
||||||
|
YogaNode clonedYogaNode = (YogaNode) super.clone();
|
||||||
|
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode);
|
||||||
|
clonedYogaNode.mOwner = null;
|
||||||
|
clonedYogaNode.mNativePointer = clonedNativePointer;
|
||||||
|
clonedYogaNode.clearChildren();
|
||||||
|
return clonedYogaNode;
|
||||||
|
} catch (CloneNotSupportedException ex) {
|
||||||
|
// This class implements Cloneable, this should not happen
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native void jni_YGNodeClearChildren(long nativePointer);
|
||||||
|
|
||||||
|
private void clearChildren() {
|
||||||
|
mChildren = null;
|
||||||
|
jni_YGNodeClearChildren(mNativePointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private native void jni_YGNodeRemoveChild(long nativePointer, long childPointer);
|
private native void jni_YGNodeRemoveChild(long nativePointer, long childPointer);
|
||||||
public YogaNode removeChildAt(int i) {
|
public YogaNode removeChildAt(int i) {
|
||||||
|
if (mChildren == null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Trying to remove a child of a YogaNode that does not have children");
|
||||||
|
}
|
||||||
final YogaNode child = mChildren.remove(i);
|
final YogaNode child = mChildren.remove(i);
|
||||||
child.mOwner = null;
|
child.mOwner = null;
|
||||||
jni_YGNodeRemoveChild(mNativePointer, child.mNativePointer);
|
jni_YGNodeRemoveChild(mNativePointer, child.mNativePointer);
|
||||||
|
@ -715,8 +759,12 @@ public class YogaNode implements Cloneable {
|
||||||
*/
|
*/
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
private final long replaceChild(YogaNode newNode, int childIndex) {
|
private final long replaceChild(YogaNode newNode, int childIndex) {
|
||||||
|
if (mChildren == null) {
|
||||||
|
throw new IllegalStateException("Cannot replace child. YogaNode does not have children");
|
||||||
|
}
|
||||||
mChildren.remove(childIndex);
|
mChildren.remove(childIndex);
|
||||||
mChildren.add(childIndex, newNode);
|
mChildren.add(childIndex, newNode);
|
||||||
|
newNode.mOwner = this;
|
||||||
return newNode.mNativePointer;
|
return newNode.mNativePointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,6 +284,11 @@ void jni_YGNodeFree(alias_ref<jobject> thiz, jlong nativePointer) {
|
||||||
YGNodeFree(node);
|
YGNodeFree(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jni_YGNodeClearChildren(alias_ref<jobject> thiz, jlong nativePointer) {
|
||||||
|
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
|
||||||
|
node->clearChildren();
|
||||||
|
}
|
||||||
|
|
||||||
void jni_YGNodeReset(alias_ref<jobject> thiz, jlong nativePointer) {
|
void jni_YGNodeReset(alias_ref<jobject> thiz, jlong nativePointer) {
|
||||||
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
|
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
|
||||||
void* context = node->getContext();
|
void* context = node->getContext();
|
||||||
|
@ -303,6 +308,15 @@ void jni_YGNodeInsertChild(alias_ref<jobject>, jlong nativePointer, jlong childP
|
||||||
YGNodeInsertChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index);
|
YGNodeInsertChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jni_YGNodeInsertSharedChild(
|
||||||
|
alias_ref<jobject>,
|
||||||
|
jlong nativePointer,
|
||||||
|
jlong childPointer,
|
||||||
|
jint index) {
|
||||||
|
YGNodeInsertSharedChild(
|
||||||
|
_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index);
|
||||||
|
}
|
||||||
|
|
||||||
void jni_YGNodeRemoveChild(alias_ref<jobject>, jlong nativePointer, jlong childPointer) {
|
void jni_YGNodeRemoveChild(alias_ref<jobject>, jlong nativePointer, jlong childPointer) {
|
||||||
YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer));
|
YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer));
|
||||||
}
|
}
|
||||||
|
@ -577,7 +591,9 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
YGMakeNativeMethod(jni_YGNodeNewWithConfig),
|
YGMakeNativeMethod(jni_YGNodeNewWithConfig),
|
||||||
YGMakeNativeMethod(jni_YGNodeFree),
|
YGMakeNativeMethod(jni_YGNodeFree),
|
||||||
YGMakeNativeMethod(jni_YGNodeReset),
|
YGMakeNativeMethod(jni_YGNodeReset),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeClearChildren),
|
||||||
YGMakeNativeMethod(jni_YGNodeInsertChild),
|
YGMakeNativeMethod(jni_YGNodeInsertChild),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeInsertSharedChild),
|
||||||
YGMakeNativeMethod(jni_YGNodeRemoveChild),
|
YGMakeNativeMethod(jni_YGNodeRemoveChild),
|
||||||
YGMakeNativeMethod(jni_YGNodeCalculateLayout),
|
YGMakeNativeMethod(jni_YGNodeCalculateLayout),
|
||||||
YGMakeNativeMethod(jni_YGNodeMarkDirty),
|
YGMakeNativeMethod(jni_YGNodeMarkDirty),
|
||||||
|
|
|
@ -389,10 +389,6 @@ void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) {
|
void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) {
|
||||||
YGAssertWithNode(
|
|
||||||
node,
|
|
||||||
child->getOwner() == nullptr,
|
|
||||||
"Child already has a owner, it must be removed first.");
|
|
||||||
YGAssertWithNode(
|
YGAssertWithNode(
|
||||||
node,
|
node,
|
||||||
node->getMeasure() == nullptr,
|
node->getMeasure() == nullptr,
|
||||||
|
@ -400,7 +396,22 @@ void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32
|
||||||
|
|
||||||
node->cloneChildrenIfNeeded();
|
node->cloneChildrenIfNeeded();
|
||||||
node->insertChild(child, index);
|
node->insertChild(child, index);
|
||||||
child->setOwner(node);
|
YGNodeRef owner = child->getOwner() ? nullptr : node;
|
||||||
|
child->setOwner(owner);
|
||||||
|
node->markDirtyAndPropogate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNodeInsertSharedChild(
|
||||||
|
const YGNodeRef node,
|
||||||
|
const YGNodeRef child,
|
||||||
|
const uint32_t index) {
|
||||||
|
YGAssertWithNode(
|
||||||
|
node,
|
||||||
|
node->getMeasure() == nullptr,
|
||||||
|
"Cannot add child: Nodes with measure functions cannot have children.");
|
||||||
|
|
||||||
|
node->insertChild(child, index);
|
||||||
|
child->setOwner(nullptr);
|
||||||
node->markDirtyAndPropogate();
|
node->markDirtyAndPropogate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,8 @@ typedef int (*YGLogger)(const YGConfigRef config,
|
||||||
YGLogLevel level,
|
YGLogLevel level,
|
||||||
const char *format,
|
const char *format,
|
||||||
va_list args);
|
va_list args);
|
||||||
typedef YGNodeRef (*YGCloneNodeFunc)(YGNodeRef oldNode,
|
typedef YGNodeRef (
|
||||||
YGNodeRef parent,
|
*YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex);
|
||||||
int childIndex);
|
|
||||||
|
|
||||||
// YGNode
|
// YGNode
|
||||||
WIN_EXPORT YGNodeRef YGNodeNew(void);
|
WIN_EXPORT YGNodeRef YGNodeNew(void);
|
||||||
|
@ -78,12 +77,26 @@ WIN_EXPORT int32_t YGNodeGetInstanceCount(void);
|
||||||
WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node,
|
WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node,
|
||||||
const YGNodeRef child,
|
const YGNodeRef child,
|
||||||
const uint32_t index);
|
const uint32_t index);
|
||||||
|
|
||||||
|
// This function inserts the child YGNodeRef as a children of the node received
|
||||||
|
// by parameter and set the Owner of the child object to null. This function is
|
||||||
|
// expected to be called when using Yoga in persistent mode in order to share a
|
||||||
|
// YGNodeRef object as a child of two different Yoga trees. The child YGNodeRef
|
||||||
|
// is expected to be referenced from its original owner and from a clone of its
|
||||||
|
// original owner.
|
||||||
|
WIN_EXPORT void YGNodeInsertSharedChild(
|
||||||
|
const YGNodeRef node,
|
||||||
|
const YGNodeRef child,
|
||||||
|
const uint32_t index);
|
||||||
WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child);
|
WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child);
|
||||||
WIN_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef node);
|
WIN_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef node);
|
||||||
WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index);
|
WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index);
|
||||||
WIN_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node);
|
WIN_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node);
|
||||||
WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node);
|
WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node);
|
||||||
WIN_EXPORT void YGNodeSetChildren(YGNodeRef const parent, const YGNodeRef children[], const uint32_t count);
|
WIN_EXPORT void YGNodeSetChildren(
|
||||||
|
YGNodeRef const owner,
|
||||||
|
const YGNodeRef children[],
|
||||||
|
const uint32_t count);
|
||||||
|
|
||||||
WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node,
|
WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node,
|
||||||
const float availableWidth,
|
const float availableWidth,
|
||||||
|
@ -307,6 +320,8 @@ YG_EXTERN_C_END
|
||||||
// Calls f on each node in the tree including the given node argument.
|
// Calls f on each node in the tree including the given node argument.
|
||||||
extern void YGTraversePreOrder(YGNodeRef const node, std::function<void(YGNodeRef node)>&& f);
|
extern void YGTraversePreOrder(YGNodeRef const node, std::function<void(YGNodeRef node)>&& f);
|
||||||
|
|
||||||
extern void YGNodeSetChildren(YGNodeRef const parent, const std::vector<YGNodeRef> &children);
|
extern void YGNodeSetChildren(
|
||||||
|
YGNodeRef const owner,
|
||||||
|
const std::vector<YGNodeRef>& children);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче