package object // Returns all the children of an object. Returns the empty slice if the object is a component. func Children(object Component) []Component { if group, ok := object.(Object); ok { return group.Children() } return nil } // Returns the child objects attached to an object func Subgroups(object Component) []Object { children := Children(object) groups := make([]Object, 0, len(children)) for _, child := range children { if group, ok := child.(Object); ok { groups = append(groups, group) } } return groups } // Returns the components attached to an object func Components(object Component) []Component { children := Children(object) components := make([]Component, 0, len(children)) for _, child := range children { _, group := child.(Object) if !group { components = append(components, child) } } return components } // Attach a child component/object to a parent object // If the object already has a parent, it will be detached first. func Attach(parent Object, child Component) { if child == nil { panic("attaching nil child") } Detach(child) child.setParent(parent) parent.attach(child) activate(child) } // Detach a child component/object from its parent object // Does nothing if the given object has no parent. func Detach(child Component) { if child.Parent() == nil { return } deactivate(child) child.Parent().detach(child) child.setParent(nil) } func Enable(object Component) { object.setEnabled(true) activate(object) } func activate(object Component) { if !object.Enabled() { return } if object.Parent() == nil || !object.Parent().Active() { return } // activate if parent is active if wasActive := object.setActive(true); !wasActive { // enabled if handler, ok := object.(EnableHandler); ok { handler.OnEnable() } } } func Disable(object Component) { object.setEnabled(false) deactivate(object) } func deactivate(object Component) { if wasActive := object.setActive(false); wasActive { // disabled if handler, ok := object.(DisableHandler); ok { handler.OnDisable() } } } func Toggle(object Component, enabled bool) { if enabled { Enable(object) } else { Disable(object) } } // Root returns the first ancestor of the given component/object func Root(obj Component) Component { for obj.Parent() != nil { obj = obj.Parent() } return obj } // Gets a reference to a component of type K on the same object as the component/object specified. func Get[K Component](self Component) K { if hit, ok := self.(K); ok { return hit } var empty K group, ok := self.(Object) if !ok { group = self.Parent() } if group == nil { return empty } if !group.Enabled() { return empty } for _, child := range group.Children() { if child == self { continue } if !child.Enabled() { continue } if hit, ok := child.(K); ok { return hit } } return empty } // Gets references to all components of type K on the same object as the component/object specified. func GetAll[K Component](self Component) []K { group, ok := self.(Object) if !ok { group = self.Parent() } if group == nil { return nil } if !group.Enabled() { return nil } var results []K if hit, ok := group.(K); ok { results = append(results, hit) } for _, child := range group.Children() { if !child.Enabled() { continue } if hit, ok := child.(K); ok { results = append(results, hit) } } return results } // Gets the first reference to a component of type K in any parent of the object/component. // For component targets, sibling components will be returned. func GetInParents[K Component](self Component) K { var empty K group := self.Parent() for group != nil { if !group.Enabled() { return empty } if hit, ok := group.(K); ok { return hit } for _, child := range group.Children() { if child == self { continue } if !child.Enabled() { continue } if hit, ok := child.(K); ok { return hit } } group = group.Parent() } return empty } // Gets references to all components of type K in any parent of the object/component. // For component targets, sibling components will be returned. func GetAllInParents[K Component](self Component) []K { group := self.Parent() var results []K for group != nil { if !group.Enabled() { return nil } if hit, ok := group.(K); ok { results = append(results, hit) } for _, child := range group.Children() { if child == self { continue } if !child.Enabled() { continue } if hit, ok := child.(K); ok { results = append(results, hit) } } group = group.Parent() } return results } // Gets a reference to a component of type K on the same object as the component/object specified, or any child of the object. func GetInChildren[K Component](self Component) K { var empty K group, ok := self.(Object) if !ok { group = self.Parent() } if group == nil { return empty } if !group.Enabled() { return empty } todo := []Object{group} for len(todo) > 0 { group = todo[0] todo = todo[1:] for _, child := range group.Children() { if child == self { continue } if !child.Enabled() { continue } if hit, ok := child.(K); ok { return hit } if childgroup, ok := child.(Object); ok { todo = append(todo, childgroup) } } } return empty } // Gets references to all components of type K on the same object as the component/object specified, or any child of the object. func GetAllInChildren[K Component](self Component) []K { group, ok := self.(Object) if !ok { group = self.Parent() } if group == nil { return nil } if !group.Enabled() { return nil } todo := []Object{group} var results []K for len(todo) > 0 { group = todo[0] todo = todo[1:] for _, child := range group.Children() { if child == self { continue } if !child.Enabled() { continue } if hit, ok := child.(K); ok { results = append(results, hit) } if childgroup, ok := child.(Object); ok { todo = append(todo, childgroup) } } } return results }