Skip to content

vladbelousoff/element-oak-bridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

element-oak-bridge

Header-only C++20 bridge between the Element ECS and the Oak scripting runtime.

The bridge lets Oak scripts declare and run ECS systems over native elm components. It is optional: pure ECS users only need Element. Reach for the bridge when you want gameplay or logic authored in Oak to drive elm::Registry data.

The single public header is include/elm/oak_bridge_core.hpp. All bridge symbols live in the oak_bridge namespace.

Requirements

  • A C++20 compiler.
  • Element, consumed as the element Meson dependency.
  • An Oak checkout providing the Oak headers and a runtime library (for example libacorn).

Building and Consuming

This project is header-only, so there is nothing to compile on its own. It exposes the element-oak-bridge Meson dependency, which adds the bridge include directory plus the Oak include paths that elm/oak_bridge_core.hpp needs. It does not build Oak itself.

oak_root is required and must point at your Oak source root:

meson setup build path/to/element-oak-bridge -Doak_root=/path/to/oak

Consume it from another Meson project:

element_oak_bridge_dep = dependency('element-oak-bridge', required: true)
oak_runtime_dep = cpp.find_library('acorn', dirs: '/path/to/oak/build')

executable('my_oak_target',
  'main.cpp',
  dependencies: [element_oak_bridge_dep, oak_runtime_dep],
)

The dependency adds Oak include paths for headers under:

  • ${OAK_ROOT}/include
  • ${OAK_ROOT}/src/runtime
  • ${OAK_ROOT}/src/common
  • ${OAK_ROOT}/src/compiler/internal

You are still responsible for providing and linking the Oak runtime/library your application uses. In a typical setup that runtime is imported from ${OAK_BUILD}/libacorn.so.

Integration Overview

A typical Oak integration does this at startup:

  1. Include elm/oak_bridge_core.hpp.
  2. Create an object that implements oak_bridge::BridgeInterface for your application.
  3. Store the bridge's oak_bridge::BridgeInterface* in each Oak VM's user_data.
  4. Initialize Oak through either the oak.hpp RAII wrappers or the raw C API.
  5. Register your C++ component types with oak_bridge::ComponentBuilder<T>.
  6. Call oak_bridge::register_common_native_functions(...) and oak_bridge::register_attributes(...).
  7. Load an Oak entry file with oak_bridge::load_program(...).
  8. Convert @ElementSystem functions into elm::System values with oak_bridge::build_systems(...).
  9. Rebuild view caches before each tick with oak_bridge::rebuild_view_caches(...).
  10. Run the generated systems through the same scheduler you use for C++ systems.

Minimal shape:

#include <elm/oak_bridge_core.hpp>

#include <vector>

struct Position {
    float x = 0.0f;
    float y = 0.0f;
};

struct Velocity {
    float x = 0.0f;
    float y = 0.0f;
};

class MyBridge final : public oak_bridge::BridgeInterface {
    // Store an elm::Registry, Oak allocator/VM state, component slots,
    // view caches, and implement the BridgeInterface virtual functions.
};

int main()
{
    MyBridge bridge;
    std::vector<elm::System> systems;

    // During setup, after creating Oak compile options and the Oak Entity type:
    // oak_bridge::ComponentBuilder<Position>(compile_opts, entity_type, "Position")
    //     .field<&Position::x>("x")
    //     .field<&Position::y>("y")
    //     .register_component(register_component);
    // oak_bridge::ComponentBuilder<Velocity>(compile_opts, entity_type, "Velocity")
    //     .field<&Velocity::x>("x")
    //     .field<&Velocity::y>("y")
    //     .register_component(register_component);
    // oak_bridge::register_attributes(compile_opts, components, pending_systems, &bridge);
    // auto program = oak_bridge::load_program("scripts/main.oak", compile_opts, allocator, vm, module_registry);
    // oak_bridge::build_systems(program.chunk, allocator, entity_type, module_registry,
    //                          components, pending_systems, slot_view_types,
    //                          slots, &delta_seconds, systems);

    // Each tick:
    // oak_bridge::rebuild_view_caches(registry, view_caches, slots, slot_count);
    // for (auto& system : systems) {
    //     system.run(registry);
    // }

}

Using oak.hpp

The bridge includes Oak's C++20 facade and accepts its RAII wrappers directly. This gives bridge integrations ownership-safe values, allocators, VMs, compile options, module registries, typed bindings, callable bindings, and diagnostics while preserving the raw C API overloads used by existing integrations.

oak::Allocator allocator;
oak::CompileOptions options(allocator);
oak::VM vm(allocator);
oak::ModuleRegistry modules(allocator);

options.with_stdlib();
vm.set_user_data(static_cast<oak_bridge::BridgeInterface*>(&bridge));

auto entity = options.bind_type<elm::Entity>("Entity", OAK_BIND_TYPE_VALUE);
oak_bridge::register_common_native_functions(options, entity.raw());
oak_bridge::register_attributes(options, entity.raw(), components,
                                view_slot_indices, pending_systems,
                                slot_view_types, attribute_state);

auto program = oak_bridge::load_program("scripts/main.oak", options, vm, modules);

Use oak::CompileOptions::bind_fn, bind_type, bind_enum, and bind_attr alongside the bridge registrations to expose application-specific Oak APIs.

Oak-generated systems are plain elm::System values, so they run through the same scheduler as your C++ systems. See the Element README for scheduler and conflict-detection details.

Relationship to Element and Oak

  • Element — the header-only ECS core. Usable on its own, with no Oak dependency.
  • Oak — the scripting language and runtime that authors systems.
  • element-oak-bridge (this repo) — depends on Element and adds Oak on top, wiring Oak VM calls into elm::System execution.

About

Header-only C++20 bridge between the Element ECS and the Oak scripting runtime.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors