1use 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}