engine: add init/project/timeline families to the C ABI facade
- oakengine_init/shutdown with HEADLESS/RENDER flags: headless boots Config, NodeFactory, ColorManager, task/conform/proxy/frame/disk managers and the serializer (plus an offscreen QGuiApplication that Qt requires for QAction); RENDER adds RenderManager. Idempotent and upgradable, no UI anywhere - oakengine_project_* (17): create/load/save, modified state, name, footage enumeration with online check, undo/redo, sequence access - oakengine_sequence_* (13): name, length (seconds and rational), frame rate, per-type track counts, playhead (timestamp and seconds), work area, markers; sequences are borrowed handles owned by their project - pure-C oakengine_init_test covers init idempotency, save/load round-trip through a real fixture project, footage online checks, timeline parameters, and NULL/bounds safety - no GL required
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
/***
|
||||
|
||||
Oak - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef OAKENGINE_INIT_H
|
||||
#define OAKENGINE_INIT_H
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file init.h
|
||||
* @brief C ABI for engine process initialization and shutdown
|
||||
*
|
||||
* oakengine_init() brings up the UI-independent engine services a consumer of
|
||||
* liboakengine needs before touching projects or timelines. It never creates
|
||||
* any UI: no QApplication, no main window, no display connection. When no
|
||||
* application object exists yet, an offscreen QGuiApplication is created (Qt
|
||||
* requires exactly one application object; it is leaked intentionally because
|
||||
* Qt cannot safely re-create one). A QGuiApplication -- not a plain
|
||||
* QCoreApplication -- is required because EngineCore's undo stack creates
|
||||
* QActions in its constructor, and Qt6 QActions need QGuiApplication state;
|
||||
* with the offscreen QPA plugin (the default, overridable through
|
||||
* QT_QPA_PLATFORM) nothing graphical ever happens.
|
||||
*
|
||||
* The flag mask selects the service set:
|
||||
*
|
||||
* - OAKENGINE_INIT_HEADLESS: Config, NodeFactory, ColorManager, TaskManager,
|
||||
* ConformManager, ProxyManager, FrameManager, DiskManager,
|
||||
* ProjectSerializer and a process-wide EngineCore shell (holds the global
|
||||
* undo stack and the EngineCore::instance() pointer engine code
|
||||
* dereferences). DiskManager is not part of EngineCore::start() but is
|
||||
* required because loading a project touches PlaybackCache state which
|
||||
* dereferences DiskManager::instance(). Everything here runs headless;
|
||||
* no GL is required.
|
||||
*
|
||||
* - OAKENGINE_INIT_RENDER: additionally creates the RenderManager. Only
|
||||
* with this bit may a consumer end up needing a GL context (the actual
|
||||
* render backends are dynamic engine plugins loaded on demand).
|
||||
*
|
||||
* Initialization is modelled on the render worker's headless bootstrap
|
||||
* (worker/workermain.cpp) rather than EngineCore::start(), because start()
|
||||
* unconditionally creates the RenderManager, starts the autorecovery timer
|
||||
* and reads the recent-projects list -- application behavior that does not
|
||||
* belong behind a library boundary.
|
||||
*
|
||||
* Conventions:
|
||||
* - Return codes: 0 (OAKENGINE_OK) on success, a negative OAKENGINE_E_*
|
||||
* error code on failure.
|
||||
* - oakengine_init() is idempotent: calling it again is a no-op for flag
|
||||
* bits already initialized and only brings up the missing bits (e.g.
|
||||
* upgrading HEADLESS to HEADLESS|RENDER).
|
||||
* - oakengine_shutdown() pairs with oakengine_init() and tears down the
|
||||
* initialized services in reverse order. The QCoreApplication and the
|
||||
* EngineCore shell are kept alive (see above), so oakengine_init() may be
|
||||
* called again afterwards.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Status and error codes shared by the init/project/timeline families.
|
||||
*/
|
||||
#define OAKENGINE_OK 0 /**< Success. */
|
||||
#define OAKENGINE_E_INVALID (-1) /**< NULL handle or invalid argument. */
|
||||
#define OAKENGINE_E_STATE (-2) /**< Call not valid in the current state. */
|
||||
#define OAKENGINE_E_FAILED (-3) /**< The engine reported a failure. */
|
||||
#define OAKENGINE_E_NOT_FOUND (-4) /**< Index out of range / entry not found. */
|
||||
|
||||
/** @brief Base headless engine services (no GL required). */
|
||||
#define OAKENGINE_INIT_HEADLESS 0x01
|
||||
/** @brief Render services on top of HEADLESS (may require GL). */
|
||||
#define OAKENGINE_INIT_RENDER 0x02
|
||||
|
||||
/**
|
||||
* @brief Initialize the engine services selected by `flags`.
|
||||
*
|
||||
* `flags` is a bitmask of OAKENGINE_INIT_HEADLESS and/or
|
||||
* OAKENGINE_INIT_RENDER; 0 is invalid. Repeated calls are idempotent and may
|
||||
* add the RENDER bit to a running HEADLESS instance.
|
||||
*
|
||||
* @return OAKENGINE_OK on success, OAKENGINE_E_INVALID for an empty mask.
|
||||
*/
|
||||
OAKENGINE_API int oakengine_init(int flags);
|
||||
|
||||
/**
|
||||
* @brief Tear down the services brought up by oakengine_init().
|
||||
*
|
||||
* Safe to call when not initialized (a no-op then). The QCoreApplication and
|
||||
* the EngineCore shell survive shutdown intentionally.
|
||||
*
|
||||
* @return OAKENGINE_OK.
|
||||
*/
|
||||
OAKENGINE_API int oakengine_shutdown(void);
|
||||
|
||||
/**
|
||||
* @brief Current initialization state as a flag bitmask (0 = not initialized).
|
||||
*
|
||||
* Only services that are actually up are reported, e.g. after upgrading a
|
||||
* HEADLESS instance with the RENDER bit the result includes both bits.
|
||||
*/
|
||||
OAKENGINE_API int oakengine_init_flags(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OAKENGINE_INIT_H */
|
||||
Reference in New Issue
Block a user