Core API

Lifecycle and Call Order

Execution flow managed by PluginManager from plugin discovery to per-frame callbacks and unload.

  • include/vliva/plugins/plugin_api.h
  • include/vliva/plugins/plugin_manager.hpp
  • plugins/example_plugin.cpp

Full source: github.com/TamKungZ/VLiva

Section 1

Lifecycle Flow

PluginManager drives plugin lifecycle in a strict order. Each callback has a clear responsibility.

  • Load *.so plugins from a directory and resolve create_plugin symbol.
  • Read returned API table and verify api_version before activation.
  • Call on_load(host) once to provide host services.
  • Update tracking snapshot and call on_frame(time_seconds, delta_seconds) each frame.
  • Call on_unload() and unload every plugin during shutdown.

text

Host start
  -> PluginManager::loadFromDirectory("plugins")
  -> dlopen each shared library (.so)
  -> lookup create_plugin symbol
  -> validate VlivaPluginApi and call on_load(host)
  -> update tracking snapshot and call on_frame(time, delta)
  -> call on_unload() + dlclose() during shutdown

Section 2

PluginManager Host Bridge

PluginManager owns loaded plugin handles and bridges host services through static callbacks.

  • setTrackingFrame()/clearTrackingFrame() control what get_tracking_frame() returns.
  • setUdpSender() connects udp_configure()/udp_send() to host UDP implementation.
  • Mutex-protected state keeps shared plugin services safe across calls.

cpp

class PluginManager {
public:
    int loadFromDirectory(const std::string& directoryPath);
    void onFrame(double timeSeconds, float deltaSeconds);
    void setUdpSender(UdpSender* sender);
    void setTrackingFrame(const VlivaTrackingFrame& frame);
    void clearTrackingFrame();
    void unloadAll();

private:
    static void hostLog(const char* message);
    static int hostGetTrackingFrame(VlivaTrackingFrame* outFrame);
    static int hostUdpConfigure(const char* host, int port, int enabled);
    static int hostUdpSend(const char* payload);
};

Section 3

Implementation Guidelines

Keep plugin runtime stable and fail-safe across all callbacks.

  • Never assume host callback pointers are always available.
  • Avoid heavy work inside on_frame without throttling.
  • Keep initialization and shutdown idempotent where possible.
  • Preserve ABI safety: no exceptions across C ABI boundary.