|
CX Framework
Cross-platform C utility framework
|
Macros | |
| #define | cchainAttach(chain, func, ...) _cchainAttach(chain, func, 0, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ }) |
| #define | cchainAttachToken(chain, func, token, ...) _cchainAttach(chain, func, token, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ }) |
| #define | cchainCall(chain, ...) _cchainCall(chain, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ }) |
| #define | cchainCallOnce(chain, ...) _cchainCallOnce(chain, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ }) |
Functions | |
| bool | cchainDetach (cchain *chain, closureFunc func, intptr token) |
| bool | cchainTransfer (cchain *dest, cchain *src) |
| bool | cchainClone (cchain *dest, _In_ptr_opt_ cchain *src) |
| bool | cchainReset (cchain *chain) |
| bool | cchainClear (cchain *chain) |
| void | cchainDestroy (cchain *chain) |
Thread-safe linked lists of closures for implementing multi-callback event systems.
Closure chains are the recommended way to implement event handlers that can have multiple subscribers. They provide thread-safe attachment and detachment of callbacks, with optional tokens for selective removal.
Key features:
The token, if provided, is automatically added as the last captured variable in each closure, after any variables passed to cchainAttach().
Basic usage:
Using tokens for selective detachment:
| #define cchainAttach | ( | chain, | |
| func, | |||
| ... | |||
| ) | _cchainAttach(chain, func, 0, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ }) |
bool cchainAttach(cchain *chain, closureFunc func, ...)
Attach a closure to the chain without a token.
Adds a new closure to the chain with the specified function and captured variables. Can fail if the chain has been consumed by cchainCallOnce().
| chain | Pointer to closure chain (may be NULL, will be initialized) |
| func | Closure function to attach |
| ... | Zero or more stvar arguments to capture |
| #define cchainAttachToken | ( | chain, | |
| func, | |||
| token, | |||
| ... | |||
| ) | _cchainAttach(chain, func, token, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ }) |
bool cchainAttachToken(cchain *chain, closureFunc func, intptr token, ...)
Attach a closure to the chain with an identifying token.
The token should be a nonzero value that can be used to selectively detach this specific closure instance using cchainDetach(). The token is automatically added as the last captured variable passed to the closure function.
| chain | Pointer to closure chain (may be NULL, will be initialized) |
| func | Closure function to attach |
| token | Nonzero identifier for this closure instance |
| ... | Zero or more stvar arguments to capture |
| #define cchainCall | ( | chain, | |
| ... | |||
| ) | _cchainCall(chain, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ }) |
bool cchainCall(cchain *chain, ...)
Call all closures in the chain with the given arguments.
Invokes each closure in the chain, passing the provided arguments. Returns true only if all closures return true. The chain is cloned internally before calling, so callbacks can take arbitrary time without blocking other threads.
Note: Unlike closureCall(), this requires a pointer to the chain (not the chain itself) to perform atomic reads for thread safety.
| chain | Pointer to closure chain |
| ... | Zero or more stvar arguments to pass to each closure |
| #define cchainCallOnce | ( | chain, | |
| ... | |||
| ) | _cchainCallOnce(chain, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ }) |
bool cchainCallOnce(cchain *chain, ...)
Call all closures in the chain once, then invalidate the chain.
Atomically calls all closures and marks the chain as invalid, preventing future attachments. This is useful for one-time events to avoid race conditions where callbacks might be added after the event has already fired.
| chain | Pointer to closure chain (will be invalidated) |
| ... | Zero or more stvar arguments to pass to each closure |
| bool cchainClear | ( | cchain * | chain | ) |
Remove all closures from the chain
Clears all closures from the chain but leaves it in a valid state for future attachments. Unlike cchainDestroy(), the chain can be reused after calling this.
| chain | Pointer to closure chain |
| bool cchainClone | ( | cchain * | dest, |
| _In_ptr_opt_ cchain * | src | ||
| ) |
Clone a closure chain to a new location
Creates a copy of all closures in src and adds them to dest. Unlike transfer, the source chain remains valid and usable. Cloned closures are inserted before any existing closures in dest.
| dest | Destination chain pointer |
| src | Source chain pointer (remains valid) |
| void cchainDestroy | ( | cchain * | chain | ) |
Destroy a closure chain and all its closures
Frees all closures and invalidates the chain. The chain cannot be used after this call.
| chain | Pointer to closure chain |
| bool cchainDetach | ( | cchain * | chain, |
| closureFunc | func, | ||
| intptr | token | ||
| ) |
Detach a closure from the chain
Attempts to remove a previously attached closure from the chain. The function pointer and token must both match the values used when attaching (use 0 for token if none was specified).
| chain | Pointer to closure chain |
| func | Closure function to detach |
| token | Token that was used when attaching (0 if none) |
| bool cchainReset | ( | cchain * | chain | ) |
Reset a previously invalidated closure chain
Resets a chain that was invalidated by cchainCallOnce() or cchainTransfer() so it can be reused. Only works on chains that are in the invalid state.
| chain | Pointer to invalidated closure chain |
| bool cchainTransfer | ( | cchain * | dest, |
| cchain * | src | ||
| ) |
Transfer a closure chain to a new location
Safely moves the chain from src to dest, invalidating the source. The transferred chain is inserted before any existing closures in dest. Future attach attempts to src will fail.
| dest | Destination chain pointer |
| src | Source chain pointer (will be invalidated) |