NovelRT icon indicating copy to clipboard operation
NovelRT copied to clipboard

Interop support for the Configurator API and all plugins

Open DynamicField opened this issue 2 years ago • 1 comments

It's currently hard to get anything — such as a window, at least — popping on your screen with the C API. This PR implements the entire Configurator API and all of its plugins. Making your dreams of a game engine usable in C a reality.

What's implemented

  • NrtConfigurator: methods to add plugin providers, as well as default systems
  • All variants of IPluginProvider: (Graphics, Input, ResourceManagement, Windowing)
  • GraphicsProvider: barebones with only a Destroy method
  • IWindowingDevice: with all methods (except TearDown), such as ProcessMessages, GetShouldClose and WindowTitle manipulation
  • IInputDevice: with all methods (except Initialise and Update)
  • ResourceLoader: only the ResourceRootDirectory property has been implemented

Questionnable implementations and the reasoning behind them

LifetimeExtender

The AllObjects<T> function uses a templated static variable for each type, which can maybe cause issues with multiple TUs. However, linkers should automatically choose only one static variable across multiple TUs: that behavior is called vague linkage.

NrtConfigurator

The AddXPluginProvider methods use Lifetime::Find to get a shared_ptr of a plugin provider. This method uses linear search on all shared_ptrs created by the C API. It shouldn't be an issue considering we don't spawn thousands of PluginProviders, but it's something to note.

NrtInputActionList

I choose to implement a span of NovelRT::Input::InputAction instances with a struct that mimics an actual span:

typedef struct {
    NrtInputActionHandle begin;
    NrtInputActionHandle end;
    intptr_t increment; // sizeof(InputAction)
} NrtInputActionList;

Contrary to iterators, they demand more "discipline" to be used, but they are much more efficient for performance (no allocation, no need to call an externally-linked method every time), easier to implement (it's just one struct!) and it actually makes sense for a span. The intptr_t Nrt_InputActionList_IncrementSize() method is there if you want to make it a constant. (it's also pretty cool for a JIT!)

DynamicField avatar Aug 02 '22 18:08 DynamicField

Note: may need to squash commits upon approval

capnkenny avatar Sep 02 '22 20:09 capnkenny

Update for this - I've gone ahead and implemented the resource loader APIs. I don't know how it affects your plugin support, but please review it.

RubyNova avatar Oct 23 '22 14:10 RubyNova

Update for this - I did the changes and adapted the existing code to the new APIs, the only thing missing is... the tests.

DynamicField avatar Oct 23 '22 17:10 DynamicField

If you can't test some of it that's fine, just test what you can, we need to get this moving.

RubyNova avatar Oct 23 '22 17:10 RubyNova