Skip to content

dngulin/ksi

Repository files navigation

ѯ-Framework

That letter is pronounced as /ksi/

About

openupm

Warning

The project is in the beta version stage.
It is fully functional and covered with unit tests, but requires usage feedback to reveal issues and to improve the API.

This unity package provides a data-oriented design framework for Unity. It relies on the special attribute (trait) system and extensively uses Roslyn analyzers and code generators.

The framework enforces explicit data ownership and data flow patterns, implies using data references and provides compile time memory-safety checks.

Key features:

  • Fully Burst-compatible
  • Dynamic collections with by-reference data access
    var list = RefList.Empty<int>();
    list.Add(42);
    ref var x = ref list.RefAt(0);
    x = 3;
    list.RefAt(0) = 0; // Same as the `x = 0`
  • Data access control based on the data mutability
    // This API call is possible if you have ANY REFERENCE to the data
    public static ref readonly T RefReadonlyAt<T>(this in RefList<T> self, int index);
    
    // This API call is possible only if you have a MUTABLE REFERENCE to the data
    public static ref T RefAt<T>(this ref RefList<T> self, int index);
  • Deallocation management extensions
    [ExplicitCopy, DynSized, Dealloc]
    public struct Node { public RefList<Node> Children; }
    
    var root = new Node();
    BuildTree(ref root);
    root.Children.RemoveAt(0); // This extension method deallocate item before removing it
    root.Dealloc(); // This extension method deallocate the full tree
  • Compile time memory safety checks
    var list = RefList.Empty<int>();
    PopulateList(ref list);
    
    ref var x = ref list.RefAt(0);
    ModifyList(ref list);
    //             ^^^^ ERROR
    // BORROW03: Passing a mutable reference argument to `list!` invalidates memory safety
    // guaranties for the local variable `x` pointing to `list![n]`.
    // Consider to pass a readonly/[DynNoResize] reference to avoid the problem
    x++;
    ProcessParentAndChild(ref list, list.RefReadonlyAt(0));
    //                        ^^^^ ERROR
    // BORROW04: Passing a mutable reference to `list!` alongside with a reference to
    // `list[n]!` as arguments invalidates memory safety rules within the calling method.
    // Consider to pass a readonly/[DynNoResize] reference to avoid the problem
  • ECS-like data composition and queries
    // ѯ-Framework generates `public static void Tick(ref Domain domain, ref SomeData d)`
    // that iterates over entities in the domain and passes them to the method below
    [KsiQuery]
    private static void Tick(
        in Domain.KsiHandle h, // Current entity address
        ref ComponentA a,
        ref ComponentB b,
        [KsiQueryParam] ref SomeData d // External parameter
    )
    {
        // Modify components here
    }
  • HashSet and HashMap collections
    [KsiHashTable]
    public partial struct MyHashMap { ... }
    
    var map = MyHashMap.Empty;
    map.RefSet(key) = value;
    ref var valRef = ref map.RefGet(key);

Planned:

Documentation

See also:

Installation

  • Ensure that the .NET API compatibility level provides Netstandard 2.1 API (Unity 2021.2+)
  • Add the package to your project from OpenUPM or from the git URL [email protected]:dngulin/ksi.git#1.0.0-beta

About

Data-oriented framework for Unity

Resources

License

Stars

Watchers

Forks

Languages