Skip to content

Commit

Permalink
feat: add msg clone api (#657)
Browse files Browse the repository at this point in the history
* feat: add msg clone api

* feat: add more test cases

* fix: fix memory leak

* fix: fix test case

* fix: refine codes

* fix: refine codes

* fix: refine codes

---------

Co-authored-by: Hu Yueh-Wei <[email protected]>
  • Loading branch information
sunxilin and halajohn authored Feb 6, 2025
1 parent d0e2d3a commit c37ffb5
Show file tree
Hide file tree
Showing 57 changed files with 1,671 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"request": "launch",
"program": "${workspaceFolder}/out/linux/x64/tests/standalone/ten_runtime_unit_test",
"args": [
"--gtest_filter=TenErrorTest.cpp_thread"
"--gtest_filter=TenMsgTest.AudioFrameClone"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/out/linux/x64/",
Expand Down
14 changes: 14 additions & 0 deletions core/include/ten_runtime/binding/cpp/detail/msg/audio_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,20 @@ class audio_frame_t : public msg_t {

~audio_frame_t() override = default;

std::unique_ptr<audio_frame_t> clone() const {
if (c_msg == nullptr) {
TEN_ASSERT(0, "Should not happen.");
return nullptr;
}

ten_shared_ptr_t *cloned_msg = ten_msg_clone(c_msg, nullptr);
if (cloned_msg == nullptr) {
return nullptr;
}

return std::make_unique<audio_frame_t>(cloned_msg, ctor_passkey_t());
}

int64_t get_timestamp(error_t *err = nullptr) const {
return ten_audio_frame_get_timestamp(c_msg);
}
Expand Down
22 changes: 14 additions & 8 deletions core/include/ten_runtime/binding/cpp/detail/msg/cmd/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ class cmd_t : public msg_t {
cmd_t &operator=(cmd_t &&cmd) noexcept = delete;
// @}

std::unique_ptr<cmd_t> clone() const {
if (c_msg == nullptr) {
TEN_ASSERT(0, "Should not happen.");
return nullptr;
}

ten_shared_ptr_t *cloned_msg = ten_msg_clone(c_msg, nullptr);
if (cloned_msg == nullptr) {
return nullptr;
}

return std::make_unique<cmd_t>(cloned_msg, ctor_passkey_t());
}

protected:
// @{
// Used by the constructor of the real command class to create a base command
Expand All @@ -65,14 +79,6 @@ class cmd_t : public msg_t {
friend extension_tester_t;
friend ten_env_t;

void clone_internal(const cmd_t &cmd) noexcept {
if (cmd.c_msg != nullptr) {
c_msg = ten_msg_clone(cmd.c_msg, nullptr);
} else {
c_msg = nullptr;
}
}

static std::unique_ptr<cmd_t> create(ten_shared_ptr_t *cmd,
error_t *err = nullptr) {
return std::make_unique<cmd_t>(cmd, ctor_passkey_t());
Expand Down
14 changes: 14 additions & 0 deletions core/include/ten_runtime/binding/cpp/detail/msg/cmd_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ class cmd_result_t : public msg_t {
c_msg, final, err != nullptr ? err->get_c_error() : nullptr);
}

std::unique_ptr<cmd_result_t> clone() const {
if (c_msg == nullptr) {
TEN_ASSERT(0, "Should not happen.");
return nullptr;
}

ten_shared_ptr_t *cloned_msg = ten_msg_clone(c_msg, nullptr);
if (cloned_msg == nullptr) {
return nullptr;
}

return std::make_unique<cmd_result_t>(cloned_msg, ctor_passkey_t());
}

// @{
cmd_result_t(cmd_result_t &other) = delete;
cmd_result_t(cmd_result_t &&other) = delete;
Expand Down
14 changes: 14 additions & 0 deletions core/include/ten_runtime/binding/cpp/detail/msg/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ class data_t : public msg_t {

~data_t() override = default;

std::unique_ptr<data_t> clone() const {
if (c_msg == nullptr) {
TEN_ASSERT(0, "Should not happen.");
return nullptr;
}

ten_shared_ptr_t *cloned_msg = ten_msg_clone(c_msg, nullptr);
if (cloned_msg == nullptr) {
return nullptr;
}

return std::make_unique<data_t>(cloned_msg, ctor_passkey_t());
}

bool alloc_buf(size_t size, error_t *err = nullptr) {
return ten_data_alloc_buf(c_msg, size) != nullptr;
}
Expand Down
14 changes: 14 additions & 0 deletions core/include/ten_runtime/binding/cpp/detail/msg/video_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ class video_frame_t : public msg_t {

~video_frame_t() override = default;

std::unique_ptr<video_frame_t> clone() const {
if (c_msg == nullptr) {
TEN_ASSERT(0, "Should not happen.");
return nullptr;
}

ten_shared_ptr_t *cloned_msg = ten_msg_clone(c_msg, nullptr);
if (cloned_msg == nullptr) {
return nullptr;
}

return std::make_unique<video_frame_t>(cloned_msg, ctor_passkey_t());
}

int32_t get_width(error_t *err = nullptr) const {
return ten_video_frame_get_width(c_msg);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,6 @@ TEN_RUNTIME_PRIVATE_API PyObject *ten_py_audio_frame_is_eof(PyObject *self,

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_audio_frame_set_eof(PyObject *self,
PyObject *args);

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_audio_frame_clone(PyObject *self,
PyObject *args);
3 changes: 3 additions & 0 deletions core/include_internal/ten_runtime/binding/python/msg/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ TEN_RUNTIME_PRIVATE_API PyObject *ten_py_cmd_create(PyTypeObject *type,
PyObject *kw);

TEN_RUNTIME_PRIVATE_API void ten_py_cmd_destroy(PyObject *self);

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_cmd_clone(PyObject *self,
PyObject *args);
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ TEN_RUNTIME_PRIVATE_API PyObject *ten_py_cmd_result_is_final(PyObject *self,

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_cmd_result_is_completed(
PyObject *self, PyObject *args);

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_cmd_result_clone(PyObject *self,
PyObject *args);
3 changes: 3 additions & 0 deletions core/include_internal/ten_runtime/binding/python/msg/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ TEN_RUNTIME_PRIVATE_API PyObject *ten_py_data_unlock_buf(PyObject *self,

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_data_get_buf(PyObject *self,
PyObject *args);

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_data_clone(PyObject *self,
PyObject *args);
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,6 @@ TEN_RUNTIME_PRIVATE_API PyObject *ten_py_video_frame_get_pixel_fmt(

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_video_frame_set_pixel_fmt(
PyObject *self, PyObject *args);

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_video_frame_clone(PyObject *self,
PyObject *args);
27 changes: 27 additions & 0 deletions core/src/ten_runtime/binding/go/interface/ten/audio_frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import "C"

import "unsafe"

// AudioFrameDataFmt is the audio frame data format.
type AudioFrameDataFmt int32

// AudioFrameDataFmt values. These definitions need to be the same as the
Expand All @@ -30,9 +31,12 @@ const (
AudioFrameDataFmtNonInterleave
)

// AudioFrame is the interface for the audio frame.
type AudioFrame interface {
Msg

Clone() (AudioFrame, error)

AllocBuf(size int) error
LockBuf() ([]byte, error)
UnlockBuf(buf *[]byte) error
Expand Down Expand Up @@ -76,6 +80,7 @@ func newAudioFrame(bridge C.uintptr_t) *audioFrame {

var _ AudioFrame = new(audioFrame)

// NewAudioFrame creates a new audio frame.
func NewAudioFrame(audioFrameName string) (AudioFrame, error) {
if len(audioFrameName) == 0 {
return nil, newTenError(
Expand Down Expand Up @@ -444,3 +449,25 @@ func (p *audioFrame) SetEOF(isEOF bool) error {
return withCGoError(&apiStatus)
})
}

func (p *audioFrame) Clone() (AudioFrame, error) {
var bridge C.uintptr_t
err := withCGOLimiter(func() error {
apiStatus := C.ten_go_audio_frame_clone(p.getCPtr(), &bridge)
return withCGoError(&apiStatus)
})

if err != nil {
return nil, err
}

if bridge == 0 {
// Should not happen.
return nil, newTenError(
ErrorCodeInvalidArgument,
"bridge is nil",
)
}

return newAudioFrame(bridge), nil
}
3 changes: 3 additions & 0 deletions core/src/ten_runtime/binding/go/interface/ten/audio_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
ten_go_error_t ten_go_audio_frame_create(const void *msg_name, int msg_name_len,
uintptr_t *bridge_addr);

ten_go_error_t ten_go_audio_frame_clone(uintptr_t bridge_addr,
uintptr_t *cloned_bridge);

ten_go_error_t ten_go_audio_frame_set_timestamp(uintptr_t bridge_addr,
int64_t timestamp);

Expand Down
27 changes: 27 additions & 0 deletions core/src/ten_runtime/binding/go/interface/ten/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type CmdBase interface {
// Cmd is the interface for the command.
type Cmd interface {
CmdBase

Clone() (Cmd, error)
}

// NewCmd creates a custom cmd which is intended to be sent to another
Expand Down Expand Up @@ -114,4 +116,29 @@ func newCmd(bridge C.uintptr_t) *cmd {
}
}

func (p *cmd) Clone() (Cmd, error) {
var bridge C.uintptr_t
err := withCGOLimiter(func() error {
apiStatus := C.ten_go_cmd_clone(
p.getCPtr(),
&bridge,
)
return withCGoError(&apiStatus)
})

if err != nil {
return nil, err
}

if bridge == 0 {
// Should not happen.
return nil, newTenError(
ErrorCodeInvalidArgument,
"bridge is nil",
)
}

return newCmd(bridge), nil
}

var _ Cmd = new(cmd)
6 changes: 6 additions & 0 deletions core/src/ten_runtime/binding/go/interface/ten/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@ typedef struct ten_go_value_t ten_go_value_t;
ten_go_error_t ten_go_cmd_create_cmd(const void *cmd_name, int cmd_name_len,
uintptr_t *bridge);

ten_go_error_t ten_go_cmd_clone(uintptr_t bridge_addr,
uintptr_t *cloned_bridge);

uintptr_t ten_go_cmd_create_cmd_result(int status_code);

ten_go_error_t ten_go_cmd_result_clone(uintptr_t bridge_addr,
uintptr_t *cloned_bridge);

int ten_go_cmd_result_get_status_code(uintptr_t bridge_addr);

ten_go_error_t ten_go_cmd_result_set_final(uintptr_t bridge_addr,
Expand Down
24 changes: 24 additions & 0 deletions core/src/ten_runtime/binding/go/interface/ten/cmd_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ func (s StatusCode) valid() bool {
// CmdResult is the interface for the cmd result.
type CmdResult interface {
CmdBase

Clone() (CmdResult, error)
GetStatusCode() (StatusCode, error)
SetFinal(isFinal bool) error
IsFinal() (bool, error)
Expand Down Expand Up @@ -135,3 +137,25 @@ func (p *cmdResult) IsCompleted() (bool, error) {

return bool(isCompleted), nil
}

func (p *cmdResult) Clone() (CmdResult, error) {
var bridge C.uintptr_t
err := withCGOLimiter(func() error {
apiStatus := C.ten_go_cmd_result_clone(p.getCPtr(), &bridge)
return withCGoError(&apiStatus)
})

if err != nil {
return nil, err
}

if bridge == 0 {
// Should not happen.
return nil, newTenError(
ErrorCodeInvalidArgument,
"bridge is nil",
)
}

return newCmdResult(bridge), nil
}
23 changes: 23 additions & 0 deletions core/src/ten_runtime/binding/go/interface/ten/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
type Data interface {
Msg

Clone() (Data, error)
AllocBuf(size int) error
LockBuf() ([]byte, error)
UnlockBuf(buf *[]byte) error
Expand Down Expand Up @@ -160,3 +161,25 @@ func (p *data) GetBuf() ([]byte, error) {

return buf, nil
}

func (p *data) Clone() (Data, error) {
var bridge C.uintptr_t
err := withCGOLimiter(func() error {
apiStatus := C.ten_go_data_clone(p.getCPtr(), &bridge)
return withCGoError(&apiStatus)
})

if err != nil {
return nil, err
}

if bridge == 0 {
// Should not happen.
return nil, newTenError(
ErrorCodeInvalidArgument,
"bridge is nil",
)
}

return newData(bridge), nil
}
3 changes: 3 additions & 0 deletions core/src/ten_runtime/binding/go/interface/ten/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
ten_go_error_t ten_go_data_create(const void *msg_name, int msg_name_len,
uintptr_t *bridge);

ten_go_error_t ten_go_data_clone(uintptr_t bridge_addr,
uintptr_t *cloned_bridge);

ten_go_error_t ten_go_data_alloc_buf(uintptr_t bridge_addr, int size);

ten_go_error_t ten_go_data_lock_buf(uintptr_t bridge_addr, uint8_t **buf_addr,
Expand Down
Loading

0 comments on commit c37ffb5

Please sign in to comment.