aboutsummaryrefslogtreecommitdiff
path: root/src/survive_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/survive_api.c')
-rw-r--r--src/survive_api.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/src/survive_api.c b/src/survive_api.c
new file mode 100644
index 0000000..a39524b
--- /dev/null
+++ b/src/survive_api.c
@@ -0,0 +1,165 @@
+#include "survive_api.h"
+#include "os_generic.h"
+#include "survive.h"
+#include "stdio.h"
+
+struct SurviveSimpleObject {
+ struct SurviveSimpleContext *actx;
+
+ enum SurviveSimpleObject_type { SurviveSimpleObject_LIGHTHOUSE, SurviveSimpleObject_OBJECT } type;
+
+ union {
+ int lighthouse;
+ struct SurviveObject* so;
+ } data;
+
+ char name[32];
+ bool has_update;
+};
+
+struct SurviveSimpleContext {
+ SurviveContext* ctx;
+
+ bool running;
+ og_thread_t thread;
+ og_mutex_t poll_mutex;
+
+ size_t object_ct;
+ struct SurviveSimpleObject objects[];
+};
+
+static void pose_fn(SurviveObject *so, uint32_t timecode, SurvivePose *pose) {
+ struct SurviveSimpleContext *actx = so->ctx->user_ptr;
+ OGLockMutex(actx->poll_mutex);
+ survive_default_raw_pose_process(so, timecode, pose);
+
+ 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 SurviveSimpleContext *actx = ctx->user_ptr;
+ OGLockMutex(actx->poll_mutex);
+ survive_default_lighthouse_pose_process(ctx, lighthouse, lighthouse_pose, object_pose);
+
+ actx->objects[lighthouse].has_update = true;
+
+ OGUnlockMutex(actx->poll_mutex);
+}
+
+struct SurviveSimpleContext *survive_simple_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 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;
+ intptr_t i = 0;
+ for (i = 0; i < ctx->activeLighthouses; i++) {
+ struct SurviveSimpleObject *obj = &actx->objects[i];
+ obj->data.lighthouse = i;
+ obj->type = SurviveSimpleObject_LIGHTHOUSE;
+ obj->actx = actx;
+ obj->has_update = ctx->bsd[i].PositionSet;
+ snprintf(obj->name, 32, "LH%ld", i);
+ }
+ for (; i < object_ct; i++) {
+ struct SurviveSimpleObject *obj = &actx->objects[i];
+ int so_idx = i - ctx->activeLighthouses;
+ obj->data.so = ctx->objs[so_idx];
+ obj->type = SurviveSimpleObject_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;
+}
+
+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_simple_stop_thread(actx);
+ }
+
+ survive_close(actx->ctx);
+}
+
+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_simple_is_running(struct SurviveSimpleContext *actx) { return actx->running; }
+void survive_simple_start_thread(struct SurviveSimpleContext *actx) {
+ actx->running = true;
+ actx->thread = OGCreateThread(__simple_thread, actx);
+}
+
+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 SurviveSimpleObject *survive_simple_get_first_object(struct SurviveSimpleContext *actx) {
+ return actx->objects;
+}
+
+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;
+ return &actx->objects[i];
+ }
+ }
+ return 0;
+}
+
+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 SurviveSimpleObject_LIGHTHOUSE: {
+ if(pose)
+ *pose = sao->actx->ctx->bsd[sao->data.lighthouse].Pose;
+ break;
+ }
+ case SurviveSimpleObject_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_simple_object_name(const SurviveSimpleObject *sao) { return sao->name; }