Skip to main content

rblx_godot/instance/
model.rs

1use r2g_mlua::prelude::*;
2
3use super::instance::IInstanceComponent;
4use super::pvinstance::IPVInstance;
5use super::{DynInstance, IInstance, IObject, InstanceComponent, ManagedInstance, PVInstanceComponent, WeakManagedInstance};
6
7use crate::core::{InheritanceBase, InheritanceTable, InheritanceTableBuilder, Irc, RwLock, RwLockReadGuard, RwLockWriteGuard};
8use crate::userdata::{CFrame, ManagedRBXScriptSignal};
9use crate::userdata::enums::{ModelLevelOfDetail, ModelStreamingMode};
10
11#[derive(Debug)]
12pub struct ModelComponent {
13    level_of_detail: ModelLevelOfDetail,
14    model_streaming_mode: ModelStreamingMode,
15    primary_part: Option<ManagedInstance>, // todo!()
16    world_pivot: CFrame
17}
18#[derive(Debug)]
19pub struct Model {
20    instance: RwLock<InstanceComponent>,
21    pvinstance: RwLock<PVInstanceComponent>,
22    model: RwLock<ModelComponent>
23}
24pub trait IModel: IPVInstance {
25    fn get_model_component(&self) -> RwLockReadGuard<'_,ModelComponent>;
26    fn get_model_component_mut(&self) -> RwLockWriteGuard<'_,ModelComponent>;
27}
28
29impl InheritanceBase for Model {
30    fn inheritance_table(&self) -> InheritanceTable {
31        InheritanceTableBuilder::new()
32            .insert_type::<Model,dyn IObject>(|x: &Self| x as &dyn IObject, |x: &mut Self| x as &mut dyn IObject)
33            .insert_type::<Model,dyn IInstance>(|x: &Self| x as &dyn IInstance, |x: &mut Self| x as &mut dyn IInstance)
34            .insert_type::<Model,dyn IPVInstance>(|x: &Self| x as &dyn IPVInstance, |x: &mut Self| x as &mut dyn IPVInstance)
35            .insert_type::<Model,dyn IModel>(|x: &Self| x as &dyn IModel, |x: &mut Self| x as &mut dyn IModel)
36            .output()
37    }
38}
39impl IObject for Model {
40    fn is_a(&self, class_name: &String) -> bool {
41        match class_name.as_str() {
42            "Model" |
43            "PVInstance" |
44            "Instance" |
45            "Object" => true,
46            _ => false
47        }
48    }
49    fn lua_get(&self, lua: &Lua, name: String) -> LuaResult<LuaValue> {
50        self.get_model_component().lua_get(self, lua, &name)
51            .or_else(|| self.get_pv_instance_component().lua_get(self, lua, &name))
52            .unwrap_or_else(|| self.get_instance_component().lua_get(lua, &name))
53    }
54    fn get_changed_signal(&self) -> ManagedRBXScriptSignal {
55        self.get_instance_component().changed.clone()
56    }
57    fn get_property_changed_signal(&self, property: String) -> ManagedRBXScriptSignal {
58        self.get_instance_component().get_property_changed_signal(property).unwrap()
59    }
60    fn get_class_name(&self) -> &'static str { "Model" }
61}
62impl IInstance for Model {
63    fn get_instance_component(&self) -> RwLockReadGuard<'_, InstanceComponent> {
64        self.instance.read().unwrap()
65    }
66    fn get_instance_component_mut(&self) -> RwLockWriteGuard<'_, InstanceComponent> {
67        self.instance.write().unwrap()
68    }
69    fn lua_set(&self, lua: &Lua, name: String, val: LuaValue) -> LuaResult<()> {
70        self.get_model_component_mut().lua_set(self, lua, &name, &val)
71            .or_else(|| self.get_pv_instance_component_mut().lua_set(self, lua, &name, &val))
72            .unwrap_or_else(|| self.get_instance_component_mut().lua_set(lua, &name, val))
73    }
74    fn clone_instance(&self, lua: &Lua) -> LuaResult<ManagedInstance> {
75        Ok(Irc::new_cyclic_fallable::<_, LuaError>(|x| {
76            let i = x.cast_to_instance();
77            Ok(Model {
78                instance: RwLock::new_with_flag_auto(self.get_instance_component().clone(lua, &i)?),
79                pvinstance: RwLock::new_with_flag_auto(self.get_pv_instance_component().clone(lua, &i)?),
80                model: RwLock::new_with_flag_auto(self.get_model_component().clone(lua, &i)?)
81            })
82        })?.cast_from_sized().unwrap())
83    }
84}
85impl IPVInstance for Model {
86    fn get_pv_instance_component(&self) -> RwLockReadGuard<'_, PVInstanceComponent> {
87        self.pvinstance.read().unwrap()
88    }
89
90    fn get_pv_instance_component_mut(&self) -> RwLockWriteGuard<'_, PVInstanceComponent> {
91        self.pvinstance.write().unwrap()
92    }
93}
94impl IModel for Model {
95    fn get_model_component(&self) -> RwLockReadGuard<'_, ModelComponent> {
96        self.model.read().unwrap()
97    }
98    fn get_model_component_mut(&self) -> RwLockWriteGuard<'_, ModelComponent> {
99        self.model.write().unwrap()
100    }
101}
102
103impl IInstanceComponent for ModelComponent {
104    fn lua_get(self: &mut RwLockReadGuard<'_, ModelComponent>, _: &DynInstance, _lua: &Lua, key: &String) -> Option<LuaResult<LuaValue>> {
105        match key.as_str() {
106            "LevelOfDetail" => todo!(),
107            "ModelStreamingMode" => todo!(),
108            "PrimaryPart" => todo!(),
109            "WorldPivot" => todo!(),
110            _ => None
111        }
112    }
113
114    fn lua_set(self: &mut RwLockWriteGuard<'_, ModelComponent>, _: &DynInstance, _lua: &Lua, key: &String, _value: &LuaValue) -> Option<LuaResult<()>> {
115        match key.as_str() {
116            "LevelOfDetail" => todo!(),
117            "ModelStreamingMode" => todo!(),
118            "PrimaryPart" => todo!(),
119            "WorldPivot" => todo!(),
120            _ => None
121        }
122    }
123
124    fn clone(self: &RwLockReadGuard<'_, ModelComponent>, _: &Lua, _: &WeakManagedInstance) -> LuaResult<Self> {
125        Ok(ModelComponent {
126            level_of_detail: self.level_of_detail,
127            model_streaming_mode: self.model_streaming_mode,
128            primary_part: None,
129            world_pivot: self.world_pivot
130        })
131    }
132
133    fn new(_: super::WeakManagedInstance, _: &'static str) -> Self {
134        ModelComponent {
135            level_of_detail: ModelLevelOfDetail::Automatic,
136            model_streaming_mode: ModelStreamingMode::Default,
137            primary_part: None,
138            world_pivot: CFrame::IDENTITY
139        }
140    }
141}
142
143impl Model {
144    pub fn new() -> ManagedInstance {
145        Irc::new_cyclic(|x| {
146            Model {
147                instance: RwLock::new_with_flag_auto(InstanceComponent::new(x.cast_to_instance(), "Model")),
148                pvinstance: RwLock::new_with_flag_auto(PVInstanceComponent::new(x.cast_to_instance(), "Model")),
149                model: RwLock::new_with_flag_auto(ModelComponent::new(x.cast_to_instance(), "Model"))
150            }
151        }).cast_from_sized().unwrap()
152    }
153}