samp/amx.rs
1//! Re-exports the SDK's `Amx` API and adds a global registry of active
2//! instances + an opaque identity to pass between callbacks.
3
4pub use samp_sdk::amx::*;
5use samp_sdk::raw::types::AMX;
6
7use crate::runtime::Runtime;
8
9/// Locates a live `&Amx` by its [`AmxIdent`].
10///
11/// Useful when the plugin stores the `ident` in a structure and needs to
12/// retrieve the `Amx` later (e.g. a list of scripts subscribed to an event).
13/// Returns `None` if the AMX has already been unloaded by the server.
14#[inline]
15#[must_use]
16pub fn get<'a>(ident: AmxIdent) -> Option<&'a Amx> {
17 let rt = Runtime::get();
18 rt.amx_list()
19 .iter()
20 .find(|(k, _)| *k == ident)
21 .map(|(_, v)| v)
22}
23
24/// Registers a freshly received `AMX*` in the global runtime.
25///
26/// Called by the `interlayer` in `AmxLoad`. Plugins normally do not invoke
27/// this function directly.
28#[inline]
29pub fn add(amx: *mut AMX) {
30 let rt = Runtime::get();
31 rt.insert_amx(amx);
32}
33
34/// Stable identity of an `Amx` instance.
35///
36/// Wrapper around the pointer address — does not dereference, safe to keep
37/// as a key in maps or pass between callbacks. To resolve back to an `&Amx`,
38/// use [`get`].
39#[derive(Debug, Clone, Copy, PartialEq, Hash, Eq)]
40pub struct AmxIdent {
41 ident: usize,
42}
43
44impl From<*mut AMX> for AmxIdent {
45 fn from(ptr: *mut AMX) -> AmxIdent {
46 AmxIdent {
47 ident: ptr as usize,
48 }
49 }
50}
51
52/// Extensions over `Amx` specific to the `samp` crate (not part of the base SDK).
53pub trait AmxExt {
54 /// Opaque identity of the `Amx` — useful for maps and cross references.
55 fn ident(&self) -> AmxIdent;
56}
57
58impl AmxExt for Amx {
59 #[inline]
60 fn ident(&self) -> AmxIdent {
61 self.amx()
62 .expect("Amx::ident() called with null pointer")
63 .as_ptr()
64 .into()
65 }
66}