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