From 6ac6256ac50a32f1a17fdf38afbb0ce0595ee379 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Thu, 26 Dec 2013 04:26:17 -0700 Subject: [PATCH] fill in rest of signal/callback/proc --- libobs/CMakeLists.txt | 3 + libobs/callback/calldata.h | 2 +- libobs/callback/proc.c | 59 ++++++++ libobs/callback/proc.h | 2 +- libobs/callback/signal.c | 186 ++++++++++++++++++++++++++ libobs/callback/signal.h | 6 +- libobs/makefile.am | 5 +- obs/window-main-basic.cpp | 4 + obs/window-main-basic.hpp | 4 +- vs/2013/libobs/libobs.vcxproj | 4 + vs/2013/libobs/libobs.vcxproj.filters | 12 ++ 11 files changed, 279 insertions(+), 8 deletions(-) diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt index 4f8b35cb4..c8ba29403 100644 --- a/libobs/CMakeLists.txt +++ b/libobs/CMakeLists.txt @@ -67,6 +67,9 @@ add_library(libobs SHARED graphics/vec2.c graphics/vec3.c graphics/vec4.c + callback/calldata.c + callback/proc.c + callback/signal.c ${libobs_platform_src}) set_target_properties(libobs diff --git a/libobs/callback/calldata.h b/libobs/callback/calldata.h index af3e07fb0..31db5dbce 100644 --- a/libobs/callback/calldata.h +++ b/libobs/callback/calldata.h @@ -178,7 +178,7 @@ EXPORT bool calldata_getstring(calldata_t data, const char *name, /* ------------------------------------------------------------------------- */ -void calldata_setchar (calldata_t data, const char *name, char val) +static void calldata_setchar (calldata_t data, const char *name, char val) { calldata_setdata(data, name, &val, sizeof(val)); } diff --git a/libobs/callback/proc.c b/libobs/callback/proc.c index b78ccae66..5156cc80d 100644 --- a/libobs/callback/proc.c +++ b/libobs/callback/proc.c @@ -14,4 +14,63 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "../util/darray.h" +#include "proc.h" + +struct proc_info { + char *name; + void (*proc)(calldata_t, void*); +}; + +static inline void proc_info_free(struct proc_info *pi) +{ + bfree(pi->name); +} + +struct proc_handler { + void *data; + + /* TODO: replace with hash table lookup? */ + DARRAY(struct proc_info) procs; +}; + +proc_handler_t proc_handler_create(void *data) +{ + struct proc_handler *handler = bmalloc(sizeof(struct proc_handler)); + handler->data = data; + da_init(handler->procs); + return handler; +} + +void proc_handler_destroy(proc_handler_t handler) +{ + if (handler) { + for (size_t i = 0; i < handler->procs.num; i++) + proc_info_free(handler->procs.array+i); + da_free(handler->procs); + bfree(handler); + } +} + +void proc_handler_add(proc_handler_t handler, const char *name, + void (*proc)(calldata_t, void*)) +{ + struct proc_info pi = {bstrdup(name), proc}; + da_push_back(handler->procs, &pi); +} + +bool proc_handler_call(proc_handler_t handler, const char *name, + calldata_t params) +{ + for (size_t i = 0; i < handler->procs.num; i++) { + struct proc_info *info = handler->procs.array+i; + + if (strcmp(info->name, name) == 0) { + info->proc(params, handler->data); + return true; + } + } + + return false; +} diff --git a/libobs/callback/proc.h b/libobs/callback/proc.h index 9ca2c8695..793562bf3 100644 --- a/libobs/callback/proc.h +++ b/libobs/callback/proc.h @@ -34,7 +34,7 @@ typedef struct proc_handler *proc_handler_t; proc_handler_t proc_handler_create(void *data); void proc_handler_destroy(proc_handler_t handler); -void proc_handler_add(proc_handler_t handler, const char *declaration, +void proc_handler_add(proc_handler_t handler, const char *name, void (*proc)(calldata_t, void*)); bool proc_handler_call(proc_handler_t handler, const char *name, diff --git a/libobs/callback/signal.c b/libobs/callback/signal.c index b78ccae66..ec2cb5d1f 100644 --- a/libobs/callback/signal.c +++ b/libobs/callback/signal.c @@ -14,4 +14,190 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "../util/darray.h" +#include "../util/threading.h" +#include "signal.h" + +struct signal_callback { + void (*callback)(calldata_t, void*); + void *data; +}; + +struct signal_info { + char *name; + DARRAY(struct signal_callback) callbacks; + pthread_mutex_t mutex; + + struct signal_info *next; +}; + +static inline struct signal_info *signal_info_create(const char *name) +{ + struct signal_info *si = bmalloc(sizeof(struct signal_info)); + si->name = bstrdup(name); + si->next = NULL; + da_init(si->callbacks); + + if (!pthread_mutex_init(&si->mutex, NULL) != 0) { + blog(LOG_ERROR, "Could not create signal!"); + bfree(si->name); + bfree(si); + return NULL; + } + + return si; +} + +static inline void signal_info_destroy(struct signal_info *si) +{ + if (si) { + pthread_mutex_destroy(&si->mutex); + bfree(si->name); + da_free(si->callbacks); + bfree(si); + } +} + +static inline size_t signal_get_callback_idx(struct signal_info *si, + void (*callback)(calldata_t, void*), void *data) +{ + for (size_t i = 0; i < si->callbacks.num; i++) { + struct signal_callback *sc = si->callbacks.array+i; + + if (sc->callback == callback && sc->data == data) + return i; + } + + return DARRAY_INVALID; +} + +struct signal_handler { + /* TODO: might be good to use hash table instead */ + struct signal_info *first; + pthread_mutex_t mutex; +}; + +static struct signal_info *getsignal(signal_handler_t handler, + const char *name, struct signal_info **p_last) +{ + struct signal_info *signal, *last= NULL; + + signal = handler->first; + while (signal != NULL) { + if (strcmp(signal->name, name) == 0) + break; + + last = signal; + signal = signal->next; + } + + if (p_last) + *p_last = last; + return signal; +} + +/* ------------------------------------------------------------------------- */ + +signal_handler_t signal_handler_create(void) +{ + struct signal_handler *handler = bmalloc(sizeof(struct signal_handler)); + handler->first = NULL; + + if (pthread_mutex_init(&handler->mutex, NULL) != 0) { + bfree(handler); + return NULL; + } + + return handler; +} + +void signal_handler_destroy(signal_handler_t handler) +{ + if (handler) { + struct signal_info *sig = handler->first; + while (sig != NULL) { + struct signal_info *next = sig->next; + signal_info_destroy(sig); + sig = next; + } + + pthread_mutex_destroy(&handler->mutex); + bfree(handler); + } +} + +void signal_handler_connect(signal_handler_t handler, const char *signal, + void (*callback)(calldata_t, void*), void *data) +{ + struct signal_info *sig, *last; + struct signal_callback cb_data = {callback, data}; + size_t idx; + + pthread_mutex_lock(&handler->mutex); + sig = getsignal(handler, signal, &last); + if (!sig) { + sig = signal_info_create(signal); + if (!last) + handler->first = sig; + else + last->next = sig; + + if (!sig) + return; + } + + pthread_mutex_unlock(&handler->mutex); + + /* -------------- */ + + pthread_mutex_lock(&sig->mutex); + + idx = signal_get_callback_idx(sig, callback, data); + if (idx == DARRAY_INVALID) + da_push_back(sig->callbacks, &cb_data); + + pthread_mutex_unlock(&sig->mutex); +} + +static inline struct signal_info *getsignal_locked(signal_handler_t handler, + const char *name) +{ + struct signal_info *sig; + + pthread_mutex_lock(&handler->mutex); + sig = getsignal(handler, name, NULL); + pthread_mutex_unlock(&handler->mutex); + + return sig; +} + +void signal_handler_disconnect(signal_handler_t handler, const char *signal, + void (*callback)(calldata_t, void*), void *data) +{ + struct signal_info *sig = getsignal_locked(handler, signal); + size_t idx; + + pthread_mutex_lock(&sig->mutex); + + idx = signal_get_callback_idx(sig, callback, data); + if (idx == DARRAY_INVALID) + da_erase(sig->callbacks, idx); + + pthread_mutex_unlock(&sig->mutex); +} + +void signal_handler_signal(signal_handler_t handler, const char *signal, + calldata_t params) +{ + struct signal_info *sig = getsignal_locked(handler, signal); + + pthread_mutex_lock(&sig->mutex); + + for (size_t i = 0; i < sig->callbacks.num; i++) { + struct signal_callback *cb = sig->callbacks.array+i; + cb->callback(params, cb->data); + } + + pthread_mutex_unlock(&sig->mutex); +} diff --git a/libobs/callback/signal.h b/libobs/callback/signal.h index dd1900c6a..9cdad6957 100644 --- a/libobs/callback/signal.h +++ b/libobs/callback/signal.h @@ -34,9 +34,9 @@ signal_handler_t signal_handler_create(void); void signal_handler_destroy(signal_handler_t handler); void signal_handler_connect(signal_handler_t handler, const char *signal, - void (*callback)(calldata_t, void*), void *param); + void (*callback)(calldata_t, void*), void *data); void signal_handler_disconnect(signal_handler_t handler, const char *signal, - void (*callback)(calldata_t. void*), void *param); + void (*callback)(calldata_t, void*), void *data); -void signal_handler_signal(signal_handler_t handler, const char *name, +void signal_handler_signal(signal_handler_t handler, const char *signal, calldata_t params); diff --git a/libobs/makefile.am b/libobs/makefile.am index 02c572ff8..6cbd3b7ee 100644 --- a/libobs/makefile.am +++ b/libobs/makefile.am @@ -52,7 +52,10 @@ libobs_la_SOURCES = obs.c \ graphics/texture-render.c \ graphics/vec2.c \ graphics/vec3.c \ - graphics/vec4.c + graphics/vec4.c \ + callback/calldata.c \ + callback/proc.c \ + callback/signal.c if OS_WIN libobs_la_SOURCES += util/platform-windows.c obs-windows.c diff --git a/obs/window-main-basic.cpp b/obs/window-main-basic.cpp index 424f0c206..0a81edb35 100644 --- a/obs/window-main-basic.cpp +++ b/obs/window-main-basic.cpp @@ -67,6 +67,10 @@ bool OBSBasic::InitGraphics() return true; } +void OBSBasic::AddScene(const char *name) +{ +} + void OBSBasic::OnClose(wxCloseEvent &event) { wxGetApp().ExitMainLoop(); diff --git a/obs/window-main-basic.hpp b/obs/window-main-basic.hpp index 0e49d44b9..1dfecd0c4 100644 --- a/obs/window-main-basic.hpp +++ b/obs/window-main-basic.hpp @@ -25,8 +25,6 @@ using namespace std; class OBSBasic : public OBSBasicBase { - vector scenes; - bool InitGraphics(); void NewProject(); @@ -62,6 +60,8 @@ public: bool Init(); + bool AddScene(const char *name); + inline wxPanel *GetPreviewPanel() {return previewPanel;} inline wxSizer *GetPreviewContainer() {return previewContainer;} }; diff --git a/vs/2013/libobs/libobs.vcxproj b/vs/2013/libobs/libobs.vcxproj index 002293e58..a0c7d31fd 100644 --- a/vs/2013/libobs/libobs.vcxproj +++ b/vs/2013/libobs/libobs.vcxproj @@ -20,6 +20,8 @@ + + @@ -67,6 +69,8 @@ + + diff --git a/vs/2013/libobs/libobs.vcxproj.filters b/vs/2013/libobs/libobs.vcxproj.filters index cfc51980b..e9e10deaf 100644 --- a/vs/2013/libobs/libobs.vcxproj.filters +++ b/vs/2013/libobs/libobs.vcxproj.filters @@ -195,6 +195,12 @@ callback\Header Files + + callback\Header Files + + + callback\Header Files + @@ -320,5 +326,11 @@ callback\Source Files + + callback\Source Files + + + callback\Source Files + \ No newline at end of file