Skip to content
This repository was archived by the owner on Nov 12, 2025. It is now read-only.

Commit 8280926

Browse files
committed
2.0.0
* Export all lua c api functions as real functions rather than lazy cells (Get function pointers from LUA_SHARED_RAW instead..) * Add [NOREF] [REFNIL] constants for the ref system * Add linux/osx support to finding lua_shared ( I still have no way to test this out yet, so as of now I am assuming it works fine. Create an issue if there's problems) * Added iface! macro to easily get access to interfaces. Updated the iengine example accordingly.
1 parent f51fa1d commit 8280926

File tree

17 files changed

+385
-323
lines changed

17 files changed

+385
-323
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,18 @@ Here's a comparison and why you could use this one.
2222

2323
| Library | [rglua] | [rust-glua-sys] | [gmod-rs] | [gmrs] |
2424
|-----------------------------------|---------|-----------------|-------------|--------|
25-
| *Full* Lua C Api Bindings | ✔️ | * |||
25+
| *Full* Lua C Api Bindings | ✔️ | |||
2626
| On Crates.io | ✔️ || ✔️ ||
2727
| Proc Macros | ✔️ || ✔️ | ✔️ |
2828
| Interfacing w/ Source SDK | ✔️ ||||
2929
| Returning Result<> from functions | ✔️ ||| ✔️ |
3030
| Can be used on stable | ✔️ | ✔️ || ✔️ |
31-
| Real world examples | ✔️ || ✔️ ||
31+
| Real world examples | ✔️ || 〰️ ||
32+
| Linux / OSX Support | ✔️ || ✔️ | ✔️ |
3233
| Github Stars | 😢 | 👍 | 👑 | 🤷‍♂️ |
3334

3435
__*You can help with that last one 😉*__
3536

36-
\* They technically do, but they depend on autogenerated bindings which is inaccurate for gmod, leading to missing functions. (See lua_resume_real)
37-
3837
## Acknowledgements
3938
### [garrysmod_common](https://github.com/danielga/garrysmod_common)
4039
This is heavily based off of garrysmod_common, in how we export the lua_shared functions and trying to replicate everything from the Lua C Api.

examples/engine/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "gmod_engine"
33
description = "Binary module that accesses engine.dll"
4-
version = "0.2.0"
4+
version = "0.3.0"
55
edition = "2021"
66
publish = false
77

@@ -10,4 +10,3 @@ crate-type = ["cdylib"]
1010

1111
[dependencies]
1212
rglua = { path = "../../rglua" }
13-
anyhow = "1.0.51"

examples/engine/src/lib.rs

Lines changed: 27 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,69 @@
1-
use rglua::interface::{get_from_interface, get_interface_handle, EngineClient};
1+
use rglua::interface::{EngineClient};
22
use rglua::prelude::*;
33

4-
use anyhow::bail;
5-
6-
fn get_iface() -> anyhow::Result<&'static EngineClient> {
7-
let handle = unsafe { get_interface_handle("engine.dll")? };
8-
let iface = get_from_interface("VEngineClient015", handle)? as *mut EngineClient;
9-
match unsafe { iface.as_ref() } {
10-
Some(iface) => Ok(iface),
11-
None => bail!("Failed to get interface"),
12-
}
4+
fn get_iface() -> Option<&'static EngineClient> {
5+
let iface: *mut EngineClient = iface!("engine", "VEngineClient015")?;
6+
unsafe { iface.as_ref() }
137
}
148

