Redid the entity system a bit to make it more reliable

Now it supports things like parenting elements before they are
added to a window and elements no longer have to constantly check
for a nil entity
This commit is contained in:
Sasha Koshka 2023-04-15 01:14:36 -04:00
parent 5cf0b162c0
commit 437aef0c27
12 changed files with 129 additions and 96 deletions

View File

@ -17,6 +17,9 @@ type Backend interface {
// possible. This method must be safe to call from other threads. // possible. This method must be safe to call from other threads.
Do (callback func ()) Do (callback func ())
// NewEntity creates a new entity for the specified element.
NewEntity (owner Element) Entity
// NewWindow creates a new window within the specified bounding // NewWindow creates a new window within the specified bounding
// rectangle. The position on screen may be overridden by the backend or // rectangle. The position on screen may be overridden by the backend or
// operating system. // operating system.

View File

@ -19,29 +19,46 @@ type entity struct {
isContainer bool isContainer bool
} }
func bind (parent *entity, window *window, element tomo.Element) *entity { func (backend *Backend) NewEntity (owner tomo.Element) tomo.Entity {
entity := &entity { entity := &entity { element: owner }
window: window, if _, ok := owner.(tomo.Container); ok {
parent: parent,
element: element,
}
entity.Invalidate()
if _, ok := element.(tomo.Container); ok {
entity.isContainer = true entity.isContainer = true
entity.InvalidateLayout() entity.InvalidateLayout()
} }
element.Bind(entity)
return entity return entity
} }
func (entity *entity) unbind () { func (ent *entity) unlink () {
entity.element.Bind(nil) ent.propagate (func (child *entity) bool {
for _, childEntity := range entity.children { child.window = nil
childEntity.unbind() delete(ent.window.system.drawingInvalid, child)
return true
})
delete(ent.window.system.drawingInvalid, ent)
ent.parent = nil
ent.window = nil
}
func (entity *entity) link (parent *entity) {
entity.parent = parent
if parent.window != nil {
entity.setWindow(parent.window)
} }
} }
func (ent *entity) setWindow (window *window) {
ent.window = window
ent.Invalidate()
ent.InvalidateLayout()
ent.propagate (func (child *entity) bool {
child.window = window
ent.Invalidate()
ent.InvalidateLayout()
return true
})
}
func (entity *entity) propagate (callback func (*entity) bool) { func (entity *entity) propagate (callback func (*entity) bool) {
for _, child := range entity.children { for _, child := range entity.children {
if callback(child) { break } if callback(child) { break }