Skip to content

Commit

Permalink
RTCDataChannel: use signal instead of vfuncs
Browse files Browse the repository at this point in the history
As it turns out, using virtual functions slow down the sample program
a lot. Not sure why; maybe it's node-gtk's inherent problem.

So just go back to using signals. The native delegate still exists, and
still post the signal to main thread. But now the call from native
delegate code to JS happens over signals.
  • Loading branch information
peat-psuwit committed Sep 23, 2023
1 parent d5f95cd commit 684f65e
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 133 deletions.
128 changes: 73 additions & 55 deletions src-native/NgwNativeRTCDataChannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,31 @@

typedef struct {
GstWebRTCDataChannel *gstdatachannel;
// TODO
} NgwNativeRTCDataChannelPrivate;

G_DEFINE_TYPE_WITH_PRIVATE(
NgwNativeRTCDataChannel,
ngw_native_rtc_data_channel,
G_TYPE_OBJECT)

enum
{
SIGNAL_ON_OPEN,
SIGNAL_ON_CLOSE,
SIGNAL_ON_ERROR,
SIGNAL_ON_MESSAGE_DATA,
SIGNAL_ON_MESSAGE_STRING,
SIGNAL_ON_BUFFERED_AMOUNT_LOW,
LAST_SIGNAL,
};

enum {
PROP_GSTDATACHANNEL = 1,
N_PROPERTIES
};

static guint datachannel_signals[LAST_SIGNAL] = { 0 };

static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };

