Skip to content

API & Extension Review

Jonathan Hoffstadt edited this page Oct 2, 2024 · 43 revisions

Table of Contents

Potential Reviewers

Before comfortably marking many of the existing APIs as 1.0, we'd like to get more eyes on them. At the moment the priority is NOT new features or implementation details. Many of these APIs are extremely minimal and that's on purpose and can be added to later.

Extendable

The 1st priority of these reviews is ensuring the APIs going into 1.0 do not box us in. An example of this could be something like this:

// initial design
plShaderModule pl_compile_glsl(const char* pcShader, const char* pcEntryFunc, bool bIncludeDebugInfo);

// better design
plShaderModule pl_compile_glsl(const char* pcShader, const char* pcEntryFunc, plShaderOptions*);

In this particular case, some obvious thought into the compiling shaders would have quickly revealed many additional parameters you may or may not want to add in the future. With the initial design, you would be forced to either break the API or add additional functions (further complicating the API). A better design in this case would be to pack options into a struct so additional members could be added in the future. This is not to say we should just have this apply to every function. Simplicity plays an important factor and if there truly is no foreseeable reason to need more parameters, then choose the simpler API.

The "tools" for adding additional functionality looks something like this (in order of preference):

  1. Add additional flags
  2. Add additional members to descriptor/options parameter
  3. Add "extended" version function with new parameters pl_compile_glsl_ext(...)
  4. Add new function These are in order of preference.

Compacting

Another thing to consider is "compacting" an API. For example:

// typical memory allocation functions
void* pl_alloc(size_t);          // allocate new memory
void  pl_free(void*);            // free memory
void* pl_realloc(void*, size_t); // reallocate memory

If you spent some time considering this API, you'd realize the API can be simplified to just the pl_realloc(...). For reallocations, just use the function like expected. To free memory, pass in the pointer and a size of 0. To allocator for the first time, just pass NULL for the data and a size > 0:

// allocate new memory
int* iData = pl_realloc(NULL, 1024);

// reallocate memory
iData = pl_realloc(iData, 2048);

// free memory
pl_realloc(iData, 0);

This is a more compact design. For users who prefer the less compact design, that can easily be created on top with either macros, inline functions, or regular functions.

More examples will be added. Please open an issue to discuss any review items.

Status

Status Legend

The status symbols found below will be used throughout this document, but I will further explain them here.

Symbol Description Notes
βœ”οΈ 1.0 API is stable (will not be broken) but can be added to
🟒 Review Needed Candidate for 1.0. Just need more eyes on the API
🟑 Beta Most of the API is stable but there are known changes needed
πŸ”΄ Active Development API is under active development and subject to frequent changes
πŸ“ Documentation Needed This doesn't hold up 1.0
πŸš₯ Tests Needed This doesn't hold up 1.0

Core

The Core of Pilot Light is very small and entirely contained in the src directory. The Core APIs are split into 2 categories. The Base category APIs are provided in the pl.h header file and are required by any Pilot Light application. The OS category APIs are optional and provided by the pl_os.h header file. The current status of these APIs can be found in the table below:

API Status Description
Base platform agnostic systems
API Registry βœ”οΈ πŸ“ πŸš₯
Data Registry βœ”οΈ πŸ“ πŸš₯
Extension Registry βœ”οΈ πŸ“ πŸš₯
IO βœ”οΈ πŸ“ πŸš₯ keyboard + mouse + event input/output
Memory βœ”οΈ πŸ“ πŸš₯ general memory allocator for tracking
OS provided by OS backends
Window βœ”οΈ πŸ“ πŸš₯ OS windowing
Library βœ”οΈ πŸ“ πŸš₯ shared library loading (dlls/so files)
File βœ”οΈ πŸ“ πŸš₯ simple file IO
Network βœ”οΈ πŸ“ πŸš₯ UDP/TCP API
Threads βœ”οΈ πŸ“ πŸš₯ basic thread & synchronization primitives
Atomics βœ”οΈ πŸ“ πŸš₯ basic atomic primitives
Virtual Memory βœ”οΈ πŸ“ πŸš₯ virtual memory access

Extension

If some functionality can be an extension, then it should be. Most of the real work is put into the extensions which are found in the extensions directory. The Standard extensions are those included directly in the Pilot Light code base. The current status of the APIs provided by these extensions can be found in the table below:

