Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/cpp/marshal/Definitions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,21 @@ namespace cpp
T& operator[] (int64_t index) const;
};

class RootHandle
{
::hx::Object** object;

RootHandle(hx::Object** obj);

public:
static RootHandle create(Dynamic obj);
static RootHandle fromVoidPointer(::cpp::Pointer<void> ptr);

::cpp::Pointer<void> toVoidPointer();
Dynamic getObject();
void close();
};

struct Marshal final
{
#ifdef HXCPP_BIG_ENDIAN
Expand Down
46 changes: 46 additions & 0 deletions include/cpp/marshal/RootHandle.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include "Definitions.inc"

inline cpp::marshal::RootHandle::RootHandle(::hx::Object** obj) : object(obj) {}

inline cpp::marshal::RootHandle cpp::marshal::RootHandle::create(::Dynamic obj)
{
if (null() == obj)
{
hx::NullReference("Dynamic", false);
}

auto root = new hx::Object* { obj.mPtr };

hx::GCAddRoot(root);

return RootHandle(root);
}

inline cpp::marshal::RootHandle cpp::marshal::RootHandle::fromVoidPointer(cpp::Pointer<void> ptr)
{
if (nullptr == ptr.ptr)
{
hx::NullReference("Dynamic", false);
}

return RootHandle(static_cast<hx::Object**>(ptr.ptr));
}

inline void cpp::marshal::RootHandle::close()
{
hx::GCRemoveRoot(object);

delete object;
}

inline ::Dynamic cpp::marshal::RootHandle::getObject()
{
return ::Dynamic{ *object };
}

inline cpp::Pointer<void> cpp::marshal::RootHandle::toVoidPointer()
{
return object;
}
1 change: 1 addition & 0 deletions include/hxcpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ typedef PropertyAccessMode PropertyAccess;
#include <cpp/marshal/PointerReference.hpp>
#include <cpp/marshal/View.hpp>
#include <cpp/marshal/Marshal.hpp>
#include <cpp/marshal/RootHandle.hpp>
#include <cpp/encoding/Ascii.hpp>
#include <cpp/encoding/Utf8.hpp>
#include <cpp/encoding/Utf16.hpp>
Expand Down
2 changes: 2 additions & 0 deletions test/native/Native.hx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class Native
new tests.marshalling.view.TestMarshal(),
new tests.marshalling.view.TestViewExtensions(),

new tests.marshalling.root.TestRoot(),

new tests.encoding.TestAscii(),
new tests.encoding.TestUtf8(),
new tests.encoding.TestUtf16(),
Expand Down
34 changes: 34 additions & 0 deletions test/native/tests/marshalling/root/TestRoot.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package tests.marshalling.root;

import cpp.marshal.RootHandle;
import utest.Assert;
import utest.Test;

class TestRoot extends Test {
function test_null_object() {
Assert.raises(() -> RootHandle.create(null));
}

function test_null_void_pointer() {
Assert.raises(() -> RootHandle.fromVoidPointer(null));
}

function test_get_object() {
final obj = "Hello, World!";
final handle = RootHandle.create(obj);

Assert.equals(obj, handle.getObject());

handle.close();
}

function test_void_pointer_roundtrip() {
final obj = "Hello, World!";
final ptr = RootHandle.create(obj).toVoidPointer();
final handle = RootHandle.fromVoidPointer(ptr);

Assert.equals(obj, handle.getObject());

handle.close();
}
}
Loading