dcso3/
static_object.rs

1/*
2Copyright 2024 Eric Stokes.
3
4This file is part of dcso3.
5
6dcso3 is free software: you can redistribute it and/or modify it under
7the terms of the MIT License.
8
9dcso3 is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE.
12*/
13
14use super::{as_tbl, coalition::Side, country::Country, object::Object};
15use crate::{airbase::Airbase, coalition::Static, object::{DcsObject, DcsOid}, wrapped_prim, wrapped_table, LuaEnv, MizLua};
16use anyhow::{anyhow, bail, Result};
17use mlua::{prelude::*, Value};
18use serde_derive::{Serialize, Deserialize};
19use std::{marker::PhantomData, ops::Deref};
20
21wrapped_prim!(StaticObjectId, i64, Hash, Copy);
22
23wrapped_table!(StaticObject, Some("StaticObject"));
24
25impl<'lua> StaticObject<'lua> {
26    pub fn get_by_name(lua: MizLua<'lua>, name: &str) -> Result<Static<'lua>> {
27        let globals = lua.inner().globals();
28        let sobj = as_tbl("StaticObject", None, globals.raw_get("StaticObject")?)?;
29        let tbl: LuaTable = sobj.call_function("getByName", name)?;
30        let mt = tbl
31            .get_metatable()
32            .ok_or_else(|| anyhow!("returned static object has no meta table"))?;
33        if mt.raw_get::<_, String>("className_")?.as_str() == "Airbase" {
34            Ok(Static::Airbase(Airbase::from_lua(
35                Value::Table(tbl),
36                lua.inner(),
37            )?))
38        } else {
39            Ok(Static::Static(StaticObject::from_lua(
40                Value::Table(tbl),
41                lua.inner(),
42            )?))
43        }
44    }
45
46    pub fn destroy(self) -> Result<()> {
47        Ok(self.t.call_method("destroy", ())?)
48    }
49
50    pub fn id(&self) -> Result<StaticObjectId> {
51        Ok(self.t.call_method("getID", ())?)
52    }
53
54    pub fn get_name(&self) -> Result<String> {
55        Ok(self.t.call_method("getName", ())?)
56    }
57
58    pub fn get_coalition(&self) -> Result<Side> {
59        Ok(self.t.call_method("getCoalition", ())?)
60    }
61
62    pub fn get_country(&self) -> Result<Country> {
63        Ok(self.t.call_method("getCountry", ())?)
64    }
65 
66    pub fn get_life(&self) -> Result<i64> {
67        Ok(self.t.call_method("getLife", ())?)
68    }
69
70    pub fn is_exist(&self) -> Result<bool> {
71        Ok(self.t.call_method("isExist", ())?)
72    }
73
74    pub fn as_object(&self) -> Result<Object<'lua>> {
75        Ok(Object::from_lua(Value::Table(self.t.clone()), self.lua)?)
76    }
77
78    pub fn get_desc(&self) -> Result<mlua::Table<'lua>> {
79        Ok(self.t.call_method("getDesc", ())?)
80    }
81}
82
83
84#[derive(Debug, Clone)]
85pub struct ClassStatic;
86
87impl<'lua> DcsObject<'lua> for StaticObject<'lua> {
88    type Class = ClassStatic;
89
90    fn get_instance(lua: MizLua<'lua>, id: &DcsOid<Self::Class>) -> Result<Self> {
91        let t = lua.inner().create_table()?;
92        t.set_metatable(Some(lua.inner().globals().raw_get(&**id.class)?));
93        t.raw_set("id_", id.id)?;
94        let t = StaticObject {
95            t,
96            lua: lua.inner(),
97        };
98        if !t.is_exist()? {
99            bail!("{} is an invalid object", id.id)
100        }
101        Ok(t)
102    }
103
104    fn get_instance_dyn<T>(lua: MizLua<'lua>, id: &DcsOid<T>) -> Result<Self> {
105        id.check_implements(lua, "StaticObject")?;
106        let id = DcsOid {
107            id: id.id,
108            class: id.class.clone(),
109            t: PhantomData,
110        };
111        Self::get_instance(lua, &id)
112    }
113
114    fn change_instance(self, id: &DcsOid<Self::Class>) -> Result<Self> {
115        self.raw_set("id_", id.id)?;
116        if !self.is_exist()? {
117            bail!("{} is an invalid object", id.id)
118        }
119        Ok(self)
120    }
121
122    fn change_instance_dyn<T>(self, id: &DcsOid<T>) -> Result<Self> {
123        id.check_implements(MizLua(self.lua), "StaticObject")?;
124        self.t.raw_set("id_", id.id)?;
125        if !self.is_exist()? {
126            bail!("{} is an invalid object", id.id)
127        }
128        Ok(self)
129    }
130}