Skip to content

Commit

Permalink
Unicode listeners now return a unique ID for the instance like device…
Browse files Browse the repository at this point in the history
… listeners. Both unicode and device listeners recycle their IDs, supporting indefinite ID adding and removing
  • Loading branch information
jcorks committed May 31, 2023
1 parent c05b8b7 commit b0af7a8
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 42 deletions.
4 changes: 2 additions & 2 deletions documentation/src/scripting/topaz_input
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ func queryPads -> Array
///
///
///
func addUnicodeListener -> Object
func addUnicodeListener -> Int
/// onNewUnicode: arguments = (unicode)
/// New incoming unicode character is detected.
@Function onNewUnicode
Expand All @@ -575,6 +575,6 @@ func addUnicodeListener -> Object
///
func removeUnicodeListener ->
/// Listener to remove. Expected to be return value from addUnicodeListener()
@Object id
@Int id


21 changes: 17 additions & 4 deletions include/topaz/modules/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,24 +339,37 @@ const topazArray_t * topaz_input_query_pads(

/// Adds a new unicode listener, which will call the given functions
/// when relevant unicode events are detected. If the engine is paused,
/// unicode events arent processed.
/// unicode events arent processed. The ID for the unicode listener
/// is returned.
///
void topaz_input_add_unicode_listener(
int topaz_input_add_unicode_listener(
/// The input to add a listener to.
topazInput_t * input,

/// The listener to read from.
const topazInput_UnicodeListener_t * listener
);

/// Removes a unicode listener.
/// Retrieves the specified listener by ID. NULL
/// is returned in the case of no such listener.
///
const topazInput_UnicodeListener_t * topaz_input_get_unicode_listener(
/// The input to query.
topazInput_t * input,

/// The ID of the listener to retrieve.
int id

);

/// Removes a unicode listener by ID.
///
void topaz_input_remove_unicode_listener(
/// The input to remove the listener from.
topazInput_t * input,

/// The listener to remove.
const topazInput_UnicodeListener_t * listener
int listener
);


Expand Down
79 changes: 60 additions & 19 deletions src/modules_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ struct topazInput_t {
topazArray_t * queriedPads;
topazArray_t * unicodeListeners;

uint32_t listenerIDPool;
topazArray_t * listenerIDPool_recycled;


uint64_t time;
uint64_t startTime;
Expand All @@ -95,6 +98,11 @@ typedef struct {
int id;
} InputListener;

typedef struct {
topazInput_UnicodeListener_t listener;
int id;
} UnicodeListener;

static void get_unicode(topazInput_t *, float prevState, const topazInputDevice_Event_t *);

static float mouse_x_device_to_world_2d(topazDisplay_t *, const topazInput_t * input, float x);
Expand Down Expand Up @@ -191,6 +199,21 @@ struct DeviceState {
};


static int listener_id_new(topazInput_t * input) {
int id = 0;
if (topaz_array_get_size(input->listenerIDPool_recycled)) {
id = topaz_array_at(input->listenerIDPool_recycled, int, topaz_array_get_size(input->listenerIDPool_recycled)-1);
topaz_array_set_size(input->listenerIDPool_recycled, topaz_array_get_size(input->listenerIDPool_recycled)-1);
} else {
id = input->listenerIDPool++;
}
return id;
}

static void listener_id_recycle(topazInput_t * input, uint32_t id) {
topaz_array_push(input->listenerIDPool_recycled, id);
}

static DeviceState * device_state_create(topazInput_t * input) {
DeviceState * out = malloc(sizeof(DeviceState));
out->iter = topaz_table_iter_create();
Expand Down Expand Up @@ -236,7 +259,7 @@ struct DeviceState {
return NULL;
}

static void device_state_update(DeviceState * d) {
static void device_state_update(topazInput_t * t, DeviceState * d) {
// process removal request
if (topaz_array_get_size(d->deletedListeners)) {
uint32_t i;
Expand All @@ -247,6 +270,7 @@ struct DeviceState {
uint32_t totalLen = topaz_array_get_size(d->listeners);
for(n = 0; n < totalLen; ++n) {
if (topaz_array_at(d->listeners, InputListener, n).id == id) {
listener_id_recycle(t, id);
InputListener * list = &topaz_array_at(d->listeners, InputListener, n);

// special case: pointer
Expand Down Expand Up @@ -403,13 +427,12 @@ struct DeviceState {
}
}

static int listenerIDPool = 1;

static int device_state_add_listener(DeviceState * d, const topazInput_Listener_t * src) {
if (listenerIDPool < 0) listenerIDPool = 1;
InputListener l;
static int device_state_add_listener(topazInput_t * input, DeviceState * d, const topazInput_Listener_t * src) {
int id = listener_id_new(input);
InputListener l = {};
l.listener = *src;
l.id = listenerIDPool++;
l.id = id;
topaz_array_push(d->listeners, l);
return l.id;
}
Expand All @@ -436,7 +459,7 @@ void topaz_input_poll(topazInput_t * t) {
for(i = 0; i < topazInputManager_DefaultDevice_Count; ++i) {
t->devices[i]->device = topaz_input_manager_query_device(t->manager, i);
if (t->devices[i]->device)
device_state_update(t->devices[i]);
device_state_update(t, t->devices[i]);
}

InputState * inputX = device_state_get_input(t->devices[topazInputManager_DefaultDevice_Mouse], topazPointer_X);
Expand Down Expand Up @@ -487,8 +510,9 @@ topazInput_t * topaz_input_create(topaz_t * context) {
out->queriedPads = topaz_array_create(sizeof(int));
out->devices = calloc(topazInputManager_DefaultDevice_Count, sizeof(DeviceState*));

out->unicodeListeners = topaz_array_create(sizeof(topazInput_UnicodeListener_t));

out->unicodeListeners = topaz_array_create(sizeof(UnicodeListener));
out->listenerIDPool_recycled = topaz_array_create(sizeof(int));
out->listenerIDPool = 1;

uint32_t i;

Expand Down Expand Up @@ -524,7 +548,7 @@ void topaz_input_destroy(topazInput_t * t) {

int topaz_input_add_keyboard_listener(topazInput_t * t, const topazInput_Listener_t * l) {
DeviceState * input = t->devices[topazInputManager_DefaultDevice_Keyboard];
return device_state_add_listener(input, l);
return device_state_add_listener(t, input, l);
}


Expand All @@ -548,17 +572,17 @@ int topaz_input_add_pointer_listener(topazInput_t * t, const topazInput_Listener
if (evdata->on_update) listener.on_update = on_update__pointer;
if (evdata->on_release) listener.on_release = on_release__pointer;

return device_state_add_listener(input, &listener);
return device_state_add_listener(t, input, &listener);

}

return device_state_add_listener(input, l);
return device_state_add_listener(t, input, l);
}

int topaz_input_add_pad_listener(topazInput_t * t, const topazInput_Listener_t * l, int pad) {
if (pad >= 4) return -1;
DeviceState * input = t->devices[topazInputManager_DefaultDevice_Pad1+pad];
return device_state_add_listener(input, l);
return device_state_add_listener(t, input, l);
}

int topaz_input_add_mapped_listener(topazInput_t * t, const topazInput_Listener_t * src, const topazString_t * str) {
Expand All @@ -567,10 +591,9 @@ int topaz_input_add_mapped_listener(topazInput_t * t, const topazInput_Listener_
arr = topaz_array_create(sizeof(InputListener));
topaz_table_insert(t->stringListeners, str, arr);
}
if (listenerIDPool < 0) listenerIDPool = 1;
InputListener l;
l.listener = *src;
l.id = listenerIDPool++;
l.id = listener_id_new(t);
topaz_array_push(arr, l);
return l.id;
}
Expand Down Expand Up @@ -685,15 +708,33 @@ const topazArray_t * topaz_input_query_pads(const topazInput_t * t) {



void topaz_input_add_unicode_listener(topazInput_t * t, const topazInput_UnicodeListener_t * l) {
topaz_array_push(t->unicodeListeners, *l);
int topaz_input_add_unicode_listener(topazInput_t * t, const topazInput_UnicodeListener_t * l) {
UnicodeListener ul = {};
ul.listener = *l;
ul.id = listener_id_new(t);
topaz_array_push(t->unicodeListeners, ul);
return ul.id;
}


const topazInput_UnicodeListener_t * topaz_input_get_unicode_listener(topazInput_t * t, int id) {
uint32_t i;
uint32_t len = topaz_array_get_size(t->unicodeListeners);
for(i = 0; i < len; ++i) {
UnicodeListener * ul = &topaz_array_at(t->unicodeListeners, UnicodeListener, i);
if (ul->id == id) {
return &ul->listener;
}
}
}

void topaz_input_remove_unicode_listener(topazInput_t * t, const topazInput_UnicodeListener_t * l) {
void topaz_input_remove_unicode_listener(topazInput_t * t, int id) {
uint32_t i;
uint32_t len = topaz_array_get_size(t->unicodeListeners);
for(i = 0; i < len; ++i) {
if (memcmp(&topaz_array_at(t->unicodeListeners, topazInput_UnicodeListener_t, i), l, sizeof(topazInput_UnicodeListener_t)) == 0) {
UnicodeListener * ul = &topaz_array_at(t->unicodeListeners, UnicodeListener, i);
if (ul->id == id) {
listener_id_recycle(t, id);
topaz_array_remove(t->unicodeListeners, i);
return;
}
Expand Down
34 changes: 17 additions & 17 deletions src/script_native__input.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,18 @@ TSO_SCRIPT_API_FN(input_api__add_unicode_listener) {
ldata->obj = topaz_script_object_from_object(script, arg0);
ldata->script = script;
topaz_script_object_reference_set_native_data(ldata->obj, ldata, TSO_OBJECT_ID__UNICODELISTENER);
topazInput_UnicodeListener_t listener;
topazInput_UnicodeListener_t listener = {};

listener.on_new_unicode = script_input_on_new_unicode;
listener.on_repeat_unicode = script_input_on_repeat_unicode;
listener.userData = ldata;
topaz_input_add_unicode_listener(
input,
&listener
return topaz_script_object_from_int(
script,

topaz_input_add_unicode_listener(
input,
&listener
)
);
TSO_NO_RETURN;
}
Expand All @@ -366,19 +370,15 @@ TSO_SCRIPT_API_FN(input_api__remove_unicode_listener) {
TSO_ARG_0;
topazInput_t * input = topaz_context_get_input(((topazScriptManager_t*)context)->ctx);

int tag = 1;
ScriptInputListener * ldata = topaz_script_object_reference_get_native_data(arg0, &tag);
if (!ldata || tag != TSO_OBJECT_ID__INPUTLISTENER) {
script_error(script, "Input object isnt an input listener.");
TSO_NO_RETURN;
}

topazInput_UnicodeListener_t listener;
listener.userData = ldata;
listener.on_new_unicode = script_input_on_new_unicode;
listener.on_repeat_unicode = script_input_on_repeat_unicode;
topaz_input_remove_unicode_listener(input, &listener);

const topazInput_UnicodeListener_t * l = topaz_input_get_unicode_listener(
input,
topaz_script_object_as_int(arg0)
);
if (!l) TSO_NO_RETURN;

ScriptInputListener * ldata = l->userData;
topaz_input_remove_unicode_listener(input, topaz_script_object_as_int(arg0));
topaz_script_object_reference_unref(ldata->obj);
topaz_script_object_destroy(ldata->obj);
free(ldata);
TSO_NO_RETURN;
Expand Down

0 comments on commit b0af7a8

Please sign in to comment.