static void ngw_native_rtc_data_channel_set_property(
Expand Down Expand Up @@ -48,11 +60,56 @@ static void ngw_native_rtc_data_channel_class_init(
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_class_install_properties(object_class, N_PROPERTIES, obj_properties);

klass->handle_close = NULL;
klass->handle_error = NULL;
klass->handle_message_data = NULL;
klass->handle_message_string = NULL;
klass->handle_open = NULL;
/**
* NgwNativeRTCDataChannel::on-open:
* @object: the #NgwNativeRTCDataChannel
*/
datachannel_signals[SIGNAL_ON_OPEN] =
g_signal_new ("on-open", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);

/**
* NgwNativeRTCDataChannel::on-close:
* @object: the #NgwNativeRTCDataChannel
*/
datachannel_signals[SIGNAL_ON_CLOSE] =
g_signal_new ("on-close", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);

/**
* NgwNativeRTCDataChannel::on-error:
* @object: the #NgwNativeRTCDataChannel
* @error: the #GError thrown
*/
datachannel_signals[SIGNAL_ON_ERROR] =
g_signal_new ("on-error", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_ERROR);

/**
* NgwNativeRTCDataChannel::on-message-data:
* @object: the #NgwNativeRTCDataChannel
* @data: (nullable): a #GBytes of the data received
*/
datachannel_signals[SIGNAL_ON_MESSAGE_DATA] =
g_signal_new ("on-message-data", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BYTES);

/**
* NgwNativeRTCDataChannel::on-message-string:
* @object: the #NgwNativeRTCDataChannel
* @data: (nullable): the data received as a string
*/
datachannel_signals[SIGNAL_ON_MESSAGE_STRING] =
g_signal_new ("on-message-string", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);

/**
* NgwNativeRTCDataChannel::on-buffered-amount-low:
* @object: the #NgwNativeRTCDataChannel
*/
datachannel_signals[SIGNAL_ON_BUFFERED_AMOUNT_LOW] =
g_signal_new ("on-buffered-amount-low", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
}

static void ngw_native_rtc_data_channel_init(
Expand Down Expand Up @@ -157,14 +214,8 @@ static void ngw_native_rtc_data_channel_dispose(GObject * object)
static int ngw_native_rtc_data_channel_on_buffered_amount_low(gpointer user_data)
{
NgwNativeRTCDataChannel * self = NGW_NATIVE_RTC_DATA_CHANNEL(user_data);
NgwNativeRTCDataChannelClass * klass = NGW_NATIVE_RTC_DATA_CHANNEL_GET_CLASS(self);

if (klass->handle_buffered_amount_low)
klass->handle_buffered_amount_low(self);
else
g_warning(
"NgwNativeRTCDataChannel[%p]: handle_buffered_amount_low() not implemented",
(void *) self);
g_signal_emit(self, datachannel_signals[SIGNAL_ON_BUFFERED_AMOUNT_LOW], 0);

g_object_unref(self);
return G_SOURCE_REMOVE;
Expand All @@ -184,14 +235,8 @@ static void on_buffered_amount_low_callback(
static int ngw_native_rtc_data_channel_on_close(gpointer user_data)
{
NgwNativeRTCDataChannel * self = NGW_NATIVE_RTC_DATA_CHANNEL(user_data);
NgwNativeRTCDataChannelClass * klass = NGW_NATIVE_RTC_DATA_CHANNEL_GET_CLASS(self);

if (klass->handle_close)
klass->handle_close(self);
else
g_warning(
"NgwNativeRTCDataChannel[%p]: handle_close() not implemented",
(void *) self);
g_signal_emit(self, datachannel_signals[SIGNAL_ON_CLOSE], 0, NULL);

g_object_unref(self);
return G_SOURCE_REMOVE;
Expand All @@ -217,15 +262,8 @@ static int ngw_native_rtc_data_channel_on_error(gpointer user_data)
{
struct OnErrorData * data = user_data;

NgwNativeRTCDataChannelClass * klass =
NGW_NATIVE_RTC_DATA_CHANNEL_GET_CLASS(data->self);

if (klass->handle_error)
klass->handle_error(data->self, data->error);
else
g_warning(
"NgwNativeRTCDataChannel[%p]: handle_error() not implemented",
(void *) data->self);
g_signal_emit(data->self,
datachannel_signals[SIGNAL_ON_ERROR], 0, data->error);

g_error_free(data->error);
g_object_unref(data->self);
Expand Down Expand Up @@ -259,15 +297,8 @@ static int ngw_native_rtc_data_channel_on_message_data(gpointer user_data)
{
struct OnMessageDataData * data = user_data;

NgwNativeRTCDataChannelClass * klass =
NGW_NATIVE_RTC_DATA_CHANNEL_GET_CLASS(data->self);

if (klass->handle_message_data)
klass->handle_message_data(data->self, data->bytes);
else
g_warning(
"NgwNativeRTCDataChannel[%p]: handle_message_data() not implemented",
(void *) data->self);
g_signal_emit(data->self,
datachannel_signals[SIGNAL_ON_MESSAGE_DATA], 0, data->bytes);

g_bytes_unref(data->bytes);
g_object_unref(data->self);
Expand Down Expand Up @@ -301,15 +332,8 @@ static int ngw_native_rtc_data_channel_on_message_string(gpointer user_data)
{
struct OnMessageStringData * data = user_data;

NgwNativeRTCDataChannelClass * klass =
NGW_NATIVE_RTC_DATA_CHANNEL_GET_CLASS(data->self);

if (klass->handle_message_string)
klass->handle_message_string(data->self, data->string);
else
g_warning(
"NgwNativeRTCDataChannel[%p]: handle_message_string() not implemented",
(void *) data->self);
g_signal_emit(data->self,
datachannel_signals[SIGNAL_ON_MESSAGE_STRING], 0, data->string);

g_free(data->string);
g_object_unref(data->self);
Expand Down Expand Up @@ -337,14 +361,8 @@ static void on_message_string_callback (
static int ngw_native_rtc_data_channel_on_open(gpointer user_data)
{
NgwNativeRTCDataChannel * self = NGW_NATIVE_RTC_DATA_CHANNEL(user_data);
NgwNativeRTCDataChannelClass * klass = NGW_NATIVE_RTC_DATA_CHANNEL_GET_CLASS(self);

if (klass->handle_open)
klass->handle_open(self);
else
g_warning(
"NgwNativeRTCDataChannel[%p]: handle_open() not implemented",
(void *) self);

g_signal_emit (self, datachannel_signals[SIGNAL_ON_OPEN], 0, NULL);

g_object_unref(self);
return G_SOURCE_REMOVE;
Expand Down
11 changes: 0 additions & 11 deletions src-native/NgwNativeRTCDataChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,6 @@ NGWNATIVE_PUBLIC G_DECLARE_DERIVABLE_TYPE(

struct _NgwNativeRTCDataChannelClass {
GObjectClass parent_class;

/* TODO: introspection for vfuncs? */
void (* handle_buffered_amount_low) (NgwNativeRTCDataChannel * self);
void (* handle_close) (NgwNativeRTCDataChannel * self);
void (* handle_error) (NgwNativeRTCDataChannel * self,
GError * error);
void (* handle_message_data) (NgwNativeRTCDataChannel * self,
GBytes * bytes);
void (* handle_message_string) (NgwNativeRTCDataChannel * self,
const char * string);
void (* handle_open) (NgwNativeRTCDataChannel * self);
};

NGWNATIVE_PUBLIC
Expand Down
91 changes: 77 additions & 14 deletions src/@types/node-ngwnative-0.0.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,51 @@ export namespace NgwNative {

module RTCDataChannel {

// Signal callback interfaces

/**
* Signal callback interface for `on-buffered-amount-low`
*/
interface OnBufferedAmountLowSignalCallback {
(): void
}

/**
* Signal callback interface for `on-close`
*/
interface OnCloseSignalCallback {
(): void
}

/**
* Signal callback interface for `on-error`
*/
interface OnErrorSignalCallback {
(error: GLib.Error): void
}

/**
* Signal callback interface for `on-message-data`
*/
interface OnMessageDataSignalCallback {
(data: any | null): void
}

/**
* Signal callback interface for `on-message-string`
*/
interface OnMessageStringSignalCallback {
(data: string | null): void
}

/**
* Signal callback interface for `on-open`
*/
interface OnOpenSignalCallback {
(): void
}


// Constructor properties interface

interface ConstructorProperties extends GObject.Object.ConstructorProperties {
Expand All @@ -45,14 +90,38 @@ interface RTCDataChannel {

parentInstance: GObject.Object

// Own virtual methods of NgwNative-0.0.NgwNative.RTCDataChannel

handleBufferedAmountLow(): void
handleClose(): void
handleError(error: GLib.Error): void
handleMessageData(bytes: any): void
handleMessageString(string: string | null): void
handleOpen(): void
// Own signals of NgwNative-0.0.NgwNative.RTCDataChannel

connect(sigName: "on-buffered-amount-low", callback: RTCDataChannel.OnBufferedAmountLowSignalCallback): number
on(sigName: "on-buffered-amount-low", callback: RTCDataChannel.OnBufferedAmountLowSignalCallback, after?: boolean): NodeJS.EventEmitter
once(sigName: "on-buffered-amount-low", callback: RTCDataChannel.OnBufferedAmountLowSignalCallback, after?: boolean): NodeJS.EventEmitter
off(sigName: "on-buffered-amount-low", callback: RTCDataChannel.OnBufferedAmountLowSignalCallback): NodeJS.EventEmitter
emit(sigName: "on-buffered-amount-low", ...args: any[]): void
connect(sigName: "on-close", callback: RTCDataChannel.OnCloseSignalCallback): number
on(sigName: "on-close", callback: RTCDataChannel.OnCloseSignalCallback, after?: boolean): NodeJS.EventEmitter
once(sigName: "on-close", callback: RTCDataChannel.OnCloseSignalCallback, after?: boolean): NodeJS.EventEmitter
off(sigName: "on-close", callback: RTCDataChannel.OnCloseSignalCallback): NodeJS.EventEmitter
emit(sigName: "on-close", ...args: any[]): void
connect(sigName: "on-error", callback: RTCDataChannel.OnErrorSignalCallback): number
on(sigName: "on-error", callback: RTCDataChannel.OnErrorSignalCallback, after?: boolean): NodeJS.EventEmitter
once(sigName: "on-error", callback: RTCDataChannel.OnErrorSignalCallback, after?: boolean): NodeJS.EventEmitter
off(sigName: "on-error", callback: RTCDataChannel.OnErrorSignalCallback): NodeJS.EventEmitter
emit(sigName: "on-error", ...args: any[]): void
connect(sigName: "on-message-data", callback: RTCDataChannel.OnMessageDataSignalCallback): number
on(sigName: "on-message-data", callback: RTCDataChannel.OnMessageDataSignalCallback, after?: boolean): NodeJS.EventEmitter
once(sigName: "on-message-data", callback: RTCDataChannel.OnMessageDataSignalCallback, after?: boolean): NodeJS.EventEmitter
off(sigName: "on-message-data", callback: RTCDataChannel.OnMessageDataSignalCallback): NodeJS.EventEmitter
emit(sigName: "on-message-data", ...args: any[]): void
connect(sigName: "on-message-string", callback: RTCDataChannel.OnMessageStringSignalCallback): number
on(sigName: "on-message-string", callback: RTCDataChannel.OnMessageStringSignalCallback, after?: boolean): NodeJS.EventEmitter
once(sigName: "on-message-string", callback: RTCDataChannel.OnMessageStringSignalCallback, after?: boolean): NodeJS.EventEmitter
off(sigName: "on-message-string", callback: RTCDataChannel.OnMessageStringSignalCallback): NodeJS.EventEmitter
emit(sigName: "on-message-string", ...args: any[]): void
connect(sigName: "on-open", callback: RTCDataChannel.OnOpenSignalCallback): number
on(sigName: "on-open", callback: RTCDataChannel.OnOpenSignalCallback, after?: boolean): NodeJS.EventEmitter
once(sigName: "on-open", callback: RTCDataChannel.OnOpenSignalCallback, after?: boolean): NodeJS.EventEmitter
off(sigName: "on-open", callback: RTCDataChannel.OnOpenSignalCallback): NodeJS.EventEmitter
emit(sigName: "on-open", ...args: any[]): void

// Class property signals of NgwNative-0.0.NgwNative.RTCDataChannel

Expand Down Expand Up @@ -93,12 +162,6 @@ interface RTCDataChannelClass {
// Own fields of NgwNative-0.0.NgwNative.RTCDataChannelClass

parentClass: GObject.ObjectClass
handleBufferedAmountLow: (self: RTCDataChannel) => void
handleClose: (self: RTCDataChannel) => void
handleError: (self: RTCDataChannel, error: GLib.Error) => void
handleMessageData: (self: RTCDataChannel, bytes: any) => void
handleMessageString: (self: RTCDataChannel, string: string | null) => void
handleOpen: (self: RTCDataChannel) => void
}

abstract class RTCDataChannelClass {
Expand Down
Loading

0 comments on commit 684f65e

Please sign in to comment.