1#![allow(non_snake_case)]
2
3pub(crate) mod prelude {
4 pub(crate) use viable::vtable;
5
6 pub(crate) use crate::interface::common::PlayerInfo;
7 pub(crate) use std::os::raw::{
8 c_char, c_double, c_float, c_int, c_long, c_uchar, c_uint, c_ushort, c_void
9 };
10 pub(crate) use crate::userdata::Vector;
11}
12
13mod common;
14mod cvar;
15mod engine;
16mod lua;
17mod materials;
18mod mdl;
19mod net;
20mod panel;
21mod client;
22
23pub use cvar::{CVar, ConVar};
24pub use engine::{EngineClient, EngineServer};
25pub use lua::{LuaInterface, LuaObject, LuaShared};
26pub use materials::MaterialSystem;
27pub use mdl::{MdlCache, MdlCacheNotify};
28pub use net::{NetChannelInfo, NetChannel, NetChannelHandler, NetMessage, CNetChan};
29pub use panel::Panel;
30pub use client::Client;
31
32use crate::try_cstr;
33use libloading::{Library, Symbol};
34use std::ffi::c_void;
35
36pub type CreateInterfaceFn =
37 extern "system" fn(pName: *const i8, pReturnCode: *mut i32) -> *mut c_void;
38
39pub unsafe fn get_interface_handle(file: &str) -> Result<CreateInterfaceFn, libloading::Error> {
55 let lib = Library::new(file)?;
56 let sym: Symbol<CreateInterfaceFn> = lib.get(b"CreateInterface\0".as_ref())?;
57
58 Ok(*sym)
59}
60
61use thiserror::Error;
62
63#[derive(Debug, Error)]
64pub enum Error {
65 #[error("Libloading error: {0}")]
66 Libloading(#[from] libloading::Error),
67
68 #[error("Failed to convert interface to c string. {0}")]
69 BadCString(#[from] std::ffi::NulError),
70
71 #[error("Couldn't find factory of interface {0}!")]
72 FactoryNotFound(String),
73
74 #[error("Failure in CreateInterface of interface {1}; Code [{0}]")]
75 CreateInterface(i32, String),
76
77 #[error("Failed to get interface {0} as mutable")]
78 IFaceMut(String),
79
80 #[error("Failed to get object as mutable")]
81 AsMut
82}
83
84pub fn get_from_interface(iface: &str, factory: CreateInterfaceFn) -> Result<*mut (), Error> {
108 let mut status = 0;
109
110 let interface = try_cstr!(iface)?;
111 let result = factory(interface.as_ptr(), &mut status);
112
113 if status == 0 && !result.is_null() {
114 Ok(result as *mut ())
115 } else {
116 Err(Error::FactoryNotFound(iface.to_owned()))
117 }
118}