pluginengine01 / cpp-cli /bex_engine.h
krystv's picture
Upload 107 files
3374e90 verified
#pragma once
/// @file bex_engine.h
/// @brief Pure C ABI for the Bex WASM Plugin Engine (v4).
///
/// This header defines the boundary between the Rust engine and any C/C++ consumer.
/// Rust implements these functions via `extern "C"`. C++ consumes them directly.
/// No bridge crate, no code generation β€” just link against libbex_runtime.
///
/// Architecture:
/// - All async operations return a request_id immediately.
/// - When the operation completes, Rust invokes the BexResultCallback from a
/// background Tokio thread.
/// - C++ must copy/parse the payload before the callback returns (payload is
/// owned by Rust and freed after the callback returns).
/// - Sync operations (install, uninstall, list, secrets) block until done.
///
/// Thread safety:
/// - bex_engine_new / bex_engine_free are NOT thread-safe.
/// - All bex_submit_* functions are thread-safe (internally synchronized).
/// - The callback is invoked from a Rust/Tokio background thread β€” the
/// callback implementation must be thread-safe.
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
// ── Opaque Engine Handle ───────────────────────────────────────────────
/// Opaque handle to the Rust BexEngine runtime.
typedef struct BexEngine BexEngine;
// ── Callback Signature ─────────────────────────────────────────────────
/// Universal async result callback.
///
/// Rust calls this from a background Tokio thread when an async task finishes.
///
/// @param user_data The opaque pointer passed to the submit function.
/// @param request_id The ID returned by the submit function.
/// @param success true if the operation succeeded, false on error.
/// @param payload Pointer to the result payload bytes (JSON string).
/// Owned by Rust β€” C++ must copy before returning.
/// @param payload_len Number of bytes in payload.
typedef void (*BexResultCallback)(
void* user_data,
uint64_t request_id,
bool success,
const uint8_t* payload,
size_t payload_len
);
// ── Plugin Info (returned by list/info sync calls) ─────────────────────
/// Information about a single installed plugin.
/// Returned by bex_engine_list_plugins and bex_engine_plugin_info.
typedef struct BexPluginInfo {
char* id; ///< Plugin identifier (e.g., "com.gogoanime")
char* name; ///< Human-readable plugin name
char* version; ///< Plugin version string
uint32_t capabilities; ///< Capability bitmask
bool enabled; ///< Whether the plugin is currently enabled
char* description; ///< Plugin description (may be empty)
char* author; ///< Plugin author (may be empty)
char* homepage; ///< Plugin homepage URL (may be empty)
} BexPluginInfo;
/// Array of BexPluginInfo structs returned by bex_engine_list_plugins.
typedef struct BexPluginInfoList {
BexPluginInfo* items; ///< Array of plugin info structs
size_t count; ///< Number of items in the array
} BexPluginInfoList;
// ── Lifecycle ──────────────────────────────────────────────────────────
/// Create a new BexEngine instance.
///
/// @param data_dir Path to the data directory (created if not exists).
/// @return Opaque engine handle, or NULL on failure.
BexEngine* bex_engine_new(const char* data_dir);
/// Free a BexEngine instance and release all resources.
///
/// This will wait for in-flight requests to complete (up to 10 seconds),
/// then shut down the Tokio runtime and release all memory.
///
/// @param engine The engine handle (may be NULL, in which case this is a no-op).
void bex_engine_free(BexEngine* engine);
// ── Plugin Management (synchronous) ────────────────────────────────────
/// Install a plugin from a .bex package file.
///
/// @param engine The engine handle.
/// @param path Filesystem path to the .bex package.
/// @return 0 on success, non-zero on error.
int bex_engine_install(BexEngine* engine, const char* path);
/// Uninstall a plugin by its ID.
///
/// @param engine The engine handle.
/// @param id The plugin identifier.
/// @return 0 on success, non-zero on error.
int bex_engine_uninstall(BexEngine* engine, const char* id);
/// List all installed plugins.
///
/// Returns a BexPluginInfoList. The caller must free it with
/// bex_plugin_info_list_free when done.
///
/// @param engine The engine handle.
/// @return List of installed plugins (empty list if none, never NULL).
BexPluginInfoList bex_engine_list_plugins(BexEngine* engine);
/// Get detailed info for a single plugin.
///
/// @param engine The engine handle.
/// @param id The plugin identifier.
/// @param out Pointer to a BexPluginInfo struct to fill.
/// @return 0 on success, non-zero if plugin not found.
int bex_engine_plugin_info(BexEngine* engine, const char* id, BexPluginInfo* out);
/// Enable a plugin.
int bex_engine_enable(BexEngine* engine, const char* id);
/// Disable a plugin.
int bex_engine_disable(BexEngine* engine, const char* id);
/// Free a BexPluginInfoList returned by bex_engine_list_plugins.
void bex_plugin_info_list_free(BexPluginInfoList list);
/// Free the strings inside a BexPluginInfo struct.
void bex_plugin_info_free(BexPluginInfo info);
// ── API Key / Secret Management (synchronous) ─────────────────────────
/// Set an API key/secret for a plugin.
///
/// @param engine The engine handle.
/// @param plugin_id The plugin identifier.
/// @param key The key name (e.g., "api_key").
/// @param value The key value.
/// @return 0 on success, non-zero on error.
int bex_engine_secret_set(BexEngine* engine, const char* plugin_id,
const char* key, const char* value);
/// Get an API key/secret value for a plugin.
///
/// @param engine The engine handle.
/// @param plugin_id The plugin identifier.
/// @param key The key name.
/// @param out_buf Buffer to write the value into.
/// @param out_buf_len Size of out_buf. On success, the actual length (excluding NUL) is written back.
/// @return 0 on success, non-zero if not found or error.
int bex_engine_secret_get(BexEngine* engine, const char* plugin_id,
const char* key, char* out_buf, size_t* out_buf_len);
/// Delete an API key/secret for a plugin.
///
/// @return 0 if deleted, 1 if key not found, negative on error.
int bex_engine_secret_delete(BexEngine* engine, const char* plugin_id,
const char* key);
/// List all secret key names for a plugin.
///
/// Returns a comma-separated string of key names. Caller must free with bex_string_free().
/// Returns NULL on error.
char* bex_engine_secret_keys(BexEngine* engine, const char* plugin_id);
/// Free a string returned by the engine (e.g., from bex_engine_secret_keys).
void bex_string_free(char* s);
// ── Async Operations ──────────────────────────────────────────────────
/// Submit a search request.
///
/// @param engine The engine handle.
/// @param plugin_id The plugin to use.
/// @param query The search query.
/// @param callback Called when the result is ready.
/// @param user_data Opaque pointer passed to the callback.
/// @return Request ID (non-zero). Returns 0 if engine is NULL or invalid.
uint64_t bex_submit_search(BexEngine* engine, const char* plugin_id,
const char* query,
BexResultCallback callback, void* user_data);
/// Submit a home page request.
uint64_t bex_submit_home(BexEngine* engine, const char* plugin_id,
BexResultCallback callback, void* user_data);
/// Submit a get_info request.
///
/// The media_id is opaque to the engine β€” the plugin knows how to interpret it.
uint64_t bex_submit_info(BexEngine* engine, const char* plugin_id,
const char* media_id,
BexResultCallback callback, void* user_data);
/// Submit a get_servers request.
///
/// The id is self-describing β€” the plugin knows how to parse its own IDs.
/// Example: "one-piece$ep=1$sub=1$dub=0"
uint64_t bex_submit_servers(BexEngine* engine, const char* plugin_id,
const char* id,
BexResultCallback callback, void* user_data);
/// Submit a resolve_stream request.
///
/// @param server_json JSON string representing a server entry (from get_servers result).
uint64_t bex_submit_stream(BexEngine* engine, const char* plugin_id,
const char* server_json,
BexResultCallback callback, void* user_data);
// ── Cancellation ──────────────────────────────────────────────────────
/// Cancel a pending async request.
///
/// @return true if the request was found and cancelled, false otherwise.
bool bex_cancel_request(BexEngine* engine, uint64_t request_id);
// ── Engine Stats (synchronous) ────────────────────────────────────────
/// Get engine statistics as a JSON string.
/// Caller must free the returned string with bex_string_free().
char* bex_engine_stats(BexEngine* engine);
// ── Last Error ────────────────────────────────────────────────────────
/// Get the last error message from a failed sync operation.
/// Returns NULL if no error. Caller must free with bex_string_free().
char* bex_engine_last_error(BexEngine* engine);
#ifdef __cplusplus
}
#endif