diff --git a/docs/sphinx/reference-core.rst b/docs/sphinx/reference-core.rst index d6be06d6d416ea..7ad790d46e0e28 100644 --- a/docs/sphinx/reference-core.rst +++ b/docs/sphinx/reference-core.rst @@ -617,6 +617,9 @@ Primary signal/procedure handlers Core OBS Signals ---------------- +Use :c:func:`signal_handler_connect()` to connect callbacks to the following +core OBS signals: + **source_create** (ptr source) Called when a source has been created. diff --git a/docs/sphinx/reference-libobs-callback.rst b/docs/sphinx/reference-libobs-callback.rst index 494efa23b820c8..f1bce2df4e1583 100644 --- a/docs/sphinx/reference-libobs-callback.rst +++ b/docs/sphinx/reference-libobs-callback.rst @@ -62,7 +62,7 @@ handlers or to procedure handlers. .. function:: void calldata_set_ptr(calldata_t *data, const char *name, void *ptr) - Sets a pointer parameter. + Sets a pointer parameter. This does not have to be a pointer to a pointer. :param data: Calldata structure :param name: Parameter name @@ -80,6 +80,18 @@ handlers or to procedure handlers. --------------------- +.. function:: void calldata_set_data(calldata_t *data, const char *name, const void *in, size_t new_size) + + Sets a parameter with any type. For common parameter types, use the functions + above. + + :param data: Calldata structure + :param name: Parameter name + :param in: Pointer to the value to be stored + :param new_size: Size of the value to be stored + +--------------------- + .. function:: long long calldata_int(const calldata_t *data, const char *name) Gets an integer parameter. @@ -132,6 +144,75 @@ handlers or to procedure handlers. --------------------- +.. function:: bool calldata_get_int(const calldata_t *data, const char *name, long long *val) + + Gets an integer parameter. See :c:func:`calldata_int` for a simpler call. + + :param data: Calldata structure + :param name: Parameter name + :param val: Pointer to an integer receiving the parameter + :return: ``true`` if the stored value is successfully cast + +--------------------- + +.. function:: bool calldata_get_float(const calldata_t *data, const char *name, double *val) + + Gets a floating point parameter. See :c:func:`calldata_float` for a simpler + call. + + :param data: Calldata structure + :param name: Parameter name + :param val: Pointer to a floating point receiving the parameter + :return: ``true`` if the stored value is successfully cast + +--------------------- + +.. function:: bool calldata_get_bool(const calldata_t *data, const char *name, bool *val) + + Gets a boolean parameter. See :c:func:`calldata_bool` for a simpler call. + + :param data: Calldata structure + :param name: Parameter name + :param val: Pointer to a boolean receiving the parameter + :return: ``true`` if the stored value is successfully cast + +--------------------- + +.. function:: bool calldata_get_ptr(const calldata_t *data, const char *name, void *p_ptr) + + Gets a pointer parameter. See :c:func:`calldata_ptr` for a simpler call. + + :param data: Calldata structure + :param name: Parameter name + :param p_ptr: Pointer to a pointer receiving the parameter + :return: ``true`` if the stored value is successfully cast + +--------------------- + +.. function:: bool calldata_get_string(const calldata_t *data, const char *name, const char **str) + + Gets a string parameter. See :c:func:`calldata_string` for a simpler call. + + :param data: Calldata structure + :param name: Parameter name + :param str: Pointer to a string receiving the parameter + :return: ``true`` if the stored value is successfully cast + +--------------------- + +.. function:: bool calldata_get_data(const calldata_t *data, const char *name, void *out, size_t size); + + Gets a parameter of any type. For common parameter types, use the functions + above. + + :param data: Calldata structure + :param name: Parameter name + :param out: Pointer receiving the parameter + :param size: Size of the parameter type + :return: ``true`` if the stored value has the correct size + +--------------------- + Signals ------- @@ -173,20 +254,61 @@ Signals are used for all event-based callbacks. .. function:: bool signal_handler_add(signal_handler_t *handler, const char *signal_decl) - Adds a signal to a signal handler. + Adds a signal to a signal handler. Will fail if the declaration string has + invalid syntax or a signal with the same name was already added. Other than + the function identifier, the ``decl_string`` is mostly for documentation, as + libobs does not strictly enforce how the parameters are handled. :param handler: Signal handler object - :param signal_decl: Signal declaration string + :param signal_decl: C-style function declaration string of the signal. The + function identifier dictates the signal name. Parameter + types can be ``int``, ``float``, ``bool``, ``ptr``, + ``string``, which indicates the appropriate calldata + function to get the parameters. May also be preceded by + ``in`` or ``out`` indicating how the parameters are used. + :return: ``true`` if the signal is successfully added. + + Example declaration strings: + + - ``void restart()`` + - ``void slide_changed(int index, string path)`` + - ``void current_index(out int current_index)`` + - ``int current_index()`` + - ``void toggled()`` + + Example code: + + .. code:: cpp + + signal_handler_t *sh = obs_source_get_signal_handler(source); + signal_handler_add(sh, "void file_changed(string next_file)"); --------------------- .. function:: bool signal_handler_add_array(signal_handler_t *handler, const char **signal_decls) - Adds multiple signals to a signal handler. + Adds multiple signals to a signal handler. This will process all signals even + if some can not be successfully added. :param handler: Signal handler object :param signal_decls: An array of signal declaration strings, terminated by *NULL* + :return: ``true`` if all signals are successfully added. + ``false`` if any of the signals can not be added + + Example: + + .. code:: cpp + + static const char *source_signals[] = { + "void destroy(ptr source)", + "void remove(ptr source)", + "void update(ptr source)", + NULL, + }; + + signal_handler_t *sh = obs_source_get_signal_handler(source); + signal_handler_add_array(sh, source_signals); --------------------- @@ -203,6 +325,40 @@ Signals are used for all event-based callbacks. For scripting, use :py:func:`signal_handler_connect`. + Example connecting to ``rename`` signal from :ref:`source_signal_handler_reference`, + declared as ``void rename(ptr source, string new_name, string prev_name)``: + + .. code:: cpp + + /* Sample source data */ + struct my_source { + obs_source_t *source; + char *prev_name; + ... + }; + + void rename_cb(void *data, calldata_t *cd) { + struct my_source *ms = data; + obs_source_t *source = calldata_ptr(cd, "source"); + /* We could also just access the source from our source data */ + source = ms->source; + const char *new_name = calldata_string(cd, "new_name"); + const char *prev_name = calldata_string(cd, "prev_name"); + + /* Do processing here */ + + /* `prev_name` will be freed after the callback, so if we want a + * reference to it after the callback, we must duplicate it. + */ + bfree(ms->prev_name); + ms->prev_name = bstrdup(prev_name); + } + + /* Assuming `ms` already contains our source data */ + struct my_source *ms; + signal_handler_t *sh = obs_source_get_signal_handler(ms->source); + signal_handler_connect(sh, "rename", rename_cb, ms); + --------------------- .. function:: void signal_handler_connect_ref(signal_handler_t *handler, const char *signal, signal_callback_t callback, void *data) @@ -237,12 +393,28 @@ Signals are used for all event-based callbacks. .. function:: void signal_handler_signal(signal_handler_t *handler, const char *signal, calldata_t *params) - Triggers a signal, calling all connected callbacks. + Emits a signal, calling all connected callbacks. :param handler: Signal handler object - :param signal: Name of signal to trigger + :param signal: Name of signal to emit :param params: Parameters to pass to the signal + Example: + + .. code:: cpp + + obs_source_t *source = obs_get_source_by_name("Image Slideshow Source"); + + /* Declaration string: void slide_changed(int index, string path) */ + calldata_t cd = {0}; + calldata_set_int(&cd, "index", 1); + calldata_set_string(&cd, "path", "path/to/image.png"); + + signal_handler_t *sh = obs_source_get_signal_handler(source); + signal_handler_signal(sh, "slide_changed", &cd); + calldata_free(&cd); + obs_source_release(source); + --------------------- @@ -287,13 +459,46 @@ direct access to declarations or callback pointers. .. function:: void proc_handler_add(proc_handler_t *handler, const char *decl_string, proc_handler_proc_t proc, void *data) - Adds a procedure to a procedure handler. + Adds a procedure to a procedure handler. Will fail if the declaration string + has invalid syntax or a procedure with the same name was already added. Other + than the function identifier, the ``decl_string`` is mostly for + documentation, as libobs does not strictly enforce how the parameters are + handled. :param handler: Procedure handler object - :param decl_string: Procedure declaration string + :param decl_string: C-style function declaration string of the procedure. The + function identifier dictates the procedure name. + Parameter types can be ``int``, ``float``, ``bool``, + ``ptr``, ``string``, which indicates the appropriate + calldata function to get the parameters. May also be + preceded by ``in`` or ``out`` indicating how the + parameters are used. :param proc: Procedure callback :param data: Private data to pass to the callback + Example code: + + .. code:: cpp + + /* Sample source data */ + struct my_source { + obs_source_t *source; + bool active; + ... + }; + + static void proc_activate(void *data, calldata_t *cd) + { + struct my_source *ms = data; + ms->active = calldata_bool(cd, "active"); + } + + /* Assuming `ms` already contains our source data */ + struct my_source *ms; + proc_handler_t *ph = obs_source_get_proc_handler(ms->source); + proc_handler_add(ph, "void activate(bool active)", + proc_activate, ms); + --------------------- .. function:: bool proc_handler_call(proc_handler_t *handler, const char *name, calldata_t *params) @@ -303,3 +508,15 @@ direct access to declarations or callback pointers. :param handler: Procedure handler object :param name: Name of procedure to call :param params: Calldata structure to pass to the procedure + :return: ``true`` if the procedure exists + + Example: + + .. code:: cpp + + /* Assuming we already have a `source` */ + proc_handler_t *ph = obs_source_get_proc_handler(source); + calldata_t cd = {0}; + calldata_set_bool(&cd, "active", false); + proc_handler_call(ph, "activate", &cd); + calldata_free(&cd); diff --git a/docs/sphinx/reference-sources.rst b/docs/sphinx/reference-sources.rst index 4729e055d8adee..290883f19b7524 100644 --- a/docs/sphinx/reference-sources.rst +++ b/docs/sphinx/reference-sources.rst @@ -547,6 +547,11 @@ Source Definition Structure (obs_source_info) Common Source Signals --------------------- +Sources can emit signals on specific events using signal handlers, with +callbacks connected via :c:func:`signal_handler_connect()`. Define signals with +:c:func:`signal_handler_add()` or :c:func:`signal_handler_add_array()`, and emit +them using :c:func:`signal_handler_signal()`. + The following signals are defined for every source type: **destroy** (ptr *source*) @@ -719,6 +724,10 @@ The following signals are defined for every source type: Source-specific Signals ----------------------- +The following is a list of signals defined by sources included with official OBS +Studio releases. For sources defined by third-party plugins, refer to the +plugin's documentation or source code to see the defined signals. + **slide_changed** (int index, string path) Called when the source's currently displayed image changes. @@ -760,6 +769,13 @@ Source-specific Signals Source-specific Procedures -------------------------- +Using procedure handlers, sources can allow external code to execute specific +actions. These actions are defined using :c:func:`proc_handler_add()` and called +by external code using :c:func:`proc_handler_call()`. For sources created by +plugins not included in official OBS Studio releases, check the plugin's +documentation or source code to determine whether custom procedures are defined +and what they do. + The following procedures are defined for specific sources only: **current_index** (out int current_index)