mirror of
https://github.com/lune-org/lune.git
synced 2024-12-13 13:30:38 +00:00
Don't allow instances to be created from dom roots
This commit is contained in:
parent
b63d016818
commit
9f13b8e667
1 changed files with 47 additions and 64 deletions
|
@ -24,28 +24,31 @@ lazy_static::lazy_static! {
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
dom_ref: DomRef,
|
dom_ref: DomRef,
|
||||||
class_name: String,
|
class_name: String,
|
||||||
is_root: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
/**
|
/**
|
||||||
Creates a new `Instance` from an existing dom object ref.
|
Creates a new `Instance` from an existing dom object ref.
|
||||||
|
|
||||||
Panics if the instance does not exist in the internal dom.
|
Panics if the instance does not exist in the internal dom,
|
||||||
|
or if the given dom object ref points to the dom root.
|
||||||
*/
|
*/
|
||||||
fn new(dom_ref: DomRef) -> Self {
|
fn new(dom_ref: DomRef) -> Self {
|
||||||
let reader = INTERNAL_DOM
|
let dom = INTERNAL_DOM
|
||||||
.try_read()
|
.try_read()
|
||||||
.expect("Failed to get read access to document");
|
.expect("Failed to get read access to document");
|
||||||
|
|
||||||
let instance = reader
|
let instance = dom
|
||||||
.get_by_ref(dom_ref)
|
.get_by_ref(dom_ref)
|
||||||
.expect("Failed to find instance in document");
|
.expect("Failed to find instance in document");
|
||||||
|
|
||||||
|
if instance.referent() == dom.root_ref() {
|
||||||
|
panic!("Instances can not be created from dom roots")
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
dom_ref,
|
dom_ref,
|
||||||
class_name: instance.class.clone(),
|
class_name: instance.class.clone(),
|
||||||
is_root: dom_ref == reader.root_ref(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +72,6 @@ impl Instance {
|
||||||
Self {
|
Self {
|
||||||
dom_ref,
|
dom_ref,
|
||||||
class_name: class_name.to_string(),
|
class_name: class_name.to_string(),
|
||||||
is_root: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +80,8 @@ impl Instance {
|
||||||
it from an external weak dom to the internal one.
|
it from an external weak dom to the internal one.
|
||||||
|
|
||||||
An orphaned instance is an instance at the root of a weak dom.
|
An orphaned instance is an instance at the root of a weak dom.
|
||||||
|
|
||||||
|
Panics if the given dom ref is the root dom ref of the external weak dom.
|
||||||
*/
|
*/
|
||||||
pub fn from_external_dom(external_dom: &mut WeakDom, external_dom_ref: DomRef) -> Self {
|
pub fn from_external_dom(external_dom: &mut WeakDom, external_dom_ref: DomRef) -> Self {
|
||||||
{
|
{
|
||||||
|
@ -95,7 +99,8 @@ impl Instance {
|
||||||
/**
|
/**
|
||||||
Transfers an instance to an external weak dom.
|
Transfers an instance to an external weak dom.
|
||||||
|
|
||||||
This will place the instance at the root of the weak dom and return its referent.
|
This will place the instance as a child of the
|
||||||
|
root of the weak dom, and return its referent.
|
||||||
*/
|
*/
|
||||||
pub fn into_external_dom(self, external_dom: &mut WeakDom) -> DomRef {
|
pub fn into_external_dom(self, external_dom: &mut WeakDom) -> DomRef {
|
||||||
let mut dom = INTERNAL_DOM
|
let mut dom = INTERNAL_DOM
|
||||||
|
@ -177,8 +182,8 @@ impl Instance {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Destroys the instance, unless it is the root instance, removing
|
Destroys the instance, removing it completely
|
||||||
it completely from the weak dom with no way of recovering it.
|
from the weak dom with no way of recovering it.
|
||||||
|
|
||||||
All member methods will throw errors when called from lua and panic
|
All member methods will throw errors when called from lua and panic
|
||||||
when called from rust after the instance has been destroyed.
|
when called from rust after the instance has been destroyed.
|
||||||
|
@ -190,7 +195,7 @@ impl Instance {
|
||||||
on the Roblox Developer Hub
|
on the Roblox Developer Hub
|
||||||
*/
|
*/
|
||||||
pub fn destroy(&mut self) -> bool {
|
pub fn destroy(&mut self) -> bool {
|
||||||
if self.is_root || self.is_destroyed() {
|
if self.is_destroyed() {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
let mut dom = INTERNAL_DOM
|
let mut dom = INTERNAL_DOM
|
||||||
|
@ -313,11 +318,6 @@ impl Instance {
|
||||||
on the Roblox Developer Hub
|
on the Roblox Developer Hub
|
||||||
*/
|
*/
|
||||||
pub fn get_parent(&self) -> Option<Instance> {
|
pub fn get_parent(&self) -> Option<Instance> {
|
||||||
if self.is_root {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (nil_parent_ref, parent_ref) = {
|
|
||||||
let dom = INTERNAL_DOM
|
let dom = INTERNAL_DOM
|
||||||
.try_read()
|
.try_read()
|
||||||
.expect("Failed to get read access to document");
|
.expect("Failed to get read access to document");
|
||||||
|
@ -327,10 +327,7 @@ impl Instance {
|
||||||
.expect("Failed to find instance in document")
|
.expect("Failed to find instance in document")
|
||||||
.parent();
|
.parent();
|
||||||
|
|
||||||
(dom.root_ref(), parent_ref)
|
if parent_ref == dom.root_ref() {
|
||||||
};
|
|
||||||
|
|
||||||
if parent_ref == nil_parent_ref {
|
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Self::new(parent_ref))
|
Some(Self::new(parent_ref))
|
||||||
|
@ -349,10 +346,6 @@ impl Instance {
|
||||||
on the Roblox Developer Hub
|
on the Roblox Developer Hub
|
||||||
*/
|
*/
|
||||||
pub fn set_parent(&self, parent: Option<Instance>) {
|
pub fn set_parent(&self, parent: Option<Instance>) {
|
||||||
if self.is_root {
|
|
||||||
panic!("Root instance can not be reparented")
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut dom = INTERNAL_DOM
|
let mut dom = INTERNAL_DOM
|
||||||
.try_write()
|
.try_write()
|
||||||
.expect("Failed to get write access to target document");
|
.expect("Failed to get write access to target document");
|
||||||
|
@ -405,16 +398,15 @@ impl Instance {
|
||||||
on the Roblox Developer Hub
|
on the Roblox Developer Hub
|
||||||
*/
|
*/
|
||||||
pub fn get_children(&self) -> Vec<Instance> {
|
pub fn get_children(&self) -> Vec<Instance> {
|
||||||
let children = {
|
|
||||||
let dom = INTERNAL_DOM
|
let dom = INTERNAL_DOM
|
||||||
.try_read()
|
.try_read()
|
||||||
.expect("Failed to get read access to document");
|
.expect("Failed to get read access to document");
|
||||||
|
|
||||||
dom.get_by_ref(self.dom_ref)
|
let children = dom
|
||||||
|
.get_by_ref(self.dom_ref)
|
||||||
.expect("Failed to find instance in document")
|
.expect("Failed to find instance in document")
|
||||||
.children()
|
.children()
|
||||||
.to_vec()
|
.to_vec();
|
||||||
};
|
|
||||||
|
|
||||||
children.into_iter().map(Self::new).collect()
|
children.into_iter().map(Self::new).collect()
|
||||||
}
|
}
|
||||||
|
@ -430,7 +422,6 @@ impl Instance {
|
||||||
on the Roblox Developer Hub
|
on the Roblox Developer Hub
|
||||||
*/
|
*/
|
||||||
pub fn get_descendants(&self) -> Vec<Instance> {
|
pub fn get_descendants(&self) -> Vec<Instance> {
|
||||||
let descendants = {
|
|
||||||
let dom = INTERNAL_DOM
|
let dom = INTERNAL_DOM
|
||||||
.try_read()
|
.try_read()
|
||||||
.expect("Failed to get read access to document");
|
.expect("Failed to get read access to document");
|
||||||
|
@ -450,9 +441,6 @@ impl Instance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
descendants
|
|
||||||
};
|
|
||||||
|
|
||||||
descendants.into_iter().map(Self::new).collect()
|
descendants.into_iter().map(Self::new).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,12 +700,7 @@ impl LuaUserData for Instance {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
"Parent" => {
|
"Parent" => {
|
||||||
if this.is_root {
|
if this.get_class_name() == "DataModel" {
|
||||||
return Err(LuaError::RuntimeError(format!(
|
|
||||||
"Failed to set property '{}' - root instance can not be reparented",
|
|
||||||
prop_name
|
|
||||||
)));
|
|
||||||
} else if this.get_class_name() == "DataModel" {
|
|
||||||
return Err(LuaError::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"Failed to set property '{}' - DataModel can not be reparented",
|
"Failed to set property '{}' - DataModel can not be reparented",
|
||||||
prop_name
|
prop_name
|
||||||
|
|
Loading…
Reference in a new issue