Skip to main content

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}