Skip to content

Commit

Permalink
Move some of the 3d gesture logic into gesture3d.c
Browse files Browse the repository at this point in the history
Instead of doing it in goxel.c.

Still a bit experimental.
  • Loading branch information
guillaumechereau committed Jul 1, 2024
1 parent 2dbbabc commit 3e5cea4
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 68 deletions.
69 changes: 68 additions & 1 deletion src/gesture3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

#include "goxel.h"

int gesture3d(gesture3d_t *gest)

static int update_state(gesture3d_t *gest)
{
bool pressed = gest->flags & GESTURE3D_FLAG_PRESSED;
int r, ret = 0;
Expand Down Expand Up @@ -121,3 +122,69 @@ int gesture3d(gesture3d_t *gest)

return ret;
}

int gesture3d(const gesture3d_t *gest, int *nb, gesture3d_t gestures[])
{
int i;
gesture3d_t *other, *match;

// Search if we already have this gesture in the list.
for (i = 0; i < goxel.gesture3ds_count; i++) {
match = &gestures[i];
if ( match->callback == gest->callback &&
match->type == gest->type) {
break;
}
}
// If no match add the gesture in the list.
if (i == *nb) {
match = &gestures[(*nb)++];
memset(match, 0, sizeof(*match));
}

// Search if we already have a different active gesture.
// XXX: should depend on the type.
for (i = 0; i < *nb; i++) {
other = &gestures[i];
if ( other->callback == gest->callback &&
other->type == gest->type) {
continue;
}
if (other->type != GESTURE3D_TYPE_HOVER && other->state != 0) {
return false;
}
}

// Update the gesture data until it has started. That way we can
// modify the gesture inside its callback function.
if (match->state == 0) {
match->type = gest->type;
match->buttons = gest->buttons;
match->snap_mask = gest->snap_mask;
match->snap_offset = gest->snap_offset;
mat4_copy(gest->snap_shape, match->snap_shape);
match->callback = gest->callback;
}
match->user = gest->user;
match->alive = true;
return update_state(match);
}

void gesture3d_remove_dead(int *nb, gesture3d_t gestures[])
{
int i, count;
gesture3d_t *gest;

for (i = *nb - 1; i >= 0; i--) {
gest = &gestures[i];
if (gest->alive) {
gest->alive = false;
continue;
}
count = *nb - i - 1;
if (count > 0) {
memmove(&gestures[i], &gestures[i + 1], count * sizeof(*gest));
}
(*nb)--;
}
}
21 changes: 18 additions & 3 deletions src/gesture3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,30 @@ struct gesture3d
int (*callback)(gesture3d_t *gest);
void *user;

// Automatically updated attributes.
// Need to be updated manually.
bool alive;
int state;
float pos[3];
float normal[3];
int snaped;
int flags;

// Updated by the 'gesture3d' function.
int state;
};

int gesture3d(gesture3d_t *gest);
/*
* Process a single 3d gesture state.
*
* Parameters:
* gest - The gesture we want to process.
* nb - The total number of gestures.
* gestures - Array of registered gestures.
*/
int gesture3d(const gesture3d_t *gest, int *nb, gesture3d_t gestures[]);

/*
* Remove the dead gestures from an array of 3d gestures.
*/
void gesture3d_remove_dead(int *nb, gesture3d_t gestures[]);

#endif // GESTURE3D_H
66 changes: 2 additions & 64 deletions src/goxel.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,78 +526,16 @@ static void update_window_title(void)

bool goxel_gesture3d(const gesture3d_t *gesture)
{
int i;
bool ret;
gesture3d_t *gest;

// Search if we already have a different active gesture.
for (i = 0; i < goxel.gesture3ds_count; i++) {
gest = &goxel.gesture3ds[i];
if ( gest->callback == gesture->callback &&
gest->type == gesture->type) {
continue;
}
if (gest->type != GESTURE3D_TYPE_HOVER && gest->state != 0) {
return false;
}
}

// Search if we already have this gesture in the list.
for (i = 0; i < goxel.gesture3ds_count; i++) {
gest = &goxel.gesture3ds[i];
if ( gest->callback == gesture->callback &&
gest->type == gesture->type) {
break;
}
}
// If no match add the gesture in the list.
if (i == goxel.gesture3ds_count) {
gest = &goxel.gesture3ds[goxel.gesture3ds_count++];
memset(gest, 0, sizeof(*gest));
*gest = *gesture;
}

// Update the gesture data until it has started. That way we can
// modify the gesture inside its callback function.
if (gest->state == 0) {
gest->type = gesture->type;
gest->buttons = gesture->buttons;
gest->snap_mask = gesture->snap_mask;
gest->snap_offset = gesture->snap_offset;
mat4_copy(gesture->snap_shape, gest->snap_shape);
gest->callback = gesture->callback;
gest->user = gesture->user;
}
gest->user = gesture->user;

gest->alive = true;
ret = gesture3d(gest);
return ret;
return gesture3d(gesture, &goxel.gesture3ds_count, goxel.gesture3ds);
}

// Cleanup the unused 3d gestures.
static void gesture3ds_iter(void)
{
int i, count;
gesture3d_t *gest;

for (i = goxel.gesture3ds_count - 1; i >= 0; i--) {
gest = &goxel.gesture3ds[i];
if (gest->alive) {
gest->alive = false;
continue;
}
count = goxel.gesture3ds_count - i - 1;
if (count > 0) {
memmove(&goxel.gesture3ds[i], &goxel.gesture3ds[i + 1],
count * sizeof(*gest));
}
goxel.gesture3ds_count--;
}
gesture3d_remove_dead(&goxel.gesture3ds_count, goxel.gesture3ds);
}



KEEPALIVE
int goxel_iter(const inputs_t *inputs)
{
Expand Down

0 comments on commit 3e5cea4

Please sign in to comment.