From 7d1d930dcb99559eee95fc8a94cc68d12a968353 Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Tue, 3 Apr 2018 16:08:00 -0600 Subject: Added simple API --- src/survive_api.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 src/survive_api.c (limited to 'src/survive_api.c') diff --git a/src/survive_api.c b/src/survive_api.c new file mode 100644 index 0000000..9883c9f --- /dev/null +++ b/src/survive_api.c @@ -0,0 +1,167 @@ +#include "survive_api.h" +#include "os_generic.h" +#include "survive.h" +#include "stdio.h" + +struct SurviveAsyncObject { + struct SurviveAsyncContext* actx; + + enum SurviveAsyncObject_type { + SurviveAsyncObject_LIGHTHOUSE, + SurviveAsyncObject_OBJECT + } type; + + union { + int lighthosue; + struct SurviveObject* so; + } data; + + char name[32]; + bool has_update; +}; + +struct SurviveAsyncContext { + SurviveContext* ctx; + + bool running; + og_thread_t thread; + og_mutex_t poll_mutex; + + size_t object_ct; + struct SurviveAsyncObject objects[]; +}; + +static void pose_fn(SurviveObject *so, uint32_t timecode, SurvivePose *pose) { + survive_default_raw_pose_process(so, timecode, pose); + + struct SurviveAsyncContext* actx = so->ctx->user_ptr; + int idx = so->user_ptr; + actx->objects[idx].has_update = true; +} +static void lh_fn(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lighthouse_pose, + SurvivePose *object_pose) { + survive_default_lighthouse_pose_process(ctx, lighthouse, lighthouse_pose, object_pose); + + struct SurviveAsyncContext* actx = ctx->user_ptr; + actx->objects[lighthouse].has_update = true; +} + +struct SurviveAsyncContext *survive_asyc_init(int argc, char *const *argv) { + SurviveContext* ctx = survive_init(argc, argv); + if (ctx == 0) + return 0; + + survive_startup(ctx); + + int object_ct = ctx->activeLighthouses + ctx->objs_ct; + struct SurviveAsyncContext * actx = calloc(1, sizeof(struct SurviveAsyncContext) + sizeof(struct SurviveAsyncObject) * object_ct ); + actx->object_ct = object_ct; + actx->ctx = ctx; + actx->poll_mutex = OGCreateMutex(); + ctx->user_ptr = actx; + int i = 0; + for (i = 0; i < ctx->activeLighthouses; i++) { + struct SurviveAsyncObject* obj = &actx->objects[i]; + obj->data.lighthosue = i; + obj->type = SurviveAsyncObject_LIGHTHOUSE; + obj->actx = actx; + obj->has_update = ctx->bsd[i].PositionSet; + snprintf(obj->name, 32, "LH%d", i); + } + for (; i < object_ct; i++) { + struct SurviveAsyncObject* obj = &actx->objects[i]; + int so_idx = i - ctx->activeLighthouses; + obj->data.so = ctx->objs[so_idx]; + obj->type = SurviveAsyncObject_OBJECT; + obj->actx = actx; + obj->data.so->user_ptr = (void*)i; + snprintf(obj->name, 32, "%s", obj->data.so->codename); + } + + survive_install_pose_fn(ctx, pose_fn); + survive_install_lighthouse_pose_fn(ctx, lh_fn); + return actx; +} + +void survive_async_close(struct SurviveAsyncContext* actx) { + if (actx->running) { + survive_async_stop_thread(actx); + } + + survive_close(actx->ctx); +} + +static inline void* __async_thread(void* _actx) { + struct SurviveAsyncContext* actx = _actx; + int error = 0; + while (actx->running && error == 0) { + OGLockMutex(actx->poll_mutex); + error = survive_poll(actx->ctx); + OGUnlockMutex(actx->poll_mutex); + } + actx->running = false; + return (void*)error; +} +bool survive_async_is_running(struct SurviveAsyncContext* actx) { + return actx->running; +} +void survive_async_start_thread(struct SurviveAsyncContext* actx) { + actx->running = true; + actx->thread = OGCreateThread(__async_thread, actx); +} +int survive_async_stop_thread(struct SurviveAsyncContext* actx) { + actx->running = false; + int error = (int)OGJoinThread(actx->thread); + if (error != 0) { + SurviveContext* ctx = actx->ctx; + SV_INFO("Warning: Loope exited with error %d", error); + } + return error; +} + +const struct SurviveAsyncObject* survive_async_get_next_tracked(struct SurviveAsyncContext* actx, const struct SurviveAsyncObject* curr) { + const struct SurviveAsyncObject* next = curr + 1; + if (next >= actx->objects + actx->object_ct) + return 0; + return next; +} + +const struct SurviveAsyncObject* survive_async_get_first_tracked(struct SurviveAsyncContext* actx) { + return actx->objects; +} + +const struct SurviveAsyncObject* survive_async_get_next_updated(struct SurviveAsyncContext* actx) { + for (int i = 0; i < actx->object_ct; i++) { + if (actx->objects[i].has_update) { + actx->objects[i].has_update = false; + return &actx->objects[i]; + } + } + return 0; +} + +uint32_t survive_async_object_get_latest_pose(const struct SurviveAsyncObject* sao, SurvivePose* pose) { + uint32_t timecode = 0; + OGLockMutex(sao->actx->poll_mutex); + + switch (sao->type) { + case SurviveAsyncObject_LIGHTHOUSE: { + if(pose) + *pose = sao->actx->ctx->bsd[sao->data.lighthosue].Pose; + break; + } + case SurviveAsyncObject_OBJECT: + if(pose) + *pose = sao->data.so->OutPose; + timecode = sao->data.so->OutPose_timecode; + break; + } + + OGUnlockMutex(sao->actx->poll_mutex); + return timecode; +} + +const char * survive_async_object_name(const SurviveAsyncObject * sao) +{ + return sao->name; +} -- cgit v1.2.3 From be7593dc945ed4025f81c6876760807310a67319 Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Tue, 3 Apr 2018 22:56:40 -0600 Subject: Minor cleanup --- src/survive_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/survive_api.c') diff --git a/src/survive_api.c b/src/survive_api.c index 9883c9f..2aaf31a 100644 --- a/src/survive_api.c +++ b/src/survive_api.c @@ -35,7 +35,7 @@ static void pose_fn(SurviveObject *so, uint32_t timecode, SurvivePose *pose) { survive_default_raw_pose_process(so, timecode, pose); struct SurviveAsyncContext* actx = so->ctx->user_ptr; - int idx = so->user_ptr; + int idx = (int)so->user_ptr; actx->objects[idx].has_update = true; } static void lh_fn(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lighthouse_pose, @@ -46,7 +46,7 @@ static void lh_fn(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lighthou actx->objects[lighthouse].has_update = true; } -struct SurviveAsyncContext *survive_asyc_init(int argc, char *const *argv) { +struct SurviveAsyncContext *survive_async_init(int argc, char *const *argv) { SurviveContext* ctx = survive_init(argc, argv); if (ctx == 0) return 0; -- cgit v1.2.3 From 229a2cb44d1462200ffa14fe925cd91796e99989 Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Wed, 4 Apr 2018 09:36:10 -0600 Subject: Dramatically reduced the scope of locking --- src/survive_api.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/survive_api.c') diff --git a/src/survive_api.c b/src/survive_api.c index 2aaf31a..bb1f090 100644 --- a/src/survive_api.c +++ b/src/survive_api.c @@ -32,18 +32,23 @@ struct SurviveAsyncContext { }; static void pose_fn(SurviveObject *so, uint32_t timecode, SurvivePose *pose) { + struct SurviveAsyncContext *actx = so->ctx->user_ptr; + OGLockMutex(actx->poll_mutex); survive_default_raw_pose_process(so, timecode, pose); - struct SurviveAsyncContext* actx = so->ctx->user_ptr; int idx = (int)so->user_ptr; actx->objects[idx].has_update = true; + OGUnlockMutex(actx->poll_mutex); } static void lh_fn(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lighthouse_pose, SurvivePose *object_pose) { + struct SurviveAsyncContext *actx = ctx->user_ptr; + OGLockMutex(actx->poll_mutex); survive_default_lighthouse_pose_process(ctx, lighthouse, lighthouse_pose, object_pose); - struct SurviveAsyncContext* actx = ctx->user_ptr; actx->objects[lighthouse].has_update = true; + + OGUnlockMutex(actx->poll_mutex); } struct SurviveAsyncContext *survive_async_init(int argc, char *const *argv) { @@ -95,9 +100,7 @@ static inline void* __async_thread(void* _actx) { struct SurviveAsyncContext* actx = _actx; int error = 0; while (actx->running && error == 0) { - OGLockMutex(actx->poll_mutex); error = survive_poll(actx->ctx); - OGUnlockMutex(actx->poll_mutex); } actx->running = false; return (void*)error; -- cgit v1.2.3 From 9e1883922de980c01e60bde10c1e67261752afa6 Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Thu, 5 Apr 2018 07:56:01 -0600 Subject: Fixed typo; naming suggestions --- src/survive_api.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/survive_api.c') diff --git a/src/survive_api.c b/src/survive_api.c index bb1f090..e2c3d54 100644 --- a/src/survive_api.c +++ b/src/survive_api.c @@ -12,7 +12,7 @@ struct SurviveAsyncObject { } type; union { - int lighthosue; + int lighthouse; struct SurviveObject* so; } data; @@ -67,7 +67,7 @@ struct SurviveAsyncContext *survive_async_init(int argc, char *const *argv) { int i = 0; for (i = 0; i < ctx->activeLighthouses; i++) { struct SurviveAsyncObject* obj = &actx->objects[i]; - obj->data.lighthosue = i; + obj->data.lighthouse = i; obj->type = SurviveAsyncObject_LIGHTHOUSE; obj->actx = actx; obj->has_update = ctx->bsd[i].PositionSet; @@ -122,14 +122,15 @@ int survive_async_stop_thread(struct SurviveAsyncContext* actx) { return error; } -const struct SurviveAsyncObject* survive_async_get_next_tracked(struct SurviveAsyncContext* actx, const struct SurviveAsyncObject* curr) { +const struct SurviveAsyncObject *survive_async_get_next_object(struct SurviveAsyncContext *actx, + const struct SurviveAsyncObject *curr) { const struct SurviveAsyncObject* next = curr + 1; if (next >= actx->objects + actx->object_ct) return 0; return next; } -const struct SurviveAsyncObject* survive_async_get_first_tracked(struct SurviveAsyncContext* actx) { +const struct SurviveAsyncObject *survive_async_get_first_object(struct SurviveAsyncContext *actx) { return actx->objects; } @@ -150,7 +151,7 @@ uint32_t survive_async_object_get_latest_pose(const struct SurviveAsyncObject* s switch (sao->type) { case SurviveAsyncObject_LIGHTHOUSE: { if(pose) - *pose = sao->actx->ctx->bsd[sao->data.lighthosue].Pose; + *pose = sao->actx->ctx->bsd[sao->data.lighthouse].Pose; break; } case SurviveAsyncObject_OBJECT: -- cgit v1.2.3 From 30cfb87ec0d95e0cb8a671cf8f2327b4204927ed Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Tue, 10 Apr 2018 23:44:36 -0600 Subject: Renamed api; fixed various warnings --- src/survive_api.c | 98 ++++++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 52 deletions(-) (limited to 'src/survive_api.c') diff --git a/src/survive_api.c b/src/survive_api.c index e2c3d54..a39524b 100644 --- a/src/survive_api.c +++ b/src/survive_api.c @@ -3,13 +3,10 @@ #include "survive.h" #include "stdio.h" -struct SurviveAsyncObject { - struct SurviveAsyncContext* actx; - - enum SurviveAsyncObject_type { - SurviveAsyncObject_LIGHTHOUSE, - SurviveAsyncObject_OBJECT - } type; +struct SurviveSimpleObject { + struct SurviveSimpleContext *actx; + + enum SurviveSimpleObject_type { SurviveSimpleObject_LIGHTHOUSE, SurviveSimpleObject_OBJECT } type; union { int lighthouse; @@ -20,7 +17,7 @@ struct SurviveAsyncObject { bool has_update; }; -struct SurviveAsyncContext { +struct SurviveSimpleContext { SurviveContext* ctx; bool running; @@ -28,21 +25,21 @@ struct SurviveAsyncContext { og_mutex_t poll_mutex; size_t object_ct; - struct SurviveAsyncObject objects[]; + struct SurviveSimpleObject objects[]; }; static void pose_fn(SurviveObject *so, uint32_t timecode, SurvivePose *pose) { - struct SurviveAsyncContext *actx = so->ctx->user_ptr; + struct SurviveSimpleContext *actx = so->ctx->user_ptr; OGLockMutex(actx->poll_mutex); - survive_default_raw_pose_process(so, timecode, pose); + survive_default_raw_pose_process(so, timecode, pose); - int idx = (int)so->user_ptr; + intptr_t idx = (intptr_t)so->user_ptr; actx->objects[idx].has_update = true; OGUnlockMutex(actx->poll_mutex); } static void lh_fn(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lighthouse_pose, SurvivePose *object_pose) { - struct SurviveAsyncContext *actx = ctx->user_ptr; + struct SurviveSimpleContext *actx = ctx->user_ptr; OGLockMutex(actx->poll_mutex); survive_default_lighthouse_pose_process(ctx, lighthouse, lighthouse_pose, object_pose); @@ -51,7 +48,7 @@ static void lh_fn(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lighthou OGUnlockMutex(actx->poll_mutex); } -struct SurviveAsyncContext *survive_async_init(int argc, char *const *argv) { +struct SurviveSimpleContext *survive_simple_init(int argc, char *const *argv) { SurviveContext* ctx = survive_init(argc, argv); if (ctx == 0) return 0; @@ -59,25 +56,26 @@ struct SurviveAsyncContext *survive_async_init(int argc, char *const *argv) { survive_startup(ctx); int object_ct = ctx->activeLighthouses + ctx->objs_ct; - struct SurviveAsyncContext * actx = calloc(1, sizeof(struct SurviveAsyncContext) + sizeof(struct SurviveAsyncObject) * object_ct ); + struct SurviveSimpleContext *actx = + calloc(1, sizeof(struct SurviveSimpleContext) + sizeof(struct SurviveSimpleObject) * object_ct); actx->object_ct = object_ct; actx->ctx = ctx; actx->poll_mutex = OGCreateMutex(); ctx->user_ptr = actx; - int i = 0; + intptr_t i = 0; for (i = 0; i < ctx->activeLighthouses; i++) { - struct SurviveAsyncObject* obj = &actx->objects[i]; + struct SurviveSimpleObject *obj = &actx->objects[i]; obj->data.lighthouse = i; - obj->type = SurviveAsyncObject_LIGHTHOUSE; + obj->type = SurviveSimpleObject_LIGHTHOUSE; obj->actx = actx; obj->has_update = ctx->bsd[i].PositionSet; - snprintf(obj->name, 32, "LH%d", i); + snprintf(obj->name, 32, "LH%ld", i); } for (; i < object_ct; i++) { - struct SurviveAsyncObject* obj = &actx->objects[i]; + struct SurviveSimpleObject *obj = &actx->objects[i]; int so_idx = i - ctx->activeLighthouses; obj->data.so = ctx->objs[so_idx]; - obj->type = SurviveAsyncObject_OBJECT; + obj->type = SurviveSimpleObject_OBJECT; obj->actx = actx; obj->data.so->user_ptr = (void*)i; snprintf(obj->name, 32, "%s", obj->data.so->codename); @@ -88,53 +86,52 @@ struct SurviveAsyncContext *survive_async_init(int argc, char *const *argv) { return actx; } -void survive_async_close(struct SurviveAsyncContext* actx) { +int survive_simple_stop_thread(struct SurviveSimpleContext *actx) { + actx->running = false; + intptr_t error = (intptr_t)OGJoinThread(actx->thread); + if (error != 0) { + SurviveContext *ctx = actx->ctx; + SV_INFO("Warning: Loope exited with error %ld", error); + } + return error; +} + +void survive_simple_close(struct SurviveSimpleContext *actx) { if (actx->running) { - survive_async_stop_thread(actx); + survive_simple_stop_thread(actx); } survive_close(actx->ctx); } -static inline void* __async_thread(void* _actx) { - struct SurviveAsyncContext* actx = _actx; - int error = 0; +static inline void *__simple_thread(void *_actx) { + struct SurviveSimpleContext *actx = _actx; + intptr_t error = 0; while (actx->running && error == 0) { error = survive_poll(actx->ctx); } actx->running = false; return (void*)error; } -bool survive_async_is_running(struct SurviveAsyncContext* actx) { - return actx->running; -} -void survive_async_start_thread(struct SurviveAsyncContext* actx) { +bool survive_simple_is_running(struct SurviveSimpleContext *actx) { return actx->running; } +void survive_simple_start_thread(struct SurviveSimpleContext *actx) { actx->running = true; - actx->thread = OGCreateThread(__async_thread, actx); -} -int survive_async_stop_thread(struct SurviveAsyncContext* actx) { - actx->running = false; - int error = (int)OGJoinThread(actx->thread); - if (error != 0) { - SurviveContext* ctx = actx->ctx; - SV_INFO("Warning: Loope exited with error %d", error); - } - return error; + actx->thread = OGCreateThread(__simple_thread, actx); } -const struct SurviveAsyncObject *survive_async_get_next_object(struct SurviveAsyncContext *actx, - const struct SurviveAsyncObject *curr) { - const struct SurviveAsyncObject* next = curr + 1; +const struct SurviveSimpleObject *survive_simple_get_next_object(struct SurviveSimpleContext *actx, + const struct SurviveSimpleObject *curr) { + const struct SurviveSimpleObject *next = curr + 1; if (next >= actx->objects + actx->object_ct) return 0; return next; } -const struct SurviveAsyncObject *survive_async_get_first_object(struct SurviveAsyncContext *actx) { +const struct SurviveSimpleObject *survive_simple_get_first_object(struct SurviveSimpleContext *actx) { return actx->objects; } -const struct SurviveAsyncObject* survive_async_get_next_updated(struct SurviveAsyncContext* actx) { +const struct SurviveSimpleObject *survive_simple_get_next_updated(struct SurviveSimpleContext *actx) { for (int i = 0; i < actx->object_ct; i++) { if (actx->objects[i].has_update) { actx->objects[i].has_update = false; @@ -144,17 +141,17 @@ const struct SurviveAsyncObject* survive_async_get_next_updated(struct SurviveAs return 0; } -uint32_t survive_async_object_get_latest_pose(const struct SurviveAsyncObject* sao, SurvivePose* pose) { +uint32_t survive_simple_object_get_latest_pose(const struct SurviveSimpleObject *sao, SurvivePose *pose) { uint32_t timecode = 0; OGLockMutex(sao->actx->poll_mutex); switch (sao->type) { - case SurviveAsyncObject_LIGHTHOUSE: { + case SurviveSimpleObject_LIGHTHOUSE: { if(pose) *pose = sao->actx->ctx->bsd[sao->data.lighthouse].Pose; break; } - case SurviveAsyncObject_OBJECT: + case SurviveSimpleObject_OBJECT: if(pose) *pose = sao->data.so->OutPose; timecode = sao->data.so->OutPose_timecode; @@ -165,7 +162,4 @@ uint32_t survive_async_object_get_latest_pose(const struct SurviveAsyncObject* s return timecode; } -const char * survive_async_object_name(const SurviveAsyncObject * sao) -{ - return sao->name; -} +const char *survive_simple_object_name(const SurviveSimpleObject *sao) { return sao->name; } -- cgit v1.2.3