GmodNET/GmodDotNet

[ENH] Add a shortcut for pushing Lua Global Table to ILua interface

GlebChili opened this issue · 5 comments

Description

Pushing Lua Global table to the stack requires a lot of boilerplate code like lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB). Since working with Global table is the most common operation in GmodDotNet modules, and use cases for other special Lua tables are rare, we should introduce a shortcut for pushing Global table for better developer experience and code readability.

Possible solution

Add ILua.PushGlobalTable() to GmodNET.API.

What if it will be GmodNET.API.Extras namespace ILua extension?
Just to keep ILua clean

I think it is not an extra, but rather a very important part of GmodDotNet experience.

Possible code implementation:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PushGlobalTable() => this.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);

but i think about something like:

GlobalTable _G = new(lua);
Console.WriteLine(_G["SERVER"] as bool);
_G["print"]("message");
_G["PrintTable"](new []{1,2,3});

but i think about something like:

GlobalTable _G = new(lua);
Console.WriteLine(_G["SERVER"] as bool);
_G["print"]("message");
_G["PrintTable"](new []{1,2,3});

Using IDictionary to work with Lua tables is interesting, but naive implementation will only work for primitive types, like number and string.

but i think about something like:

GlobalTable _G = new(lua);
Console.WriteLine(_G["SERVER"] as bool);
_G["print"]("message");
_G["PrintTable"](new []{1,2,3});

Using IDictionary to work with Lua tables is interesting, but naive implementation will only work for primitive types, like number and string.

casting:

GlobalTable _G = new(lua);
GluaDelegates.print print = (GluaDelegates.print)_G["print"];
print("msg");

templates:

GlobalTable _G = new(lua);
GluaDelegates.print print = _G.Get<GluaDelegates.print>("print");
print("msg");

also templates:

GlobalTable _G = new(lua);
GluaDelegates.print print = _G.Get<GluaDelegates.print>(); // use Type.Name;
print("msg");

or make a class what binds whole lua api to use like:

GlobalTable _G = new(lua);
_G.print("msg");
string osname = _G.jit.os;
_G.print($"os is {osname}");

ILua class extension with ._G field:

// ILua lua
lua._G.print("message");
lua._G.MsgC(new Color(0, 255, 0, 255), "message");