API Status File Description
Image 🟒 πŸ“ πŸš₯ pl_image_ext.h image loading
Stats βœ”οΈ πŸ“ πŸš₯ pl_stats_ext.h statistics
Rect Pack βœ”οΈ πŸ“ πŸš₯ pl_rect_pack_ext.h rectangle packing
Job βœ”οΈ πŸ“ πŸš₯ pl_job_ext.h basic job system
Model Loader 🟑 πŸ“ pl_model_loader_ext.h model loaders
GPU Allocators 🟑 πŸ“ πŸš₯ pl_gpu_allocators_ext.h GPU allocators
Shader 🟒 πŸ“ πŸš₯ pl_shader_ext.h shader compiling
Draw 🟒 πŸ“ πŸš₯ pl_draw_ext.h 2D/3D drawing
UI 🟑 πŸ“ πŸš₯ pl_ui_ext.h debug UI
Resource Manager πŸ”΄ πŸ“ πŸš₯ pl_resource_ext.h resource manager
Renderer πŸ”΄ πŸ“ pl_renderer_ext.h reference renderer
Graphics 🟑 πŸ“ pl_graphics_ext.h graphics API abstraction over Vulkan & Metal 2.0
ECS 🟑 πŸ“ pl_ecs_ext.h

Libraries

The Libraries are referring to the STB style libraries found in the libs directory. These are completely standalone libraries. The status of this can be seen below:

Library Status File Description
Data Structures βœ”οΈ πŸš₯ pl_ds.h minimal data structures
JSON βœ”οΈ πŸš₯ pl_json.h JSON parser
Log βœ”οΈ πŸš₯ pl_log.h logger
Math βœ”οΈ πŸš₯ pl_math.h math
Memory βœ”οΈ πŸš₯ pl_memory.h memory allocators
Profiler βœ”οΈ πŸš₯ pl_profile.h profiler
STL βœ”οΈ πŸš₯ pl_stl.h STL File parser
String βœ”οΈ πŸš₯ pl_string.h string utilities
Testing βœ”οΈ pl_test.h minimal testing library

API Interdependencies

From an API standpoint, most of the APIs are standalone. However, it is worth noting that some of their internal implementations do have interdependencies. Extensions are meant to be built upon by users however we do try to minimize interdependencies internally. For reference, the current interdependencies can be seen in the graph below:

flowchart BT
    stats((stats))
    image((image))
    job{job}
    ecs(ECS)
    graphics{graphics}
    ui(ui)
    draw(draw)
    shader(shader)
    renderer([renderer])
    resource(resource)
    gpu(GPU allocators)
    model(model loader)
    os[(OS)]

    stats ------> renderer
    image ------> renderer
    gpu ----> renderer
    ui --> renderer

    os -.-> job
    os -.-> graphics
    os -.-> model
    os -.-> renderer


    job --> renderer
    job --> ecs
    

    graphics --> shader
    graphics --> draw
    graphics --> gpu
    graphics --> resource

    shader --> draw
    shader --> renderer

    draw --> ui
    draw --> renderer
    
    ecs ----> renderer
    ecs --> model

    resource ----> renderer
    resource --> model
Loading

Some notes about the above graph:

  • All APIs depend on Core APIs. We do not show this.
  • Some APIs depend on OS provided APIs. This is shown since those APIs are considered optional.
  • Some APIs that aren't currently used by other APIs are not shown.

This can also be visualized somewhat as layers:

flowchart BT
    subgraph Libraries
        direction LR
        ds[[Data Structures]]
        json[[JSON]]
        log[[Log]]
        math[[Math]]
        mem[[Memory Allocators]]
        profile[[Profiler]]
        stl[[STL Parser]]
        string[[Strings]]
        test[[Testing]]
    end
    subgraph Core
        direction LR
        subgraph Base
            direction LR
            api([API Registry])
            data([Data Registry])
            memory([Memory Context])
            io([IO])
        end
        subgraph OS
            direction LR
            Window([Window])
            Library([Library])
            File([File])
            UDP([UDP])
            Threads([Threads])
            Atomics([Atomics])
        end
    end
    subgraph Standalone
        direction LR
        stats
        image
        rect_pack
        subgraph Partial
            direction LR
            graphics
            job
        end
    end
    subgraph Regular
        gpu(GPU Allocators)
        shader
        resource
        ecs(ECS)
        draw
        model(Model Loader)
        ui(UI)
        Renderer
    end
    Regular ~~~ App
    Libraries ~~~ Core
    Base ~~~ OS
    Core ~~~ Standalone
    Standalone ~~~ Regular
    Window ~~~ Library ~~~ File
    UDP ~~~ Threads ~~~ Atomics
    api ~~~ data
    memory ~~~ io
    graphics ~~~ job
    stats ~~~ image ~~~ rect_pack ~~~ Partial
    ds ~~~ json ~~~ log
    math ~~~ mem ~~~ profile
    stl ~~~ string ~~~ test
Loading

Contributor Docs

User Docs

Clone this wiki locally