159
#[lua_function]
1610
fn concmd(l: LuaState) -> i32 {
17-
match get_iface() {
18-
Ok(iface) => {
19-
iface.ExecuteClientCmd( luaL_checklstring(l, 1, 0) );
20-
}
21-
Err(e) => printgm!(l, "{}", e)
11+
if let Some(iface) = get_iface() {
12+
iface.ExecuteClientCmd( luaL_checklstring(l, 1, 0) );
2213
}
2314
0
2415
}
2516

2617
#[lua_function]
2718
fn get_resolution(l: LuaState) -> i32 {
28-
match get_iface() {
29-
Ok(iface) => unsafe {
30-
let (w, h): (*mut _, *mut _) = (&mut 0, &mut 0);
31-
iface.GetScreenSize(w, h);
19+
if let Some(iface) = get_iface() {
20+
let (w, h): (*mut _, *mut _) = (&mut 0, &mut 0);
21+
iface.GetScreenSize(w, h);
22+
unsafe {
3223
lua_pushinteger(l, *w as isize);
3324
lua_pushinteger(l, *h as isize);
34-
return 2;
35-
},
36-
Err(e) => {
37-
printgm!(l, "Failed to get interface: {}", e);
3825
}
26+
return 2;
3927
}
4028
0
4129
}
4230

4331
#[lua_function]
4432
fn get_directory(l: LuaState) -> i32 {
45-
match get_iface() {
46-
Ok(iface) => {
47-
let dir = iface.GetGameDirectory();
48-
lua_pushstring(l, dir);
49-
return 1;
50-
},
51-
Err(e) => {
52-
printgm!(l, "Failed to get interface: {}", e);
53-
}
33+
if let Some(iface) = get_iface() {
34+
let dir = iface.GetGameDirectory();
35+
lua_pushstring(l, dir);
36+
return 1;
5437
}
5538
0
5639
}
5740

5841
#[lua_function]
5942
fn get_level(l: LuaState) -> i32 {
60-
match get_iface() {
61-
Ok(iface) => {
62-
let level = iface.GetLevelName();
63-
lua_pushstring(l, level);
64-
return 1;
65-
},
66-
Err(e) => {
67-
printgm!(l, "Failed to get interface: {}", e);
68-
}
43+
if let Some(iface) = get_iface() {
44+
let level = iface.GetLevelName();
45+
lua_pushstring(l, level);
46+
return 1;
6947
}
7048
0
7149
}
7250

7351
#[lua_function]
7452
fn is_recording(l: LuaState) -> i32 {
75-
match get_iface() {
76-
Ok(iface) => {
77-
let demo = iface.IsRecordingDemo();
78-
lua_pushboolean(l, demo as i32);
79-
return 1;
80-
},
81-
Err(e) => {
82-
printgm!(l, "Failed to get interface: {}", e);
83-
}
53+
if let Some(iface) = get_iface() {
54+
let demo = iface.IsRecordingDemo();
55+
lua_pushboolean(l, demo as i32);
56+
return 1;
8457
}
8558
0
8659
}
8760

8861
#[lua_function]
8962
fn is_paused(l: LuaState) -> i32 {
90-
match get_iface() {
91-
Ok(iface) => {
92-
let paused = iface.IsPaused();
93-
lua_pushboolean(l, paused as i32);
94-
return 1;
95-
},
96-
Err(e) => {
97-
printgm!(l, "Failed to get interface: {}", e);
98-
}
63+
if let Some(iface) = get_iface() {
64+
let paused = iface.IsPaused();
65+
lua_pushboolean(l, paused as i32);
66+
return 1;
9967
}
10068
0
10169
}

rglua/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "rglua"
33
description = "Toolkit for garrysmod development with the source sdk and luajit api"
4-
version = "2.0.0-beta"
4+
version = "2.0.0"
55
authors = ["Vurv <vurvdevelops@gmail.com>"]
66
keywords = ["glua", "garrysmod", "lua", "gmod"]
77
categories = ["api-bindings", "external-ffi-bindings", "development-tools::ffi", "game-development", "accessibility"]

rglua/src/interface/cvar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ pub struct ConCommandBase {
1010
pub flags: c_int, // 20
1111
}
1212

13-
iface! {
13+
interfaces! {
1414
#[version("VEngineCvar007")]
15-
#[file("vstdlib.dll")]
15+
#[file("vstdlib")]
1616
pub abstract struct ICVar {};
1717
}
1818

rglua/src/interface/engine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use super::prelude::*;
33

44
use std::os::raw::c_char;
55

6-
iface! {
6+
interfaces! {
77
#[version("VEngineClient015")]
8-
#[file("engine.dll")]
8+
#[file("engine")]
99
pub abstract struct EngineClient {};
1010
}
1111

rglua/src/interface/lua/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
pub(crate) use super::prelude::{self, iface, VTable};
1+
pub(crate) use super::prelude::{self, interfaces, VTable};
22

3-
iface! {
3+
interfaces! {
44
#[version("")]
55
#[file("")]
66
/// <https://github.com/danielga/garrysmod_common/blob/9981d4aaee15452a9b0f53436c1aa807f81f3fd6/include/GarrysMod/Lua/LuaObject.h#L24>

rglua/src/interface/materials.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::prelude::*;
22

3-
iface! {
3+
interfaces! {
44
#[version("")]
55
#[file("")]
66
/// You do not get this through creating an interface, it is instead exported by other interface functions.

rglua/src/interface/mdl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use super::common::StudioHdr;
22
use super::prelude::*;
33

4-
iface! {
4+
interfaces! {
55
#[version("MDLCache004")]
6-
#[file("datacache.dll")]
6+
#[file("datacache")]
77
pub abstract struct IMdlCache {};
88

99
#[version("")]

rglua/src/interface/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub(crate) mod prelude {
1010
#[cfg(feature = "userdata")]
1111
pub(crate) use crate::userdata::Vector;
1212

13-
macro_rules! iface {
13+
macro_rules! interfaces {
1414
(
1515
#[ version ( $ver:literal ) ]
1616
#[ file ( $file:literal ) ]
@@ -24,12 +24,12 @@ pub(crate) mod prelude {
2424
$vis struct $iface {
2525
pub vtable: usize
2626
}
27-
iface!( $($rest)* );
27+
interfaces!( $($rest)* );
2828
};
2929
() => ();
3030
}
3131

32-
pub(crate) use iface;
32+
pub(crate) use interfaces;
3333
}
3434

3535
mod common;
@@ -70,9 +70,9 @@ pub type CreateInterfaceFn =
7070
/// ```
7171
pub unsafe fn get_interface_handle(file: &str) -> Result<CreateInterfaceFn, libloading::Error> {
7272
let lib = Library::new(file)?;
73-
let sym: Symbol<CreateInterfaceFn> = lib.get(b"CreateInterface\0")?;
73+
let sym: Symbol<CreateInterfaceFn> = lib.get(b"CreateInterface\0".as_ref())?;
7474

75-
Ok(std::mem::transmute(sym))
75+
Ok(*sym)
7676
}
7777

7878
use thiserror::Error;
@@ -124,7 +124,6 @@ pub fn get_from_interface(
124124
let mut status = 0;
125125

126126
let iface = try_cstr!(iface)?;
127-
128127
let result = factory(iface.as_ptr(), &mut status);
129128

130129
if status == 0 && !result.is_null() {

0 commit comments

Comments
 (0)