Add memory allocation interface

This commit is contained in:
KitsuneAlex
2022-01-31 19:34:42 +01:00
parent bd95b3d243
commit fffa5856de
2 changed files with 63 additions and 9 deletions

View File

@@ -106,6 +106,35 @@ static int YGDefaultLog(
#undef YG_UNUSED
#endif
static YGAllocatorAllocateFunc gAllocatorAllocateFunc = &malloc;
static YGAllocatorFreeFunc gAllocatorFreeFunc = &free;
YOGA_EXPORT void YGSetAllocationCallbacks(
YGAllocatorAllocateFunc allocFunc,
YGAllocatorFreeFunc freeFunc) {
gAllocatorAllocateFunc = allocFunc;
gAllocatorFreeFunc = freeFunc;
}
YOGA_EXPORT void YGGetAllocationCallbacks(
YGAllocatorAllocateFunc* allocFunc,
YGAllocatorFreeFunc* freeFunc) {
if(allocFunc != nullptr) {
*allocFunc = gAllocatorAllocateFunc;
}
if(freeFunc != nullptr) {
*freeFunc = gAllocatorFreeFunc;
}
}
YOGA_EXPORT void* YGMemoryAllocate(size_t size) {
return gAllocatorAllocateFunc(size);
}
YOGA_EXPORT void YGMemoryFree(void* memory) {
gAllocatorFreeFunc(memory);
}
static inline bool YGDoubleIsUndefined(const double value) {
return facebook::yoga::isUndefined(value);
}
@@ -192,7 +221,7 @@ YOGA_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(
int32_t gConfigInstanceCount = 0;
YOGA_EXPORT WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
const YGNodeRef node = new YGNode{config};
const YGNodeRef node = YGAllocate<YGNode>(config);
YGAssertWithConfig(
config, node != nullptr, "Could not allocate memory for node");
Event::publish<Event::NodeAllocation>(node, {config});
@@ -210,7 +239,7 @@ YOGA_EXPORT YGNodeRef YGNodeNew(void) {
}
YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) {
YGNodeRef node = new YGNode(*oldNode);
YGNodeRef node = YGAllocate<YGNode>(*oldNode);
YGAssertWithConfig(
oldNode->getConfig(),
node != nullptr,
@@ -221,7 +250,7 @@ YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) {
}
static YGConfigRef YGConfigClone(const YGConfig& oldConfig) {
const YGConfigRef config = new YGConfig(oldConfig);
const YGConfigRef config = YGAllocate<YGConfig>(oldConfig);
YGAssert(config != nullptr, "Could not allocate memory for config");
gConfigInstanceCount++;
return config;
@@ -229,7 +258,7 @@ static YGConfigRef YGConfigClone(const YGConfig& oldConfig) {
static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) {
auto config = YGConfigClone(*oldNode->getConfig());
auto node = new YGNode{*oldNode, config};
auto node = YGAllocate<YGNode>(*oldNode, config);
node->setOwner(nullptr);
Event::publish<Event::NodeAllocation>(node, {node->getConfig()});
@@ -260,13 +289,13 @@ YOGA_EXPORT void YGNodeFree(const YGNodeRef node) {
node->clearChildren();
Event::publish<Event::NodeDeallocation>(node, {node->getConfig()});
delete node;
YGFree(node);
}
static void YGConfigFreeRecursive(const YGNodeRef root) {
if (root->getConfig() != nullptr) {
gConfigInstanceCount--;
delete root->getConfig();
YGFree(root->getConfig());
}
// Delete configs recursively for childrens
for (auto* child : root->getChildren()) {
@@ -308,16 +337,16 @@ int32_t YGConfigGetInstanceCount(void) {
YOGA_EXPORT YGConfigRef YGConfigNew(void) {
#ifdef ANDROID
const YGConfigRef config = new YGConfig(YGAndroidLog);
const YGConfigRef config = YGAllocate<YGConfig>(YGAndroidLog);
#else
const YGConfigRef config = new YGConfig(YGDefaultLog);
const YGConfigRef config = YGAllocate<YGConfig>(YGDefaultLog);
#endif
gConfigInstanceCount++;
return config;
}
YOGA_EXPORT void YGConfigFree(const YGConfigRef config) {
delete config;
YGFree(config);
gConfigInstanceCount--;
}

View File

@@ -29,6 +29,9 @@ typedef struct YGSize {
float height;
} YGSize;
typedef void* (*YGAllocatorAllocateFunc)(size_t size);
typedef void (*YGAllocatorFreeFunc)(void* memory);
typedef struct YGConfig* YGConfigRef;
typedef struct YGNode* YGNodeRef;
@@ -53,6 +56,13 @@ typedef int (*YGLogger)(
typedef YGNodeRef (
*YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex);
// Memory allocation
WIN_EXPORT void YGSetAllocationCallbacks(YGAllocatorAllocateFunc allocFunc, YGAllocatorFreeFunc freeFunc);
WIN_EXPORT void YGGetAllocationCallbacks(YGAllocatorAllocateFunc* allocFunc, YGAllocatorFreeFunc* freeFunc);
WIN_EXPORT void* YGMemoryAllocate(size_t size);
WIN_EXPORT void YGMemoryFree(void* memory);
// YGNode
WIN_EXPORT YGNodeRef YGNodeNew(void);
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(YGConfigRef config);
@@ -363,6 +373,21 @@ YG_EXTERN_C_END
#include <functional>
#include <vector>
#include <type_traits>
// Templated delegates for YGMemoryAllocate & YGMemoryFree, so we don't have to
// cast nor pass in the size of the allocated chunk of memory explicitly.
template<typename T, typename... A>
T* YGAllocate(A&&... arguments) {
auto* memory = reinterpret_cast<T*>(YGMemoryAllocate(sizeof(T)));
new(memory) T(std::forward<A>(arguments)...);
return memory;
}
template<typename T>
void YGFree(T* memory) {
memory->~T();
YGMemoryFree(memory);
}
// Calls f on each node in the tree including the given node argument.
void YGTraversePreOrder(