github.com/goki/ki@v1.1.17/ki/node.go (about)

     1  // Copyright (c) 2018, The GoKi Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ki
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/gob"
    10  	"errors"
    11  	"fmt"
    12  	"strconv"
    13  	"sync/atomic"
    14  	"unsafe"
    15  
    16  	"log"
    17  	"reflect"
    18  	"strings"
    19  
    20  	"github.com/goki/ki/bitflag"
    21  	"github.com/goki/ki/kit"
    22  	"github.com/jinzhu/copier"
    23  )
    24  
    25  // The Node implements the Ki interface and provides the core functionality
    26  // for the GoKi tree -- use the Node as an embedded struct or as a struct
    27  // field -- the embedded version supports full JSON save / load.
    28  //
    29  // The desc: key for fields is used by the GoGi GUI viewer for help / tooltip
    30  // info -- add these to all your derived struct's fields.  See relevant docs
    31  // for other such tags controlling a wide range of GUI and other functionality
    32  // -- Ki makes extensive use of such tags.
    33  type Node struct {
    34  
    35  	// Ki.Name() user-supplied name of this node -- can be empty or non-unique
    36  	Nm string `copy:"-" label:"Name" desc:"Ki.Name() user-supplied name of this node -- can be empty or non-unique"`
    37  
    38  	// [tableview: -] bit flags for internal node state
    39  	Flag int64 `tableview:"-" copy:"-" json:"-" xml:"-" max-width:"80" height:"3" desc:"bit flags for internal node state"`
    40  
    41  	// [tableview: -] Ki.Properties() property map for arbitrary extensible properties, including style properties
    42  	Props Props `tableview:"-" xml:"-" copy:"-" label:"Properties" desc:"Ki.Properties() property map for arbitrary extensible properties, including style properties"`
    43  
    44  	// [view: -] [tableview: -] Ki.Parent() parent of this node -- set automatically when this node is added as a child of parent
    45  	Par Ki `tableview:"-" copy:"-" json:"-" xml:"-" label:"Parent" view:"-" desc:"Ki.Parent() parent of this node -- set automatically when this node is added as a child of parent"`
    46  
    47  	// [tableview: -] Ki.Children() list of children of this node -- all are set to have this node as their parent -- can reorder etc but generally use Ki Node methods to Add / Delete to ensure proper usage
    48  	Kids Slice `tableview:"-" copy:"-" label:"Children" desc:"Ki.Children() list of children of this node -- all are set to have this node as their parent -- can reorder etc but generally use Ki Node methods to Add / Delete to ensure proper usage"`
    49  
    50  	// [view: -] Ki.NodeSignal() signal for node structure / state changes -- emits NodeSignals signals -- can also extend to custom signals (see signal.go) but in general better to create a new Signal instead
    51  	NodeSig Signal `copy:"-" json:"-" xml:"-" view:"-" desc:"Ki.NodeSignal() signal for node structure / state changes -- emits NodeSignals signals -- can also extend to custom signals (see signal.go) but in general better to create a new Signal instead"`
    52  
    53  	// [view: -] we need a pointer to ourselves as a Ki, which can always be used to extract the true underlying type of object when Node is embedded in other structs -- function receivers do not have this ability so this is necessary.  This is set to nil when deleted.  Typically use This() convenience accessor which protects against concurrent access.
    54  	Ths Ki `copy:"-" json:"-" xml:"-" view:"-" desc:"we need a pointer to ourselves as a Ki, which can always be used to extract the true underlying type of object when Node is embedded in other structs -- function receivers do not have this ability so this is necessary.  This is set to nil when deleted.  Typically use This() convenience accessor which protects against concurrent access."`
    55  
    56  	// [view: -] last value of our index -- used as a starting point for finding us in our parent next time -- is not guaranteed to be accurate!  use IndexInParent() method
    57  	index int `copy:"-" json:"-" xml:"-" view:"-" desc:"last value of our index -- used as a starting point for finding us in our parent next time -- is not guaranteed to be accurate!  use IndexInParent() method"`
    58  
    59  	// [view: -] optional depth parameter of this node -- only valid during specific contexts, not generally -- e.g., used in FuncDownBreadthFirst function
    60  	depth int `copy:"-" json:"-" xml:"-" view:"-" desc:"optional depth parameter of this node -- only valid during specific contexts, not generally -- e.g., used in FuncDownBreadthFirst function"`
    61  
    62  	// [view: -] cached version of the field offsets relative to base Node address -- used in generic field access.
    63  	fieldOffs []uintptr `copy:"-" json:"-" xml:"-" view:"-" desc:"cached version of the field offsets relative to base Node address -- used in generic field access."`
    64  }
    65  
    66  // must register all new types so type names can be looked up by name -- also props
    67  // EnumType:Flags registers KiT_Flags as type for Flags field for GUI views
    68  // Nodes can also use type properties e.g., StructViewFields key with props
    69  // inside that to set view properties for types, e.g., to hide or show
    70  // some of these base Node flags.
    71  var KiT_Node = kit.Types.AddType(&Node{}, Props{EnumTypeFlag: KiT_Flags})
    72  
    73  // check implementation of [Ki] interface
    74  var _ = Ki(&Node{})
    75  
    76  // EnumTypeFlag is a [Props] property name that
    77  // indicates what enum type to use as the type for
    78  // the flags field in GUI views. Its value should be
    79  // of the type [reflect.Type]
    80  const EnumTypeFlag string = "EnumType:Flag"
    81  
    82  //////////////////////////////////////////////////////////////////////////
    83  //  fmt.Stringer
    84  
    85  // String implements the fmt.stringer interface -- returns the Path of the node
    86  func (n *Node) String() string {
    87  	return n.This().Path()
    88  }
    89  
    90  //////////////////////////////////////////////////////////////////////////
    91  //  Basic Ki fields
    92  
    93  // This returns the Ki interface that guarantees access to the Ki
    94  // interface in a way that always reveals the underlying type
    95  // (e.g., in reflect calls).  Returns nil if node is nil,
    96  // has been destroyed, or is improperly constructed.
    97  func (n *Node) This() Ki {
    98  	if n == nil || n.IsDestroyed() {
    99  		return nil
   100  	}
   101  	return n.Ths
   102  }
   103  
   104  // AsNode returns the *ki.Node base type for this node.
   105  func (n *Node) AsNode() *Node {
   106  	return n
   107  }
   108  
   109  // InitName initializes this node to given actual object as a Ki interface
   110  // and sets its name.  The names should be unique among children of a node.
   111  // This is needed for root nodes -- automatically done for other nodes
   112  // when they are added to the Ki tree.
   113  // Even though this is a method and gets the method receiver, it needs
   114  // an "external" version of itself passed as the first arg, from which
   115  // the proper Ki interface pointer will be obtained.  This is the only
   116  // way to get virtual functional calling to work within the Go framework.
   117  func (n *Node) InitName(k Ki, name string) {
   118  	InitNode(k)
   119  	n.SetName(name)
   120  }
   121  
   122  // Embed returns the embedded struct of given type from this node (or nil
   123  // if it does not embed that type, or the type is not a Ki type -- see
   124  // kit.Embed for a generic interface{} version.
   125  func (n *Node) Embed(t reflect.Type) Ki {
   126  	if n == nil {
   127  		return nil
   128  	}
   129  	es := kit.Embed(n.This(), t)
   130  	if es != nil {
   131  		k, ok := es.(Ki)
   132  		if ok {
   133  			return k
   134  		}
   135  		log.Printf("ki.Embed on: %v embedded struct is not a Ki type -- use kit.Embed for a more general version\n", n.Path())
   136  		return nil
   137  	}
   138  	return nil
   139  }
   140  
   141  // BaseIface returns the base interface type for all elements
   142  // within this tree.  Use reflect.TypeOf((*<interface_type>)(nil)).Elem().
   143  // Used e.g., for determining what types of children
   144  // can be created (see kit.EmbedImplements for test method)
   145  func (n *Node) BaseIface() reflect.Type {
   146  	return KiType
   147  }
   148  
   149  // Name returns the user-defined name of the object (Node.Nm),
   150  // for finding elements, generating paths, IO, etc.
   151  func (n *Node) Name() string {
   152  	return n.Nm
   153  }
   154  
   155  // SetName sets the name of this node.
   156  // Names should generally be unique across children of each node.
   157  // See Unique* functions to check / fix.
   158  // If node requires non-unique names, add a separate Label field.
   159  // Does NOT wrap in UpdateStart / End.
   160  func (n *Node) SetName(name string) {
   161  	n.Nm = name
   162  }
   163  
   164  //////////////////////////////////////////////////////////////////////////
   165  //  Parents
   166  
   167  // Parent returns the parent of this Ki (Node.Par) -- Ki has strict
   168  // one-parent, no-cycles structure -- see SetParent.
   169  func (n *Node) Parent() Ki {
   170  	return n.Par
   171  }
   172  
   173  // IndexInParent returns our index within our parent object -- caches the
   174  // last value and uses that for an optimized search so subsequent calls
   175  // are typically quite fast.  Returns false if we don't have a parent.
   176  func (n *Node) IndexInParent() (int, bool) {
   177  	if n.Par == nil {
   178  		return -1, false
   179  	}
   180  	idx, ok := n.Par.Children().IndexOf(n.This(), n.index) // very fast if index is close..
   181  	if ok {
   182  		n.index = idx
   183  	}
   184  	return idx, ok
   185  }
   186  
   187  // ParentLevel finds a given potential parent node recursively up the
   188  // hierarchy, returning level above current node that the parent was
   189  // found, and -1 if not found.
   190  func (n *Node) ParentLevel(par Ki) int {
   191  	parLev := -1
   192  	n.FuncUpParent(0, n, func(k Ki, level int, d any) bool {
   193  		if k == par {
   194  			parLev = level
   195  			return Break
   196  		}
   197  		return Continue
   198  	})
   199  	return parLev
   200  }
   201  
   202  // ParentByName finds first parent recursively up hierarchy that matches
   203  // given name -- returns nil if not found.
   204  func (n *Node) ParentByName(name string) Ki {
   205  	if IsRoot(n) {
   206  		return nil
   207  	}
   208  	if n.Par.Name() == name {
   209  		return n.Par
   210  	}
   211  	return n.Par.ParentByName(name)
   212  }
   213  
   214  // ParentByNameTry finds first parent recursively up hierarchy that matches
   215  // given name -- returns error if not found.
   216  func (n *Node) ParentByNameTry(name string) (Ki, error) {
   217  	par := n.ParentByName(name)
   218  	if par != nil {
   219  		return par, nil
   220  	}
   221  	return nil, fmt.Errorf("ki %v: Parent name: %v not found", n.Nm, name)
   222  }
   223  
   224  // ParentByType finds parent recursively up hierarchy, by type, and
   225  // returns nil if not found. If embeds is true, then it looks for any
   226  // type that embeds the given type at any level of anonymous embedding.
   227  func (n *Node) ParentByType(t reflect.Type, embeds bool) Ki {
   228  	if IsRoot(n) {
   229  		return nil
   230  	}
   231  	if embeds {
   232  		if TypeEmbeds(n.Par, t) {
   233  			return n.Par
   234  		}
   235  	} else {
   236  		if Type(n.Par) == t {
   237  			return n.Par
   238  		}
   239  	}
   240  	return n.Par.ParentByType(t, embeds)
   241  }
   242  
   243  // ParentByTypeTry finds parent recursively up hierarchy, by type, and
   244  // returns error if not found. If embeds is true, then it looks for any
   245  // type that embeds the given type at any level of anonymous embedding.
   246  func (n *Node) ParentByTypeTry(t reflect.Type, embeds bool) (Ki, error) {
   247  	par := n.ParentByType(t, embeds)
   248  	if par != nil {
   249  		return par, nil
   250  	}
   251  	return nil, fmt.Errorf("ki %v: Parent of type: %v not found", n.Nm, t)
   252  }
   253  
   254  //////////////////////////////////////////////////////////////////////////
   255  //  Children
   256  
   257  // HasChildren tests whether this node has children (i.e., non-terminal).
   258  func (n *Node) HasChildren() bool {
   259  	return len(n.Kids) > 0
   260  }
   261  
   262  // NumChildren returns the number of children of this node.
   263  func (n *Node) NumChildren() int {
   264  	return len(n.Kids)
   265  }
   266  
   267  // Children returns a pointer to the slice of children (Node.Kids) -- use
   268  // methods on ki.Slice for further ways to access (ByName, ByType, etc).
   269  // Slice can be modified directly (e.g., sort, reorder) but Add* / Delete*
   270  // methods on parent node should be used to ensure proper tracking.
   271  func (n *Node) Children() *Slice {
   272  	return &n.Kids
   273  }
   274  
   275  // IsValidIndex returns error if given index is not valid for accessing children
   276  // nil otherwise.
   277  func (n *Node) IsValidIndex(idx int) error {
   278  	sz := len(n.Kids)
   279  	if idx >= 0 && idx < sz {
   280  		return nil
   281  	}
   282  	return fmt.Errorf("ki %v: invalid index: %v -- len = %v", n.Nm, idx, sz)
   283  }
   284  
   285  // Child returns the child at given index -- will panic if index is invalid.
   286  // See methods on ki.Slice for more ways to access.
   287  func (n *Node) Child(idx int) Ki {
   288  	return n.Kids[idx]
   289  }
   290  
   291  // ChildTry returns the child at given index.  Try version returns error if index is invalid.
   292  // See methods on ki.Slice for more ways to acces.
   293  func (n *Node) ChildTry(idx int) (Ki, error) {
   294  	if err := n.IsValidIndex(idx); err != nil {
   295  		return nil, err
   296  	}
   297  	return n.Kids[idx], nil
   298  }
   299  
   300  // ChildByName returns first element that has given name, nil if not found.
   301  // startIdx arg allows for optimized bidirectional find if you have
   302  // an idea where it might be -- can be key speedup for large lists -- pass
   303  // [ki.StartMiddle] to start in the middle (good default).
   304  func (n *Node) ChildByName(name string, startIdx int) Ki {
   305  	return n.Kids.ElemByName(name, startIdx)
   306  }
   307  
   308  // ChildByNameTry returns first element that has given name, error if not found.
   309  // startIdx arg allows for optimized bidirectional find if you have
   310  // an idea where it might be -- can be key speedup for large lists -- pass
   311  // [ki.StartMiddle] to start in the middle (good default).
   312  func (n *Node) ChildByNameTry(name string, startIdx int) (Ki, error) {
   313  	idx, ok := n.Kids.IndexByName(name, startIdx)
   314  	if !ok {
   315  		return nil, fmt.Errorf("ki %v: child named: %v not found", n.Nm, name)
   316  	}
   317  	return n.Kids[idx], nil
   318  }
   319  
   320  // ChildByType returns first element that has given type, nil if not found.
   321  // If embeds is true, then it looks for any type that embeds the given type
   322  // at any level of anonymous embedding.
   323  // startIdx arg allows for optimized bidirectional find if you have
   324  // an idea where it might be -- can be key speedup for large lists -- pass
   325  // [ki.StartMiddle] to start in the middle (good default).
   326  func (n *Node) ChildByType(t reflect.Type, embeds bool, startIdx int) Ki {
   327  	return n.Kids.ElemByType(t, embeds, startIdx)
   328  }
   329  
   330  // ChildByTypeTry returns first element that has given name -- Try version
   331  // returns error message if not found.
   332  // If embeds is true, then it looks for any type that embeds the given type
   333  // at any level of anonymous embedding.
   334  // startIdx arg allows for optimized bidirectional find if you have
   335  // an idea where it might be -- can be key speedup for large lists -- pass
   336  // [ki.StartMiddle] to start in the middle (good default).
   337  func (n *Node) ChildByTypeTry(t reflect.Type, embeds bool, startIdx int) (Ki, error) {
   338  	idx, ok := n.Kids.IndexByType(t, embeds, startIdx)
   339  	if !ok {
   340  		return nil, fmt.Errorf("ki %v: child of type: %t not found", n.Nm, t)
   341  	}
   342  	return n.Kids[idx], nil
   343  }
   344  
   345  //////////////////////////////////////////////////////////////////////////
   346  //  Paths
   347  
   348  // EscapePathName returns a name that replaces any path delimiter symbols
   349  // . or / with \, and \\ escaped versions.
   350  func EscapePathName(name string) string {
   351  	return strings.Replace(strings.Replace(name, ".", `\,`, -1), "/", `\\`, -1)
   352  }
   353  
   354  // UnescapePathName returns a name that replaces any escaped path delimiter symbols
   355  // \, or \\ with . and / unescaped versions.
   356  func UnescapePathName(name string) string {
   357  	return strings.Replace(strings.Replace(name, `\,`, ".", -1), `\\`, "/", -1)
   358  }
   359  
   360  // Path returns path to this node from the tree root, using node Names
   361  // separated by / and fields by .
   362  // Node names escape any existing / and . characters to \\ and \,
   363  // Path is only valid when child names are unique (see Unique* functions)
   364  func (n *Node) Path() string {
   365  	if n.Par != nil {
   366  		if n.IsField() {
   367  			return n.Par.Path() + "." + EscapePathName(n.Nm)
   368  		}
   369  		return n.Par.Path() + "/" + EscapePathName(n.Nm)
   370  	}
   371  	return "/" + EscapePathName(n.Nm)
   372  }
   373  
   374  // PathFrom returns path to this node from given parent node, using
   375  // node Names separated by / and fields by .
   376  // Node names escape any existing / and . characters to \\ and \,
   377  // Path is only valid for finding items when child names are unique
   378  // (see Unique* functions)
   379  func (n *Node) PathFrom(par Ki) string {
   380  	if n.Par != nil {
   381  		ppath := ""
   382  		if n.Par == par {
   383  			ppath = "/" + EscapePathName(par.Name())
   384  		} else {
   385  			ppath = n.Par.PathFrom(par)
   386  		}
   387  		if n.IsField() {
   388  			return ppath + "." + EscapePathName(n.Nm)
   389  		}
   390  		return ppath + "/" + EscapePathName(n.Nm)
   391  	}
   392  	return "/" + n.Nm
   393  }
   394  
   395  // find the child on the path
   396  func findPathChild(k Ki, child string) (int, bool) {
   397  	if child[0] == '[' && child[len(child)-1] == ']' {
   398  		idx, err := strconv.Atoi(child[1 : len(child)-1])
   399  		if err != nil {
   400  			return idx, false
   401  		}
   402  		if idx < 0 { // from end
   403  			idx = len(*k.Children()) + idx
   404  		}
   405  		if k.Children().IsValidIndex(idx) != nil {
   406  			return idx, false
   407  		}
   408  		return idx, true
   409  	}
   410  	return k.Children().IndexByName(child, 0)
   411  }
   412  
   413  // FindPath returns Ki object at given path, starting from this node
   414  // (e.g., the root).  If this node is not the root, then the path
   415  // to this node is subtracted from the start of the path if present there.
   416  // FindPath only works correctly when names are unique.
   417  // Path has node Names separated by / and fields by .
   418  // Node names escape any existing / and . characters to \\ and \,
   419  // There is also support for [idx] index-based access for any given path
   420  // element, for cases when indexes are more useful than names.
   421  // Returns nil if not found.
   422  func (n *Node) FindPath(path string) Ki {
   423  	if n.Par != nil { // we are not root..
   424  		myp := n.Path()
   425  		path = strings.TrimPrefix(path, myp)
   426  	}
   427  	curn := Ki(n)
   428  	pels := strings.Split(strings.Trim(strings.TrimSpace(path), "\""), "/")
   429  	for i, pe := range pels {
   430  		if len(pe) == 0 {
   431  			continue
   432  		}
   433  		if i <= 1 && curn.Name() == UnescapePathName(pe) {
   434  			continue
   435  		}
   436  		if strings.Contains(pe, ".") { // has fields
   437  			fels := strings.Split(pe, ".")
   438  			// find the child first, then the fields
   439  			idx, ok := findPathChild(curn, UnescapePathName(fels[0]))
   440  			if !ok {
   441  				return nil
   442  			}
   443  			curn = (*(curn.Children()))[idx]
   444  			for i := 1; i < len(fels); i++ {
   445  				fe := UnescapePathName(fels[i])
   446  				fk := KiFieldByName(curn.AsNode(), fe)
   447  				if fk == nil {
   448  					return nil
   449  				}
   450  				curn = fk
   451  			}
   452  		} else {
   453  			idx, ok := findPathChild(curn, UnescapePathName(pe))
   454  			if !ok {
   455  				return nil
   456  			}
   457  			curn = (*(curn.Children()))[idx]
   458  		}
   459  	}
   460  	return curn
   461  }
   462  
   463  // FindPathTry returns Ki object at given path, starting from this node
   464  // (e.g., the root).  If this node is not the root, then the path
   465  // to this node is subtracted from the start of the path if present there.
   466  // FindPath only works correctly when names are unique.
   467  // Path has node Names separated by / and fields by .
   468  // Node names escape any existing / and . characters to \\ and \,
   469  // There is also support for [idx] index-based access for any given path
   470  // element, for cases when indexes are more useful than names.
   471  // Returns error if not found.
   472  func (n *Node) FindPathTry(path string) (Ki, error) {
   473  	fk := n.This().FindPath(path)
   474  	if fk != nil {
   475  		return fk, nil
   476  	}
   477  	return nil, fmt.Errorf("ki %v: element at path: %v not found", n.Nm, path)
   478  }
   479  
   480  //////////////////////////////////////////////////////////////////////////
   481  //  Adding, Inserting Children
   482  
   483  // AddChild adds given child at end of children list.
   484  // The kid node is assumed to not be on another tree (see MoveToParent)
   485  // and the existing name should be unique among children.
   486  // No UpdateStart / End wrapping is done: do that externally as needed.
   487  // Can also call SetFlag(ki.ChildAdded) if notification is needed.
   488  func (n *Node) AddChild(kid Ki) error {
   489  	if err := ThisCheck(n); err != nil {
   490  		return err
   491  	}
   492  	InitNode(kid)
   493  	n.Kids = append(n.Kids, kid)
   494  	SetParent(kid, n.This()) // key to set new parent before deleting: indicates move instead of delete
   495  	return nil
   496  }
   497  
   498  // AddNewChild creates a new child of given type and
   499  // add at end of children list.
   500  // The name should be unique among children.
   501  // No UpdateStart / End wrapping is done: do that externally as needed.
   502  // Can also call SetChildAdded() if notification is needed.
   503  func (n *Node) AddNewChild(typ reflect.Type, name string) Ki {
   504  	if err := ThisCheck(n); err != nil {
   505  		return nil
   506  	}
   507  	kid := NewOfType(typ)
   508  	InitNode(kid)
   509  	n.Kids = append(n.Kids, kid)
   510  	kid.SetName(name)
   511  	SetParent(kid, n.This())
   512  	return kid
   513  }
   514  
   515  // SetChild sets child at given index to be the given item -- if name is
   516  // non-empty then it sets the name of the child as well -- just calls Init
   517  // (or InitName) on the child, and SetParent.
   518  // Names should be unique among children.
   519  // No UpdateStart / End wrapping is done: do that externally as needed.
   520  // Can also call SetChildAdded() if notification is needed.
   521  func (n *Node) SetChild(kid Ki, idx int, name string) error {
   522  	if err := n.Kids.IsValidIndex(idx); err != nil {
   523  		return err
   524  	}
   525  	if name != "" {
   526  		kid.InitName(kid, name)
   527  	} else {
   528  		InitNode(kid)
   529  	}
   530  	n.Kids[idx] = kid
   531  	SetParent(kid, n.This())
   532  	return nil
   533  }
   534  
   535  // InsertChild adds given child at position in children list.
   536  // The kid node is assumed to not be on another tree (see MoveToParent)
   537  // and the existing name should be unique among children.
   538  // No UpdateStart / End wrapping is done: do that externally as needed.
   539  // Can also call SetChildAdded() if notification is needed.
   540  func (n *Node) InsertChild(kid Ki, at int) error {
   541  	if err := ThisCheck(n); err != nil {
   542  		return err
   543  	}
   544  	InitNode(kid)
   545  	n.Kids.Insert(kid, at)
   546  	SetParent(kid, n.This())
   547  	return nil
   548  }
   549  
   550  // InsertNewChild creates a new child of given type and
   551  // add at position in children list.
   552  // The name should be unique among children.
   553  // No UpdateStart / End wrapping is done: do that externally as needed.
   554  // Can also call SetChildAdded() if notification is needed.
   555  func (n *Node) InsertNewChild(typ reflect.Type, at int, name string) Ki {
   556  	if err := ThisCheck(n); err != nil {
   557  		return nil
   558  	}
   559  	kid := NewOfType(typ)
   560  	InitNode(kid)
   561  	n.Kids.Insert(kid, at)
   562  	kid.SetName(name)
   563  	SetParent(kid, n.This())
   564  	return kid
   565  }
   566  
   567  // SetNChildren ensures that there are exactly n children, deleting any
   568  // extra, and creating any new ones, using AddNewChild with given type and
   569  // naming according to nameStubX where X is the index of the child.
   570  //
   571  // IMPORTANT: returns whether any modifications were made (mods) AND if
   572  // that is true, the result from the corresponding UpdateStart call --
   573  // UpdateEnd is NOT called, allowing for further subsequent updates before
   574  // you call UpdateEnd(updt)
   575  //
   576  // Note that this does not ensure existing children are of given type, or
   577  // change their names -- use ConfigChildren for those cases.
   578  // This function is for simpler cases where a parent uses this function
   579  // consistently to manage children all of the same type.
   580  func (n *Node) SetNChildren(trgn int, typ reflect.Type, nameStub string) (mods, updt bool) {
   581  	mods, updt = false, false
   582  	sz := len(n.Kids)
   583  	if trgn == sz {
   584  		return
   585  	}
   586  	for sz > trgn {
   587  		if !mods {
   588  			mods = true
   589  			updt = n.UpdateStart()
   590  		}
   591  		sz--
   592  		n.DeleteChildAtIndex(sz, true)
   593  	}
   594  	for sz < trgn {
   595  		if !mods {
   596  			mods = true
   597  			updt = n.UpdateStart()
   598  		}
   599  		nm := fmt.Sprintf("%s%d", nameStub, sz)
   600  		n.InsertNewChild(typ, sz, nm)
   601  		sz++
   602  	}
   603  	return
   604  }
   605  
   606  // ConfigChildren configures children according to given list of
   607  // type-and-name's -- attempts to have minimal impact relative to existing
   608  // items that fit the type and name constraints (they are moved into the
   609  // corresponding positions), and any extra children are removed, and new
   610  // ones added, to match the specified config.  If uniqNm, then names
   611  // represent UniqueNames (this results in Name == UniqueName for created
   612  // children).
   613  //
   614  // IMPORTANT: returns whether any modifications were made (mods) AND if
   615  // that is true, the result from the corresponding UpdateStart call --
   616  // UpdateEnd is NOT called, allowing for further subsequent updates before
   617  // you call UpdateEnd(updt).
   618  func (n *Node) ConfigChildren(config kit.TypeAndNameList) (mods, updt bool) {
   619  	return n.Kids.Config(n.This(), config)
   620  }
   621  
   622  //////////////////////////////////////////////////////////////////////////
   623  //  Deleting Children
   624  
   625  // DeleteChildAtIndex deletes child at given index (returns error for
   626  // invalid index).
   627  // Wraps delete in UpdateStart / End and sets ChildDeleted flag.
   628  func (n *Node) DeleteChildAtIndex(idx int, destroy bool) error {
   629  	child, err := n.ChildTry(idx)
   630  	if err != nil {
   631  		return err
   632  	}
   633  	updt := n.UpdateStart()
   634  	n.SetFlag(int(ChildDeleted))
   635  	if child.Parent() == n.This() {
   636  		// only deleting if we are still parent -- change parent first to
   637  		// signal move delete is always sent live to affected node without
   638  		// update blocking note: children of child etc will not send a signal
   639  		// at this point -- only later at destroy -- up to this parent to
   640  		// manage all that
   641  		child.SetFlag(int(NodeDeleted))
   642  		child.NodeSignal().Emit(child, int64(NodeSignalDeleting), nil)
   643  		SetParent(child, nil)
   644  	}
   645  	n.Kids.DeleteAtIndex(idx)
   646  	if destroy {
   647  		DelMgr.Add(child)
   648  	}
   649  	UpdateReset(child) // it won't get the UpdateEnd from us anymore -- init fresh in any case
   650  	n.UpdateEnd(updt)
   651  	return nil
   652  }
   653  
   654  // DeleteChild deletes child node, returning error if not found in
   655  // Children.
   656  // Wraps delete in UpdateStart / End and sets ChildDeleted flag.
   657  func (n *Node) DeleteChild(child Ki, destroy bool) error {
   658  	if child == nil {
   659  		return errors.New("ki DeleteChild: child is nil")
   660  	}
   661  	idx, ok := n.Kids.IndexOf(child, 0)
   662  	if !ok {
   663  		return fmt.Errorf("ki %v: child: %v not found", n.Nm, child.Path())
   664  	}
   665  	return n.DeleteChildAtIndex(idx, destroy)
   666  }
   667  
   668  // DeleteChildByName deletes child node by name -- returns child, error
   669  // if not found.
   670  // Wraps delete in UpdateStart / End and sets ChildDeleted flag.
   671  func (n *Node) DeleteChildByName(name string, destroy bool) (Ki, error) {
   672  	idx, ok := n.Kids.IndexByName(name, 0)
   673  	if !ok {
   674  		return nil, fmt.Errorf("ki %v: child named: %v not found", n.Nm, name)
   675  	}
   676  	child := n.Kids[idx]
   677  	return child, n.DeleteChildAtIndex(idx, destroy)
   678  }
   679  
   680  // DeleteChildren deletes all children nodes -- destroy will add removed
   681  // children to deleted list, to be destroyed later -- otherwise children
   682  // remain intact but parent is nil -- could be inserted elsewhere, but you
   683  // better have kept a slice of them before calling this.
   684  func (n *Node) DeleteChildren(destroy bool) {
   685  	updt := n.UpdateStart()
   686  	n.SetFlag(int(ChildrenDeleted))
   687  	kids := n.Kids
   688  	n.Kids = n.Kids[:0] // preserves capacity of list
   689  	for _, child := range kids {
   690  		if child == nil {
   691  			continue
   692  		}
   693  		child.SetFlag(int(NodeDeleted))
   694  		child.NodeSignal().Emit(child, int64(NodeSignalDeleting), nil)
   695  		SetParent(child, nil)
   696  		UpdateReset(child)
   697  	}
   698  	if destroy {
   699  		DelMgr.Add(kids...)
   700  	}
   701  	n.UpdateEnd(updt)
   702  }
   703  
   704  // Delete deletes this node from its parent children list -- destroy will
   705  // add removed child to deleted list, to be destroyed later -- otherwise
   706  // child remains intact but parent is nil -- could be inserted elsewhere.
   707  func (n *Node) Delete(destroy bool) {
   708  	if n.Par == nil {
   709  		if destroy {
   710  			n.This().Destroy()
   711  		}
   712  	} else {
   713  		n.Par.DeleteChild(n.This(), destroy)
   714  	}
   715  }
   716  
   717  // Destroy calls DisconnectAll to cut all pointers and signal connections,
   718  // and remove all children and their childrens-children, etc.
   719  func (n *Node) Destroy() {
   720  	// fmt.Printf("Destroying: %v %T %p Kids: %v\n", n.Nm, n.This(), n.This(), len(n.Kids))
   721  	if n.This() == nil { // already dead!
   722  		return
   723  	}
   724  	n.DisconnectAll()
   725  	n.DeleteChildren(true) // first delete all my children
   726  	// and destroy all my fields
   727  	n.FuncFields(0, nil, func(k Ki, level int, d any) bool {
   728  		k.Destroy()
   729  		return true
   730  	})
   731  	DelMgr.DestroyDeleted() // then destroy all those kids
   732  	n.SetFlag(int(NodeDestroyed))
   733  	n.Ths = nil // last gasp: lose our own sense of self..
   734  	// note: above is thread-safe because This() accessor checks Destroyed
   735  }
   736  
   737  //////////////////////////////////////////////////////////////////////////
   738  //  Flags
   739  
   740  // Flags returns an atomically safe copy of the bit flags for this node --
   741  // can use bitflag package to check lags.
   742  // See Flags type for standard values used in Ki Node --
   743  // can be extended from FlagsN up to 64 bit capacity.
   744  // Note that we must always use atomic access as *some* things need to be atomic,
   745  // and with bits, that means that *all* access needs to be atomic,
   746  // as you cannot atomically update just a single bit.
   747  func (n *Node) Flags() int64 {
   748  	return atomic.LoadInt64(&n.Flag)
   749  }
   750  
   751  // HasFlag checks if flag is set
   752  // using atomic, safe for concurrent access
   753  func (n *Node) HasFlag(flag int) bool {
   754  	return bitflag.HasAtomic(&n.Flag, flag)
   755  }
   756  
   757  // SetFlag sets the given flag(s)
   758  // using atomic, safe for concurrent access
   759  func (n *Node) SetFlag(flag ...int) {
   760  	bitflag.SetAtomic(&n.Flag, flag...)
   761  }
   762  
   763  // SetFlagState sets the given flag(s) to given state
   764  // using atomic, safe for concurrent access
   765  func (n *Node) SetFlagState(on bool, flag ...int) {
   766  	bitflag.SetStateAtomic(&n.Flag, on, flag...)
   767  }
   768  
   769  // SetFlagMask sets the given flags as a mask
   770  // using atomic, safe for concurrent access
   771  func (n *Node) SetFlagMask(mask int64) {
   772  	bitflag.SetMaskAtomic(&n.Flag, mask)
   773  }
   774  
   775  // ClearFlag clears the given flag(s)
   776  // using atomic, safe for concurrent access
   777  func (n *Node) ClearFlag(flag ...int) {
   778  	bitflag.ClearAtomic(&n.Flag, flag...)
   779  }
   780  
   781  // ClearFlagMask clears the given flags as a bitmask
   782  // using atomic, safe for concurrent access
   783  func (n *Node) ClearFlagMask(mask int64) {
   784  	bitflag.ClearMaskAtomic(&n.Flag, mask)
   785  }
   786  
   787  // IsField checks if this is a field on a parent struct (via IsField
   788  // Flag), as opposed to a child in Children -- Ki nodes can be added as
   789  // fields to structs and they are automatically parented and named with
   790  // field name during Init function -- essentially they function as fixed
   791  // children of the parent struct, and are automatically included in
   792  // FuncDown* traversals, etc -- see also FunFields.
   793  func (n *Node) IsField() bool {
   794  	return bitflag.HasAtomic(&n.Flag, int(IsField))
   795  }
   796  
   797  // IsUpdating checks if node is currently updating.
   798  func (n *Node) IsUpdating() bool {
   799  	return bitflag.HasAtomic(&n.Flag, int(Updating))
   800  }
   801  
   802  // OnlySelfUpdate checks if this node only applies UpdateStart / End logic
   803  // to itself, not its children (which is the default) (via Flag of same
   804  // name) -- useful for a parent node that has a different function than
   805  // its children.
   806  func (n *Node) OnlySelfUpdate() bool {
   807  	return bitflag.HasAtomic(&n.Flag, int(OnlySelfUpdate))
   808  }
   809  
   810  // SetOnlySelfUpdate sets the OnlySelfUpdate flag -- see OnlySelfUpdate
   811  // method and flag.
   812  func (n *Node) SetOnlySelfUpdate() {
   813  	n.SetFlag(int(OnlySelfUpdate))
   814  }
   815  
   816  // SetChildAdded sets the ChildAdded flag -- set when notification is needed
   817  // for Add, Insert methods
   818  func (n *Node) SetChildAdded() {
   819  	n.SetFlag(int(ChildAdded))
   820  }
   821  
   822  // SetValUpdated sets the ValUpdated flag -- set when notification is needed
   823  // for modifying a value (field, prop, etc)
   824  func (n *Node) SetValUpdated() {
   825  	n.SetFlag(int(ValUpdated))
   826  }
   827  
   828  // IsDeleted checks if this node has just been deleted (within last update
   829  // cycle), indicated by the NodeDeleted flag which is set when the node is
   830  // deleted, and is cleared at next UpdateStart call.
   831  func (n *Node) IsDeleted() bool {
   832  	return bitflag.HasAtomic(&n.Flag, int(NodeDeleted))
   833  }
   834  
   835  // IsDestroyed checks if this node has been destroyed -- the NodeDestroyed
   836  // flag is set at start of Destroy function -- the Signal Emit process
   837  // checks for destroyed receiver nodes and removes connections to them
   838  // automatically -- other places where pointers to potentially destroyed
   839  // nodes may linger should also check this flag and reset those pointers.
   840  func (n *Node) IsDestroyed() bool {
   841  	return bitflag.HasAtomic(&n.Flag, int(NodeDestroyed))
   842  }
   843  
   844  //////////////////////////////////////////////////////////////////////////
   845  //  Property interface with inheritance -- nodes can inherit props from parents
   846  
   847  // Properties (Node.Props) tell the GoGi GUI or other frameworks operating
   848  // on Trees about special features of each node -- functions below support
   849  // inheritance up Tree -- see kit convert.go for robust convenience
   850  // methods for converting interface{} values to standard types.
   851  func (n *Node) Properties() *Props {
   852  	return &n.Props
   853  }
   854  
   855  // SetProp sets given property key to value val.
   856  // initializes property map if nil.
   857  func (n *Node) SetProp(key string, val any) {
   858  	if n.Props == nil {
   859  		n.Props = make(Props)
   860  	}
   861  	n.Props[key] = val
   862  }
   863  
   864  // SetPropStr sets given property key to value val as a string (e.g., for python wrapper)
   865  // Initializes property map if nil.
   866  func (n *Node) SetPropStr(key string, val string) {
   867  	n.SetProp(key, val)
   868  }
   869  
   870  // SetPropInt sets given property key to value val as an int (e.g., for python wrapper)
   871  // Initializes property map if nil.
   872  func (n *Node) SetPropInt(key string, val int) {
   873  	n.SetProp(key, val)
   874  }
   875  
   876  // SetPropFloat64 sets given property key to value val as a float64 (e.g., for python wrapper)
   877  // Initializes property map if nil.
   878  func (n *Node) SetPropFloat64(key string, val float64) {
   879  	n.SetProp(key, val)
   880  }
   881  
   882  // SetSubProps sets given property key to sub-Props value (e.g., for python wrapper)
   883  // Initializes property map if nil.
   884  func (n *Node) SetSubProps(key string, val Props) {
   885  	n.SetProp(key, val)
   886  }
   887  
   888  // SetProps sets a whole set of properties
   889  func (n *Node) SetProps(props Props) {
   890  	if n.Props == nil {
   891  		n.Props = make(Props, len(props))
   892  	}
   893  	for key, val := range props {
   894  		n.Props[key] = val
   895  	}
   896  }
   897  
   898  // Prop returns property value for key that is known to exist.
   899  // Returns nil if it actually doesn't -- this version allows
   900  // direct conversion of return.  See PropTry for version with
   901  // error message if uncertain if property exists.
   902  func (n *Node) Prop(key string) any {
   903  	return n.Props[key]
   904  }
   905  
   906  // PropTry returns property value for key.  Returns error message
   907  // if property with that key does not exist.
   908  func (n *Node) PropTry(key string) (any, error) {
   909  	v, ok := n.Props[key]
   910  	if !ok {
   911  		return v, fmt.Errorf("ki.PropTry, could not find property with key %v on node %v", key, n.Nm)
   912  	}
   913  	return v, nil
   914  }
   915  
   916  // PropInherit gets property value from key with options for inheriting
   917  // property from parents and / or type-level properties.  If inherit, then
   918  // checks all parents.  If typ then checks property on type as well
   919  // (registered via KiT type registry).  Returns false if not set anywhere.
   920  func (n *Node) PropInherit(key string, inherit, typ bool) (any, bool) {
   921  	// pr := prof.Start("PropInherit")
   922  	// defer pr.End()
   923  	v, ok := n.Props[key]
   924  	if ok {
   925  		return v, ok
   926  	}
   927  	if inherit && n.Par != nil {
   928  		v, ok = n.Par.PropInherit(key, inherit, typ)
   929  		if ok {
   930  			return v, ok
   931  		}
   932  	}
   933  	if typ {
   934  		return kit.Types.Prop(Type(n.This()), key)
   935  	}
   936  	return nil, false
   937  }
   938  
   939  // DeleteProp deletes property key on this node.
   940  func (n *Node) DeleteProp(key string) {
   941  	if n.Props == nil {
   942  		return
   943  	}
   944  	delete(n.Props, key)
   945  }
   946  
   947  func init() {
   948  	gob.Register(Props{})
   949  }
   950  
   951  // CopyPropsFrom copies our properties from another node -- if deep then
   952  // does a deep copy -- otherwise copied map just points to same values in
   953  // the original map (and we don't reset our map first -- call
   954  // DeleteAllProps to do that -- deep copy uses gob encode / decode --
   955  // usually not needed).
   956  func (n *Node) CopyPropsFrom(frm Ki, deep bool) error {
   957  	if *(frm.Properties()) == nil {
   958  		return nil
   959  	}
   960  	// pr := prof.Start("CopyPropsFrom")
   961  	// defer pr.End()
   962  	if n.Props == nil {
   963  		n.Props = make(Props)
   964  	}
   965  	fmP := *(frm.Properties())
   966  	if deep {
   967  		// code from https://gist.github.com/soroushjp/0ec92102641ddfc3ad5515ca76405f4d
   968  		var buf bytes.Buffer
   969  		enc := gob.NewEncoder(&buf)
   970  		dec := gob.NewDecoder(&buf)
   971  		err := enc.Encode(fmP)
   972  		if err != nil {
   973  			return err
   974  		}
   975  		err = dec.Decode(&n.Props)
   976  		if err != nil {
   977  			return err
   978  		}
   979  		return nil
   980  	}
   981  	for k, v := range fmP {
   982  		n.Props[k] = v
   983  	}
   984  	return nil
   985  }
   986  
   987  // PropTag returns the name to look for in type properties, for types
   988  // that are valid options for values that can be set in Props.  For example
   989  // in GoGi, it is "style-props" which is then set for all types that can
   990  // be used in a style (colors, enum options, etc)
   991  func (n *Node) PropTag() string {
   992  	return ""
   993  }
   994  
   995  //////////////////////////////////////////////////////////////////////////
   996  //  Tree walking and state updating
   997  
   998  // FlatFieldsValueFunc is the Node version of this function from kit/embeds.go
   999  // it is very slow and should be avoided at all costs!
  1000  func FlatFieldsValueFunc(stru any, fun func(stru any, typ reflect.Type, field reflect.StructField, fieldVal reflect.Value) bool) bool {
  1001  	v := kit.NonPtrValue(reflect.ValueOf(stru))
  1002  	typ := v.Type()
  1003  	if typ == nil || typ == KiT_Node { // this is only diff from embeds.go version -- prevent processing of any Node fields
  1004  		return true
  1005  	}
  1006  	rval := true
  1007  	for i := 0; i < typ.NumField(); i++ {
  1008  		f := typ.Field(i)
  1009  		vf := v.Field(i)
  1010  		if !vf.CanInterface() {
  1011  			continue
  1012  		}
  1013  		vfi := vf.Interface() // todo: check for interfaceablity etc
  1014  		if vfi == nil || vfi == stru {
  1015  			continue
  1016  		}
  1017  		if f.Type.Kind() == reflect.Struct && f.Anonymous && kit.PtrType(f.Type) != KiT_Node {
  1018  			rval = FlatFieldsValueFunc(kit.PtrValue(vf).Interface(), fun)
  1019  			if !rval {
  1020  				break
  1021  			}
  1022  		} else {
  1023  			rval = fun(vfi, typ, f, vf)
  1024  			if !rval {
  1025  				break
  1026  			}
  1027  		}
  1028  	}
  1029  	return rval
  1030  }
  1031  
  1032  // FuncFields calls function on all Ki fields within this node.
  1033  func (n *Node) FuncFields(level int, data any, fun Func) {
  1034  	if n.This() == nil {
  1035  		return
  1036  	}
  1037  	op := uintptr(unsafe.Pointer(n))
  1038  	foffs := KiFieldOffs(n)
  1039  	for _, fo := range foffs {
  1040  		fn := (*Node)(unsafe.Pointer(op + fo))
  1041  		fun(fn.This(), level, data)
  1042  	}
  1043  }
  1044  
  1045  // FuncUp calls function on given node and all the way up to its parents,
  1046  // and so on -- sequentially all in current go routine (generally
  1047  // necessary for going up, which is typically quite fast anyway) -- level
  1048  // is incremented after each step (starts at 0, goes up), and passed to
  1049  // function -- returns false if fun aborts with false, else true.
  1050  func (n *Node) FuncUp(level int, data any, fun Func) bool {
  1051  	cur := n.This()
  1052  	for {
  1053  		if !fun(cur, level, data) { // false return means stop
  1054  			return false
  1055  		}
  1056  		level++
  1057  		par := cur.Parent()
  1058  		if par == nil || par == cur { // prevent loops
  1059  			return true
  1060  		}
  1061  		cur = par
  1062  	}
  1063  	return true
  1064  }
  1065  
  1066  // FuncUpParent calls function on parent of node and all the way up to its
  1067  // parents, and so on -- sequentially all in current go routine (generally
  1068  // necessary for going up, which is typically quite fast anyway) -- level
  1069  // is incremented after each step (starts at 0, goes up), and passed to
  1070  // function -- returns false if fun aborts with false, else true.
  1071  func (n *Node) FuncUpParent(level int, data any, fun Func) bool {
  1072  	if IsRoot(n) {
  1073  		return true
  1074  	}
  1075  	cur := n.Parent()
  1076  	for {
  1077  		if !fun(cur, level, data) { // false return means stop
  1078  			return false
  1079  		}
  1080  		level++
  1081  		par := cur.Parent()
  1082  		if par == nil || par == cur { // prevent loops
  1083  			return true
  1084  		}
  1085  		cur = par
  1086  	}
  1087  }
  1088  
  1089  ////////////////////////////////////////////////////////////////////////
  1090  // FuncDown -- Traversal records
  1091  
  1092  // TravIdxs are tree traversal indexes
  1093  type TravIdxs struct {
  1094  
  1095  	// current index of field: -1 for start
  1096  	Field int `desc:"current index of field: -1 for start"`
  1097  
  1098  	// current index of children: -1 for start
  1099  	Child int `desc:"current index of children: -1 for start"`
  1100  }
  1101  
  1102  // TravMap is a map for recording the traversal of nodes
  1103  type TravMap map[Ki]TravIdxs
  1104  
  1105  // Start is called at start of traversal
  1106  func (tm TravMap) Start(k Ki) {
  1107  	tm[k] = TravIdxs{-1, -1}
  1108  }
  1109  
  1110  // End deletes node once done at end of traversal
  1111  func (tm TravMap) End(k Ki) {
  1112  	delete(tm, k)
  1113  }
  1114  
  1115  // Set updates traversal state
  1116  func (tm TravMap) Set(k Ki, curField, curChild int) {
  1117  	tm[k] = TravIdxs{curField, curChild}
  1118  }
  1119  
  1120  // Get retrieves current traversal state
  1121  func (tm TravMap) Get(k Ki) (curField, curChild int) {
  1122  	tr := tm[k]
  1123  	return tr.Field, tr.Child
  1124  }
  1125  
  1126  // strategy -- same as used in TreeView:
  1127  // https://stackoverflow.com/questions/5278580/non-recursive-depth-first-search-algorithm
  1128  
  1129  // FuncDownMeFirst calls function on this node (MeFirst) and then iterates
  1130  // in a depth-first manner over all the children, including Ki Node fields,
  1131  // which are processed first before children.
  1132  // The node traversal is non-recursive and uses locally-allocated state -- safe
  1133  // for concurrent calling (modulo conflict management in function call itself).
  1134  // Function calls are sequential all in current go routine.
  1135  // The level var tracks overall depth in the tree.
  1136  // If fun returns false then any further traversal of that branch of the tree is
  1137  // aborted, but other branches continue -- i.e., if fun on current node
  1138  // returns false, children are not processed further.
  1139  func (n *Node) FuncDownMeFirst(level int, data any, fun Func) {
  1140  	if n.This() == nil || n.IsDeleted() {
  1141  		return
  1142  	}
  1143  	tm := TravMap{} // not significantly faster to pre-allocate larger size
  1144  	start := n.This()
  1145  	cur := start
  1146  	tm.Start(cur)
  1147  outer:
  1148  	for {
  1149  		if cur.This() != nil && !cur.IsDeleted() && fun(cur, level, data) { // false return means stop
  1150  			level++ // this is the descent branch
  1151  			if KiHasKiFields(cur.AsNode()) {
  1152  				tm.Set(cur, 0, -1)
  1153  				nxt := KiField(cur.AsNode(), 0).This()
  1154  				if nxt != nil {
  1155  					cur = nxt
  1156  					tm.Start(cur)
  1157  					continue
  1158  				}
  1159  			}
  1160  			if cur.HasChildren() {
  1161  				tm.Set(cur, 0, 0) // 0 for no fields
  1162  				nxt := cur.Child(0)
  1163  				if nxt != nil && nxt.This() != nil && !nxt.IsDeleted() {
  1164  					cur = nxt.This()
  1165  					tm.Start(cur)
  1166  					continue
  1167  				}
  1168  			}
  1169  		} else {
  1170  			tm.Set(cur, NumKiFields(cur.AsNode()), cur.NumChildren())
  1171  			level++ // we will pop back up out of this next
  1172  		}
  1173  		// if we get here, we're in the ascent branch -- move to the right and then up
  1174  		for {
  1175  			curField, curChild := tm.Get(cur)
  1176  			if KiHasKiFields(cur.AsNode()) {
  1177  				if (curField + 1) < NumKiFields(cur.AsNode()) {
  1178  					curField++
  1179  					tm.Set(cur, curField, curChild)
  1180  					nxt := KiField(cur.AsNode(), curField).This()
  1181  					if nxt != nil {
  1182  						cur = nxt
  1183  						tm.Start(cur)
  1184  						continue outer
  1185  					}
  1186  					continue
  1187  				}
  1188  			}
  1189  			if (curChild + 1) < cur.NumChildren() {
  1190  				curChild++
  1191  				tm.Set(cur, curField, curChild)
  1192  				nxt := cur.Child(curChild)
  1193  				if nxt != nil && nxt.This() != nil && !nxt.IsDeleted() {
  1194  					cur = nxt.This()
  1195  					tm.Start(cur)
  1196  					continue outer
  1197  				}
  1198  				continue
  1199  			}
  1200  			tm.End(cur)
  1201  			// couldn't go right, move up..
  1202  			if cur == start {
  1203  				break outer // done!
  1204  			}
  1205  			level--
  1206  			par := cur.Parent()
  1207  			if par == nil || par == cur { // shouldn't happen, but does..
  1208  				// fmt.Printf("nil / cur parent %v\n", par)
  1209  				break outer
  1210  			}
  1211  			cur = par
  1212  		}
  1213  	}
  1214  }
  1215  
  1216  // FuncDownMeLast iterates in a depth-first manner over the children, calling
  1217  // doChildTestFunc on each node to test if processing should proceed (if it returns
  1218  // false then that branch of the tree is not further processed), and then
  1219  // calls given fun function after all of a node's children (including fields)
  1220  // have been iterated over ("Me Last").
  1221  // The node traversal is non-recursive and uses locally-allocated state -- safe
  1222  // for concurrent calling (modulo conflict management in function call itself).
  1223  // Function calls are sequential all in current go routine.
  1224  // The level var tracks overall depth in the tree.
  1225  func (n *Node) FuncDownMeLast(level int, data any, doChildTestFunc Func, fun Func) {
  1226  	if n.This() == nil || n.IsDeleted() {
  1227  		return
  1228  	}
  1229  	tm := TravMap{} // not significantly faster to pre-allocate larger size
  1230  	start := n.This()
  1231  	cur := start
  1232  	tm.Start(cur)
  1233  outer:
  1234  	for {
  1235  		if cur.This() != nil && !cur.IsDeleted() && doChildTestFunc(cur, level, data) { // false return means stop
  1236  			level++ // this is the descent branch
  1237  			if KiHasKiFields(cur.AsNode()) {
  1238  				tm.Set(cur, 0, -1)
  1239  				nxt := KiField(cur.AsNode(), 0).This()
  1240  				if nxt != nil {
  1241  					cur = nxt
  1242  					tm.Set(cur, -1, -1)
  1243  					continue
  1244  				}
  1245  			}
  1246  			if cur.HasChildren() {
  1247  				tm.Set(cur, 0, 0) // 0 for no fields
  1248  				nxt := cur.Child(0)
  1249  				if nxt != nil && nxt.This() != nil && !nxt.IsDeleted() {
  1250  					cur = nxt.This()
  1251  					tm.Set(cur, -1, -1)
  1252  					continue
  1253  				}
  1254  			}
  1255  		} else {
  1256  			tm.Set(cur, NumKiFields(cur.AsNode()), cur.NumChildren())
  1257  			level++ // we will pop back up out of this next
  1258  		}
  1259  		// if we get here, we're in the ascent branch -- move to the right and then up
  1260  		for {
  1261  			curField, curChild := tm.Get(cur)
  1262  			if KiHasKiFields(cur.AsNode()) {
  1263  				if (curField + 1) < NumKiFields(cur.AsNode()) {
  1264  					curField++
  1265  					tm.Set(cur, curField, curChild)
  1266  					nxt := KiField(cur.AsNode(), curField).This()
  1267  					if nxt != nil {
  1268  						cur = nxt
  1269  						tm.Set(cur, -1, -1)
  1270  						continue outer
  1271  					}
  1272  					continue
  1273  				}
  1274  			}
  1275  			if (curChild + 1) < cur.NumChildren() {
  1276  				curChild++
  1277  				tm.Set(cur, curField, curChild)
  1278  				nxt := cur.Child(curChild)
  1279  				if nxt != nil && nxt.This() != nil && !nxt.IsDeleted() {
  1280  					cur = nxt.This()
  1281  					tm.Start(cur)
  1282  					continue outer
  1283  				}
  1284  				continue
  1285  			}
  1286  			level--
  1287  			fun(cur, level, data) // now we call the function, last..
  1288  			// couldn't go right, move up..
  1289  			tm.End(cur)
  1290  			if cur == start {
  1291  				break outer // done!
  1292  			}
  1293  			par := cur.Parent()
  1294  			if par == nil || par == cur { // shouldn't happen
  1295  				break outer
  1296  			}
  1297  			cur = par
  1298  		}
  1299  	}
  1300  }
  1301  
  1302  // Note: it does not appear that there is a good recursive BFS search strategy
  1303  // https://herringtondarkholme.github.io/2014/02/17/generator/
  1304  // https://stackoverflow.com/questions/2549541/performing-breadth-first-search-recursively/2549825#2549825
  1305  
  1306  // FuncDownBreadthFirst calls function on all children in breadth-first order
  1307  // using the standard queue strategy.  This depends on and updates the
  1308  // Depth parameter of the node.  If fun returns false then any further
  1309  // traversal of that branch of the tree is aborted, but other branches continue.
  1310  func (n *Node) FuncDownBreadthFirst(level int, data any, fun Func) {
  1311  	start := n.This()
  1312  
  1313  	SetDepth(start, level)
  1314  	queue := make([]Ki, 1)
  1315  	queue[0] = start
  1316  
  1317  	for {
  1318  		if len(queue) == 0 {
  1319  			break
  1320  		}
  1321  		cur := queue[0]
  1322  		depth := Depth(cur)
  1323  		queue = queue[1:]
  1324  
  1325  		if cur.This() != nil && !cur.IsDeleted() && fun(cur, depth, data) { // false return means don't proceed
  1326  			if KiHasKiFields(cur.AsNode()) {
  1327  				cur.FuncFields(depth+1, data, func(k Ki, level int, d any) bool {
  1328  					SetDepth(k, level)
  1329  					queue = append(queue, k)
  1330  					return true
  1331  				})
  1332  			}
  1333  			for _, k := range *cur.Children() {
  1334  				if k != nil && k.This() != nil && !k.IsDeleted() {
  1335  					SetDepth(k, depth+1)
  1336  					queue = append(queue, k)
  1337  				}
  1338  			}
  1339  		}
  1340  	}
  1341  }
  1342  
  1343  //////////////////////////////////////////////////////////////////////////
  1344  //  State update signaling -- automatically consolidates all changes across
  1345  //   levels so there is only one update at highest level of modification
  1346  //   All modification starts with UpdateStart() and ends with UpdateEnd()
  1347  
  1348  // after an UpdateEnd, DestroyDeleted is called
  1349  
  1350  // NodeSignal returns the main signal for this node that is used for
  1351  // update, child signals.
  1352  func (n *Node) NodeSignal() *Signal {
  1353  	return &n.NodeSig
  1354  }
  1355  
  1356  // UpdateStart should be called when starting to modify the tree (state or
  1357  // structure) -- returns whether this node was first to set the Updating
  1358  // flag (if so, all children have their Updating flag set -- pass the
  1359  // result to UpdateEnd -- automatically determines the highest level
  1360  // updated, within the normal top-down updating sequence -- can be called
  1361  // multiple times at multiple levels -- it is essential to ensure that all
  1362  // such Start's have an End!  Usage:
  1363  //
  1364  //	updt := n.UpdateStart()
  1365  //	... code
  1366  //	n.UpdateEnd(updt)
  1367  //
  1368  // or
  1369  //
  1370  //	updt := n.UpdateStart()
  1371  //	defer n.UpdateEnd(updt)
  1372  //	... code
  1373  func (n *Node) UpdateStart() bool {
  1374  	if n.IsUpdating() || n.IsDestroyed() {
  1375  		return false
  1376  	}
  1377  	if n.OnlySelfUpdate() {
  1378  		n.SetFlag(int(Updating))
  1379  	} else {
  1380  		// pr := prof.Start("ki.Node.UpdateStart")
  1381  		n.FuncDownMeFirst(0, nil, func(k Ki, level int, d any) bool {
  1382  			if !k.IsUpdating() {
  1383  				k.ClearFlagMask(int64(UpdateFlagsMask))
  1384  				k.SetFlag(int(Updating))
  1385  				return Continue
  1386  			}
  1387  			return Break // bail -- already updating
  1388  		})
  1389  		// pr.End()
  1390  	}
  1391  	return true
  1392  }
  1393  
  1394  // UpdateEnd should be called when done updating after an UpdateStart, and
  1395  // passed the result of the UpdateStart call -- if this is true, the
  1396  // NodeSignalUpdated signal will be emitted and the Updating flag will be
  1397  // cleared, and DestroyDeleted called -- otherwise it is a no-op.
  1398  func (n *Node) UpdateEnd(updt bool) {
  1399  	if !updt {
  1400  		return
  1401  	}
  1402  	if n.IsDestroyed() || n.IsDeleted() {
  1403  		return
  1404  	}
  1405  	if bitflag.HasAnyAtomic(&n.Flag, int(ChildDeleted), int(ChildrenDeleted)) {
  1406  		DelMgr.DestroyDeleted()
  1407  	}
  1408  	if n.OnlySelfUpdate() {
  1409  		n.ClearFlag(int(Updating))
  1410  		n.NodeSignal().Emit(n.This(), int64(NodeSignalUpdated), n.Flags())
  1411  	} else {
  1412  		// pr := prof.Start("ki.Node.UpdateEnd")
  1413  		n.FuncDownMeFirst(0, nil, func(k Ki, level int, d any) bool {
  1414  			k.ClearFlag(int(Updating)) // note: could check first and break here but good to ensure all clear
  1415  			return true
  1416  		})
  1417  		// pr.End()
  1418  		n.NodeSignal().Emit(n.This(), int64(NodeSignalUpdated), n.Flags())
  1419  	}
  1420  }
  1421  
  1422  // UpdateEndNoSig is just like UpdateEnd except it does not emit a
  1423  // NodeSignalUpdated signal -- use this for situations where updating is
  1424  // already known to be in progress and the signal would be redundant.
  1425  func (n *Node) UpdateEndNoSig(updt bool) {
  1426  	if !updt {
  1427  		return
  1428  	}
  1429  	if n.IsDestroyed() || n.IsDeleted() {
  1430  		return
  1431  	}
  1432  	if bitflag.HasAnyAtomic(&n.Flag, int(ChildDeleted), int(ChildrenDeleted)) {
  1433  		DelMgr.DestroyDeleted()
  1434  	}
  1435  	if n.OnlySelfUpdate() {
  1436  		n.ClearFlag(int(Updating))
  1437  		// n.NodeSignal().Emit(n.This(), int64(NodeSignalUpdated), n.Flags())
  1438  	} else {
  1439  		n.FuncDownMeFirst(0, nil, func(k Ki, level int, d any) bool {
  1440  			k.ClearFlag(int(Updating)) // note: could check first and break here but good to ensure all clear
  1441  			return true
  1442  		})
  1443  		// n.NodeSignal().Emit(n.This(), int64(NodeSignalUpdated), n.Flags())
  1444  	}
  1445  }
  1446  
  1447  // UpdateSig just emits a NodeSignalUpdated if the Updating flag is not
  1448  // set -- use this to trigger an update of a given node when there aren't
  1449  // any structural changes and you don't need to prevent any lower-level
  1450  // updates -- much more efficient than a pair of UpdateStart /
  1451  // UpdateEnd's.  Returns true if an update signal was sent.
  1452  func (n *Node) UpdateSig() bool {
  1453  	if n.IsUpdating() || n.IsDestroyed() {
  1454  		return false
  1455  	}
  1456  	n.NodeSignal().Emit(n.This(), int64(NodeSignalUpdated), n.Flags())
  1457  	return true
  1458  }
  1459  
  1460  // Disconnect disconnects this node, by calling DisconnectAll() on
  1461  // any Signal fields.  Any Node that adds a Signal must define an
  1462  // updated version of this method that calls its embedded parent's
  1463  // version and then calls DisconnectAll() on its Signal fields.
  1464  func (n *Node) Disconnect() {
  1465  	n.NodeSig.DisconnectAll()
  1466  }
  1467  
  1468  // DisconnectAll disconnects all the way from me down the tree.
  1469  func (n *Node) DisconnectAll() {
  1470  	n.FuncDownMeFirst(0, nil, func(k Ki, level int, d any) bool {
  1471  		k.Disconnect()
  1472  		return true
  1473  	})
  1474  }
  1475  
  1476  //////////////////////////////////////////////////////////////////////////
  1477  //  Field Value setting with notification
  1478  
  1479  // SetField sets given field name to given value, using very robust
  1480  // conversion routines to e.g., convert from strings to numbers, and
  1481  // vice-versa, automatically.  Returns error if not successfully set.
  1482  // wrapped in UpdateStart / End and sets the ValUpdated flag.
  1483  func (n *Node) SetField(field string, val any) error {
  1484  	fv := kit.FlatFieldValueByName(n.This(), field)
  1485  	if !fv.IsValid() {
  1486  		return fmt.Errorf("ki.SetField, could not find field %v on node %v", field, n.Nm)
  1487  	}
  1488  	updt := n.UpdateStart()
  1489  	var err error
  1490  	if field == "Nm" {
  1491  		n.SetName(kit.ToString(val))
  1492  		n.SetValUpdated()
  1493  	} else {
  1494  		if kit.SetRobust(kit.PtrValue(fv).Interface(), val) {
  1495  			n.SetValUpdated()
  1496  		} else {
  1497  			err = fmt.Errorf("ki.SetField, SetRobust failed to set field %v on node %v to value: %v", field, n.Nm, val)
  1498  		}
  1499  	}
  1500  	n.UpdateEnd(updt)
  1501  	return err
  1502  }
  1503  
  1504  //////////////////////////////////////////////////////////////////////////
  1505  //  Deep Copy / Clone
  1506  
  1507  // note: we use the copy from direction as the receiver is modified whereas the
  1508  // from is not and assignment is typically in same direction
  1509  
  1510  // CopyFrom another Ki node.  It is essential that source has Unique names!
  1511  // The Ki copy function recreates the entire tree in the copy, duplicating
  1512  // children etc, copying Props too.  It is very efficient by
  1513  // using the ConfigChildren method which attempts to preserve any existing
  1514  // nodes in the destination if they have the same name and type -- so a
  1515  // copy from a source to a target that only differ minimally will be
  1516  // minimally destructive.  Only copies to same types are supported.
  1517  // Signal connections are NOT copied.  No other Ki pointers are copied,
  1518  // and the field tag copy:"-" can be added for any other fields that
  1519  // should not be copied (unexported, lower-case fields are not copyable).
  1520  func (n *Node) CopyFrom(frm Ki) error {
  1521  	if frm == nil {
  1522  		err := fmt.Errorf("ki.Node CopyFrom into %v -- null 'from' source", n.Path())
  1523  		log.Println(err)
  1524  		return err
  1525  	}
  1526  	if Type(n.This()) != Type(frm.This()) {
  1527  		err := fmt.Errorf("ki.Node Copy to %v from %v -- must have same types, but %v != %v", n.Path(), frm.Path(), Type(n.This()).Name(), Type(frm.This()).Name())
  1528  		log.Println(err)
  1529  		return err
  1530  	}
  1531  	updt := n.UpdateStart()
  1532  	defer n.UpdateEnd(updt)
  1533  	err := CopyFromRaw(n.This(), frm)
  1534  	return err
  1535  }
  1536  
  1537  // Clone creates and returns a deep copy of the tree from this node down.
  1538  // Any pointers within the cloned tree will correctly point within the new
  1539  // cloned tree (see Copy info).
  1540  func (n *Node) Clone() Ki {
  1541  	nki := NewOfType(Type(n.This()))
  1542  	nki.InitName(nki, n.Nm)
  1543  	nki.CopyFrom(n.This())
  1544  	return nki
  1545  }
  1546  
  1547  // CopyFromRaw performs a raw copy that just does the deep copy of the
  1548  // bits and doesn't do anything with pointers.
  1549  func CopyFromRaw(kn, frm Ki) error {
  1550  	kn.Children().ConfigCopy(kn.This(), *frm.Children())
  1551  	n := kn.AsNode()
  1552  	fmp := *frm.Properties()
  1553  	n.Props = make(Props, len(fmp))
  1554  	n.Props.CopyFrom(fmp, DeepCopy)
  1555  
  1556  	kn.This().CopyFieldsFrom(frm)
  1557  	for i, kid := range *kn.Children() {
  1558  		fmk := frm.Child(i)
  1559  		CopyFromRaw(kid, fmk)
  1560  	}
  1561  	return nil
  1562  }
  1563  
  1564  // CopyFieldsFrom copies from primary fields of source object,
  1565  // recursively following anonymous embedded structs
  1566  func (n *Node) CopyFieldsFrom(frm any) {
  1567  	GenCopyFieldsFrom(n.This(), frm)
  1568  }
  1569  
  1570  // GenCopyFieldsFrom is a general-purpose copy of primary fields
  1571  // of source object, recursively following anonymous embedded structs
  1572  func GenCopyFieldsFrom(to any, frm any) {
  1573  	// pr := prof.Start("GenCopyFieldsFrom")
  1574  	// defer pr.End()
  1575  	kitype := KiType
  1576  	tv := kit.NonPtrValue(reflect.ValueOf(to))
  1577  	sv := kit.NonPtrValue(reflect.ValueOf(frm))
  1578  	typ := tv.Type()
  1579  	if kit.ShortTypeName(typ) == "ki.Node" {
  1580  		return // nothing to copy for base node!
  1581  	}
  1582  	for i := 0; i < typ.NumField(); i++ {
  1583  		f := typ.Field(i)
  1584  		tf := tv.Field(i)
  1585  		if !tf.CanInterface() {
  1586  			continue
  1587  		}
  1588  		ctag := f.Tag.Get("copy")
  1589  		if ctag == "-" {
  1590  			continue
  1591  		}
  1592  		sf := sv.Field(i)
  1593  		tfpi := kit.PtrValue(tf).Interface()
  1594  		sfpi := kit.PtrValue(sf).Interface()
  1595  		if f.Type.Kind() == reflect.Struct && f.Anonymous {
  1596  			// the generic version cannot ever go back to the node-specific
  1597  			// because the n.This() is ALWAYS the final type, not the intermediate
  1598  			// embedded ones
  1599  			GenCopyFieldsFrom(tfpi, sfpi)
  1600  		} else {
  1601  			switch {
  1602  			case sf.Kind() == reflect.Struct && kit.EmbedImplements(sf.Type(), kitype):
  1603  				sfk := sfpi.(Ki)
  1604  				tfk := tfpi.(Ki)
  1605  				if tfk != nil && sfk != nil {
  1606  					tfk.CopyFrom(sfk)
  1607  				}
  1608  			case f.Type == KiT_Signal: // note: don't copy signals by default
  1609  			case sf.Type().AssignableTo(tf.Type()):
  1610  				tf.Set(sf)
  1611  				// kit.PtrValue(tf).Set(sf)
  1612  			default:
  1613  				// use copier https://github.com/jinzhu/copier which handles as much as possible..
  1614  				// pr := prof.Start("Copier")
  1615  				copier.Copy(tfpi, sfpi)
  1616  				// pr.End()
  1617  			}
  1618  		}
  1619  
  1620  	}
  1621  }
  1622  
  1623  // OnInit is a placeholder implementation of
  1624  // [Ki.OnInit] that does nothing.
  1625  func (n *Node) OnInit() {}
  1626  
  1627  // OnAdd is a placeholder implementation of
  1628  // [Ki.OnAdd] that does nothing.
  1629  func (n *Node) OnAdd() {}
  1630  
  1631  // OnChildAdded is a placeholder implementation of
  1632  // [Ki.OnChildAdded] that does nothing.
  1633  func (n *Node) OnChildAdded(child Ki) {}