github.com/goki/ki@v1.1.11/ki/ki.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  	"io"
     9  	"log"
    10  	"reflect"
    11  
    12  	"github.com/goki/ki/kit"
    13  )
    14  
    15  // The Ki interface provides the core functionality for a GoKi tree.
    16  // Each Ki is a node in the tree and can have child nodes, and no cycles
    17  // are allowed (i.e., each node can only appear once in the tree).
    18  // All the usual methods are included for accessing and managing Children,
    19  // and efficiently traversing the tree and calling functions on the nodes.
    20  // In addition, Ki nodes can have Fields that are also Ki nodes that
    21  // are included in all the automatic tree traversal methods -- they are
    22  // effectively named fixed children that are automatically present.
    23  //
    24  // In general, the names of the children of a given node should all be unique.
    25  // The following functions defined in ki package can be used:
    26  // UniqueNameCheck(node) to check for unique names on node if uncertain.
    27  // UniqueNameCheckAll(node) to check entire tree under given node.
    28  // UniquifyNames(node) to add a suffix to name to ensure uniqueness.
    29  // UniquifyNamesAll(node) to to uniquify all names in entire tree.
    30  //
    31  // Use function MoveChild to move a node between trees or within a tree --
    32  // otherwise nodes are typically created and deleted but not moved.
    33  //
    34  // The Ki interface is designed to support virtual method calling in Go
    35  // and is only intended to be implemented once, by the ki.Node type
    36  // (as opposed to interfaces that are used for hiding multiple different
    37  // implementations of a common concept).  Thus, all of the fields in ki.Node
    38  // are exported (have captital names), to be accessed directly in types
    39  // that embed and extend the ki.Node. The Ki interface has the "formal" name
    40  // (e.g., Children) while the Node has the "nickname" (e.g., Kids).  See the
    41  // Naming Conventions on the GoKi Wiki for more details.
    42  //
    43  // Each Node stores the Ki interface version of itself, as This() / Ths
    44  // which enables full virtual function calling by calling the method
    45  // on that interface instead of directly on the receiver Node itself.
    46  // This requires proper initialization via Init method of the Ki interface.
    47  //
    48  // Ki nodes also support the following core functionality:
    49  // * UpdateStart() / UpdateEnd() to wrap around tree updating code, which then
    50  //   automatically triggers update signals at the highest level of the
    51  //   affected tree, resulting in efficient updating logic for arbitrary
    52  //   nested tree modifications.
    53  // * Signal framework for sending messages such as the Update signals, used
    54  //   extensively in the GoGi GUI framework for sending event messages etc.
    55  // * ConfigChildren system for minimally updating children to fit a given
    56  //   Name & Type template.
    57  // * Automatic JSON I/O of entire tree including type information.
    58  //
    59  type Ki interface {
    60  	// InitName initializes this node to given actual object as a Ki interface
    61  	// and sets its name.  The names should be unique among children of a node.
    62  	// This is needed for root nodes -- automatically done for other nodes
    63  	// when they are added to the Ki tree.
    64  	// Even though this is a method and gets the method receiver, it needs
    65  	// an "external" version of itself passed as the first arg, from which
    66  	// the proper Ki interface pointer will be obtained.  This is the only
    67  	// way to get virtual functional calling to work within the Go framework.
    68  	InitName(this Ki, name string)
    69  
    70  	// This returns the Ki interface that guarantees access to the Ki
    71  	// interface in a way that always reveals the underlying type
    72  	// (e.g., in reflect calls).  Returns nil if node is nil,
    73  	// has been destroyed, or is improperly constructed.
    74  	This() Ki
    75  
    76  	// AsNode returns the *ki.Node base type for this node.
    77  	AsNode() *Node
    78  
    79  	// Embed returns the embedded struct of given type from this node (or nil
    80  	// if it does not embed that type, or the type is not a Ki type -- see
    81  	// kit.Embed for a generic interface{} version.
    82  	Embed(t reflect.Type) Ki
    83  
    84  	// BaseIface returns the base interface type for all elements
    85  	// within this tree.  Use reflect.TypeOf((*<interface_type>)(nil)).Elem().
    86  	// Used e.g., for determining what types of children
    87  	// can be created (see kit.EmbedImplements for test method)
    88  	BaseIface() reflect.Type
    89  
    90  	// Name returns the user-defined name of the object (Node.Nm),
    91  	// for finding elements, generating paths, IO, etc.
    92  	Name() string
    93  
    94  	// SetName sets the name of this node.
    95  	// Names should generally be unique across children of each node.
    96  	// See Unique* functions to check / fix.
    97  	// If node requires non-unique names, add a separate Label field.
    98  	// Does NOT wrap in UpdateStart / End.
    99  	SetName(name string)
   100  
   101  	//////////////////////////////////////////////////////////////////////////
   102  	//  Parents
   103  
   104  	// Parent returns the parent of this Ki (Node.Par) -- Ki has strict
   105  	// one-parent, no-cycles structure -- see SetParent.
   106  	Parent() Ki
   107  
   108  	// IndexInParent returns our index within our parent object -- caches the
   109  	// last value and uses that for an optimized search so subsequent calls
   110  	// are typically quite fast.  Returns false if we don't have a parent.
   111  	IndexInParent() (int, bool)
   112  
   113  	// ParentLevel finds a given potential parent node recursively up the
   114  	// hierarchy, returning level above current node that the parent was
   115  	// found, and -1 if not found.
   116  	ParentLevel(par Ki) int
   117  
   118  	// ParentByName finds first parent recursively up hierarchy that matches
   119  	// given name.  Returns nil if not found.
   120  	ParentByName(name string) Ki
   121  
   122  	// ParentByNameTry finds first parent recursively up hierarchy that matches
   123  	// given name -- Try version returns error on failure.
   124  	ParentByNameTry(name string) (Ki, error)
   125  
   126  	// ParentByType finds parent recursively up hierarchy, by type, and
   127  	// returns nil if not found. If embeds is true, then it looks for any
   128  	// type that embeds the given type at any level of anonymous embedding.
   129  	ParentByType(t reflect.Type, embeds bool) Ki
   130  
   131  	// ParentByTypeTry finds parent recursively up hierarchy, by type, and
   132  	// returns error if not found. If embeds is true, then it looks for any
   133  	// type that embeds the given type at any level of anonymous embedding.
   134  	ParentByTypeTry(t reflect.Type, embeds bool) (Ki, error)
   135  
   136  	//////////////////////////////////////////////////////////////////////////
   137  	//  Children
   138  
   139  	// HasChildren tests whether this node has children (i.e., non-terminal).
   140  	HasChildren() bool
   141  
   142  	// NumChildren returns the number of children
   143  	NumChildren() int
   144  
   145  	// Children returns a pointer to the slice of children (Node.Kids) -- use
   146  	// methods on ki.Slice for further ways to access (ByName, ByType, etc).
   147  	// Slice can be modified, deleted directly (e.g., sort, reorder) but Add
   148  	// method on parent node should be used to ensure proper init.
   149  	Children() *Slice
   150  
   151  	// Child returns the child at given index -- will panic if index is invalid.
   152  	// See methods on ki.Slice for more ways to access.
   153  	Child(idx int) Ki
   154  
   155  	// ChildTry returns the child at given index -- Try version returns
   156  	// error if index is invalid.
   157  	// See methods on ki.Slice for more ways to access.
   158  	ChildTry(idx int) (Ki, error)
   159  
   160  	// ChildByName returns first element that has given name, nil if not found.
   161  	// startIdx arg allows for optimized bidirectional find if you have
   162  	// an idea where it might be -- can be key speedup for large lists -- pass
   163  	// -1 to start in the middle (good default).
   164  	ChildByName(name string, startIdx int) Ki
   165  
   166  	// ChildByNameTry returns first element that has given name -- Try version
   167  	// returns error message if not found.
   168  	// startIdx arg allows for optimized bidirectional find if you have
   169  	// an idea where it might be -- can be key speedup for large lists -- pass
   170  	// -1 to start in the middle (good default).
   171  	ChildByNameTry(name string, startIdx int) (Ki, error)
   172  
   173  	// ChildByType returns first element that has given type, nil if not found.
   174  	// If embeds is true, then it looks for any type that embeds the given type
   175  	// at any level of anonymous embedding.
   176  	// startIdx arg allows for optimized bidirectional find if you have
   177  	// an idea where it might be -- can be key speedup for large lists -- pass
   178  	// -1 to start in the middle (good default).
   179  	ChildByType(t reflect.Type, embeds bool, startIdx int) Ki
   180  
   181  	// ChildByTypeTry returns first element that has given name -- Try version
   182  	// returns error message if not found.
   183  	// If embeds is true, then it looks for any type that embeds the given type
   184  	// at any level of anonymous embedding.
   185  	// startIdx arg allows for optimized bidirectional find if you have
   186  	// an idea where it might be -- can be key speedup for large lists -- pass
   187  	// -1 to start in the middle (good default).
   188  	ChildByTypeTry(t reflect.Type, embeds bool, startIdx int) (Ki, error)
   189  
   190  	//////////////////////////////////////////////////////////////////////////
   191  	//  Paths
   192  
   193  	// Path returns path to this node from the tree root, using node Names
   194  	// separated by / and fields by .
   195  	// Node names escape any existing / and . characters to \\ and \,
   196  	// Path is only valid when child names are unique (see Unique* functions)
   197  	Path() string
   198  
   199  	// PathFrom returns path to this node from given parent node, using
   200  	// node Names separated by / and fields by .
   201  	// Node names escape any existing / and . characters to \\ and \,
   202  	// Path is only valid when child names are unique (see Unique* functions)
   203  	PathFrom(par Ki) string
   204  
   205  	// FindPath returns Ki object at given path, starting from this node
   206  	// (e.g., the root).  If this node is not the root, then the path
   207  	// to this node is subtracted from the start of the path if present there.
   208  	// FindPath only works correctly when names are unique.
   209  	// Path has node Names separated by / and fields by .
   210  	// Node names escape any existing / and . characters to \\ and \,
   211  	// There is also support for [idx] index-based access for any given path
   212  	// element, for cases when indexes are more useful than names.
   213  	// Returns nil if not found.
   214  	FindPath(path string) Ki
   215  
   216  	// FindPathTry returns Ki object at given path, starting from this node
   217  	// (e.g., the root).  If this node is not the root, then the path
   218  	// to this node is subtracted from the start of the path if present there.
   219  	// FindPath only works correctly when names are unique.
   220  	// Path has node Names separated by / and fields by .
   221  	// Node names escape any existing / and . characters to \\ and \,
   222  	// There is also support for [idx] index-based access for any given path
   223  	// element, for cases when indexes are more useful than names.
   224  	// Returns error if not found.
   225  	FindPathTry(path string) (Ki, error)
   226  
   227  	//////////////////////////////////////////////////////////////////////////
   228  	//  Adding, Inserting Children
   229  
   230  	// AddChild adds given child at end of children list.
   231  	// The kid node is assumed to not be on another tree (see MoveToParent)
   232  	// and the existing name should be unique among children.
   233  	// No UpdateStart / End wrapping is done: do that externally as needed.
   234  	// Can also call SetFlag(ki.ChildAdded) if notification is needed.
   235  	AddChild(kid Ki) error
   236  
   237  	// AddNewChild creates a new child of given type and
   238  	// add at end of children list.
   239  	// The name should be unique among children.
   240  	// No UpdateStart / End wrapping is done: do that externally as needed.
   241  	// Can also call SetFlag(ki.ChildAdded) if notification is needed.
   242  	AddNewChild(typ reflect.Type, name string) Ki
   243  
   244  	// SetChild sets child at given index to be the given item -- if name is
   245  	// non-empty then it sets the name of the child as well -- just calls Init
   246  	// (or InitName) on the child, and SetParent.
   247  	// Names should be unique among children.
   248  	// No UpdateStart / End wrapping is done: do that externally as needed.
   249  	// Can also call SetFlag(ki.ChildAdded) if notification is needed.
   250  	SetChild(kid Ki, idx int, name string) error
   251  
   252  	// InsertChild adds given child at position in children list.
   253  	// The kid node is assumed to not be on another tree (see MoveToParent)
   254  	// and the existing name should be unique among children.
   255  	// No UpdateStart / End wrapping is done: do that externally as needed.
   256  	// Can also call SetFlag(ki.ChildAdded) if notification is needed.
   257  	InsertChild(kid Ki, at int) error
   258  
   259  	// InsertNewChild creates a new child of given type and
   260  	// add at position in children list.
   261  	// The name should be unique among children.
   262  	// No UpdateStart / End wrapping is done: do that externally as needed.
   263  	// Can also call SetFlag(ki.ChildAdded) if notification is needed.
   264  	InsertNewChild(typ reflect.Type, at int, name string) Ki
   265  
   266  	// SetNChildren ensures that there are exactly n children, deleting any
   267  	// extra, and creating any new ones, using AddNewChild with given type and
   268  	// naming according to nameStubX where X is the index of the child.
   269  	//
   270  	// IMPORTANT: returns whether any modifications were made (mods) AND if
   271  	// that is true, the result from the corresponding UpdateStart call --
   272  	// UpdateEnd is NOT called, allowing for further subsequent updates before
   273  	// you call UpdateEnd(updt)
   274  	//
   275  	// Note that this does not ensure existing children are of given type, or
   276  	// change their names, or call UniquifyNames -- use ConfigChildren for
   277  	// those cases -- this function is for simpler cases where a parent uses
   278  	// this function consistently to manage children all of the same type.
   279  	SetNChildren(n int, typ reflect.Type, nameStub string) (mods, updt bool)
   280  
   281  	// ConfigChildren configures children according to given list of
   282  	// type-and-name's -- attempts to have minimal impact relative to existing
   283  	// items that fit the type and name constraints (they are moved into the
   284  	// corresponding positions), and any extra children are removed, and new
   285  	// ones added, to match the specified config.
   286  	// It is important that names are unique!
   287  	//
   288  	// IMPORTANT: returns whether any modifications were made (mods) AND if
   289  	// that is true, the result from the corresponding UpdateStart call --
   290  	// UpdateEnd is NOT called, allowing for further subsequent updates before
   291  	// you call UpdateEnd(updt).
   292  	ConfigChildren(config kit.TypeAndNameList) (mods, updt bool)
   293  
   294  	//////////////////////////////////////////////////////////////////////////
   295  	//  Deleting Children
   296  
   297  	// DeleteChildAtIndex deletes child at given index (returns error for
   298  	// invalid index).
   299  	// Wraps delete in UpdateStart / End and sets ChildDeleted flag.
   300  	DeleteChildAtIndex(idx int, destroy bool) error
   301  
   302  	// DeleteChild deletes child node, returning error if not found in
   303  	// Children.
   304  	// Wraps delete in UpdateStart / End and sets ChildDeleted flag.
   305  	DeleteChild(child Ki, destroy bool) error
   306  
   307  	// DeleteChildByName deletes child node by name -- returns child, error
   308  	// if not found.
   309  	// Wraps delete in UpdateStart / End and sets ChildDeleted flag.
   310  	DeleteChildByName(name string, destroy bool) (Ki, error)
   311  
   312  	// DeleteChildren deletes all children nodes -- destroy will add removed
   313  	// children to deleted list, to be destroyed later -- otherwise children
   314  	// remain intact but parent is nil -- could be inserted elsewhere, but you
   315  	// better have kept a slice of them before calling this.
   316  	DeleteChildren(destroy bool)
   317  
   318  	// Delete deletes this node from its parent children list -- destroy will
   319  	// add removed child to deleted list, to be destroyed later -- otherwise
   320  	// child remains intact but parent is nil -- could be inserted elsewhere.
   321  	Delete(destroy bool)
   322  
   323  	// Destroy calls DisconnectAll to cut all signal connections,
   324  	// and remove all children and their childrens-children, etc.
   325  	Destroy()
   326  
   327  	//////////////////////////////////////////////////////////////////////////
   328  	//  Flags
   329  
   330  	// Flag returns an atomically safe copy of the bit flags for this node --
   331  	// can use bitflag package to check lags.
   332  	// See Flags type for standard values used in Ki Node --
   333  	// can be extended from FlagsN up to 64 bit capacity.
   334  	// Note that we must always use atomic access as *some* things need to be atomic,
   335  	// and with bits, that means that *all* access needs to be atomic,
   336  	// as you cannot atomically update just a single bit.
   337  	Flags() int64
   338  
   339  	// HasFlag checks if flag is set
   340  	// using atomic, safe for concurrent access
   341  	HasFlag(flag int) bool
   342  
   343  	// SetFlag sets the given flag(s)
   344  	// using atomic, safe for concurrent access
   345  	SetFlag(flag ...int)
   346  
   347  	// SetFlagState sets the given flag(s) to given state
   348  	// using atomic, safe for concurrent access
   349  	SetFlagState(on bool, flag ...int)
   350  
   351  	// SetFlagMask sets the given flags as a mask
   352  	// using atomic, safe for concurrent access
   353  	SetFlagMask(mask int64)
   354  
   355  	// ClearFlag clears the given flag(s)
   356  	// using atomic, safe for concurrent access
   357  	ClearFlag(flag ...int)
   358  
   359  	// ClearFlagMask clears the given flags as a bitmask
   360  	// using atomic, safe for concurrent access
   361  	ClearFlagMask(mask int64)
   362  
   363  	// IsField checks if this is a field on a parent struct (via IsField
   364  	// Flag), as opposed to a child in Children -- Ki nodes can be added as
   365  	// fields to structs and they are automatically parented and named with
   366  	// field name during Init function -- essentially they function as fixed
   367  	// children of the parent struct, and are automatically included in
   368  	// FuncDown* traversals, etc -- see also FunFields.
   369  	IsField() bool
   370  
   371  	// IsUpdating checks if node is currently updating.
   372  	IsUpdating() bool
   373  
   374  	// OnlySelfUpdate checks if this node only applies UpdateStart / End logic
   375  	// to itself, not its children (which is the default) (via Flag of same
   376  	// name) -- useful for a parent node that has a different function than
   377  	// its children.
   378  	OnlySelfUpdate() bool
   379  
   380  	// SetChildAdded sets the ChildAdded flag -- set when notification is needed
   381  	// for Add, Insert methods
   382  	SetChildAdded()
   383  
   384  	// SetValUpdated sets the ValUpdated flag -- set when notification is needed
   385  	// for modifying a value (field, prop, etc)
   386  	SetValUpdated()
   387  
   388  	// IsDeleted checks if this node has just been deleted (within last update
   389  	// cycle), indicated by the NodeDeleted flag which is set when the node is
   390  	// deleted, and is cleared at next UpdateStart call.
   391  	IsDeleted() bool
   392  
   393  	// IsDestroyed checks if this node has been destroyed -- the NodeDestroyed
   394  	// flag is set at start of Destroy function -- the Signal Emit process
   395  	// checks for destroyed receiver nodes and removes connections to them
   396  	// automatically -- other places where pointers to potentially destroyed
   397  	// nodes may linger should also check this flag and reset those pointers.
   398  	IsDestroyed() bool
   399  
   400  	//////////////////////////////////////////////////////////////////////////
   401  	//  Property interface with inheritance -- nodes can inherit props from parents
   402  
   403  	// Properties (Node.Props) tell the GoGi GUI or other frameworks operating
   404  	// on Trees about special features of each node -- functions below support
   405  	// inheritance up Tree -- see kit convert.go for robust convenience
   406  	// methods for converting interface{} values to standard types.
   407  	Properties() *Props
   408  
   409  	// SetProp sets given property key to value val -- initializes property
   410  	// map if nil.
   411  	SetProp(key string, val interface{})
   412  
   413  	// Prop returns property value for key that is known to exist.
   414  	// Returns nil if it actually doesn't -- this version allows
   415  	// direct conversion of return.  See PropTry for version with
   416  	// error message if uncertain if property exists.
   417  	Prop(key string) interface{}
   418  
   419  	// PropTry returns property value for key.  Returns error message
   420  	// if property with that key does not exist.
   421  	PropTry(key string) (interface{}, error)
   422  
   423  	// PropInherit gets property value from key with options for inheriting
   424  	// property from parents and / or type-level properties.  If inherit, then
   425  	// checks all parents.  If typ then checks property on type as well
   426  	// (registered via KiT type registry).  Returns false if not set anywhere.
   427  	PropInherit(key string, inherit, typ bool) (interface{}, bool)
   428  
   429  	// DeleteProp deletes property key on this node.
   430  	DeleteProp(key string)
   431  
   432  	// PropTag returns the name to look for in type properties, for types
   433  	// that are valid options for values that can be set in Props.  For example
   434  	// in GoGi, it is "style-props" which is then set for all types that can
   435  	// be used in a style (colors, enum options, etc)
   436  	PropTag() string
   437  
   438  	//////////////////////////////////////////////////////////////////////////
   439  	//  Tree walking and Paths
   440  	//   note: always put function args last -- looks better for inline functions
   441  
   442  	// FuncFields calls function on all Ki fields within this node.
   443  	FuncFields(level int, data interface{}, fun Func)
   444  
   445  	// FuncUp calls function on given node and all the way up to its parents,
   446  	// and so on -- sequentially all in current go routine (generally
   447  	// necessary for going up, which is typically quite fast anyway) -- level
   448  	// is incremented after each step (starts at 0, goes up), and passed to
   449  	// function -- returns false if fun aborts with false, else true.
   450  	FuncUp(level int, data interface{}, fun Func) bool
   451  
   452  	// FuncUpParent calls function on parent of node and all the way up to its
   453  	// parents, and so on -- sequentially all in current go routine (generally
   454  	// necessary for going up, which is typically quite fast anyway) -- level
   455  	// is incremented after each step (starts at 0, goes up), and passed to
   456  	// function -- returns false if fun aborts with false, else true.
   457  	FuncUpParent(level int, data interface{}, fun Func) bool
   458  
   459  	// FuncDownMeFirst calls function on this node (MeFirst) and then iterates
   460  	// in a depth-first manner over all the children, including Ki Node fields,
   461  	// which are processed first before children.
   462  	// This uses node state information to manage the traversal and is very fast,
   463  	// but can only be called by one thread at a time -- use a Mutex if there is
   464  	// a chance of multiple threads running at the same time.
   465  	// Function calls are sequential all in current go routine.
   466  	// The level var tracks overall depth in the tree.
   467  	// If fun returns false then any further traversal of that branch of the tree is
   468  	// aborted, but other branches continue -- i.e., if fun on current node
   469  	// returns false, children are not processed further.
   470  	FuncDownMeFirst(level int, data interface{}, fun Func)
   471  
   472  	// FuncDownMeLast iterates in a depth-first manner over the children, calling
   473  	// doChildTestFunc on each node to test if processing should proceed (if it returns
   474  	// false then that branch of the tree is not further processed), and then
   475  	// calls given fun function after all of a node's children (including fields)
   476  	// have been iterated over ("Me Last").
   477  	// This uses node state information to manage the traversal and is very fast,
   478  	// but can only be called by one thread at a time -- use a Mutex if there is
   479  	// a chance of multiple threads running at the same time.
   480  	// Function calls are sequential all in current go routine.
   481  	// The level var tracks overall depth in the tree.
   482  	FuncDownMeLast(level int, data interface{}, doChildTestFunc Func, fun Func)
   483  
   484  	// FuncDownBreadthFirst calls function on all children in breadth-first order
   485  	// using the standard queue strategy.  This depends on and updates the
   486  	// Depth parameter of the node.  If fun returns false then any further
   487  	// traversal of that branch of the tree is aborted, but other branches continue.
   488  	FuncDownBreadthFirst(level int, data interface{}, fun Func)
   489  
   490  	//////////////////////////////////////////////////////////////////////////
   491  	//  State update signaling -- automatically consolidates all changes across
   492  	//   levels so there is only one update at end (optionally per node or only
   493  	//   at highest level)
   494  	//   All modification starts with UpdateStart() and ends with UpdateEnd()
   495  
   496  	// NodeSignal returns the main signal for this node that is used for
   497  	// update, child signals.
   498  	NodeSignal() *Signal
   499  
   500  	// UpdateStart should be called when starting to modify the tree (state or
   501  	// structure) -- returns whether this node was first to set the Updating
   502  	// flag (if so, all children have their Updating flag set -- pass the
   503  	// result to UpdateEnd -- automatically determines the highest level
   504  	// updated, within the normal top-down updating sequence -- can be called
   505  	// multiple times at multiple levels -- it is essential to ensure that all
   506  	// such Start's have an End!  Usage:
   507  	//
   508  	//   updt := n.UpdateStart()
   509  	//   ... code
   510  	//   n.UpdateEnd(updt)
   511  	// or
   512  	//   updt := n.UpdateStart()
   513  	//   defer n.UpdateEnd(updt)
   514  	//   ... code
   515  	UpdateStart() bool
   516  
   517  	// UpdateEnd should be called when done updating after an UpdateStart, and
   518  	// passed the result of the UpdateStart call -- if this is true, the
   519  	// NodeSignalUpdated signal will be emitted and the Updating flag will be
   520  	// cleared, and DestroyDeleted called -- otherwise it is a no-op.
   521  	UpdateEnd(updt bool)
   522  
   523  	// UpdateEndNoSig is just like UpdateEnd except it does not emit a
   524  	// NodeSignalUpdated signal -- use this for situations where updating is
   525  	// already known to be in progress and the signal would be redundant.
   526  	UpdateEndNoSig(updt bool)
   527  
   528  	// UpdateSig just emits a NodeSignalUpdated if the Updating flag is not
   529  	// set -- use this to trigger an update of a given node when there aren't
   530  	// any structural changes and you don't need to prevent any lower-level
   531  	// updates -- much more efficient than a pair of UpdateStart /
   532  	// UpdateEnd's.  Returns true if an update signal was sent.
   533  	UpdateSig() bool
   534  
   535  	// Disconnect disconnects this node, by calling DisconnectAll() on
   536  	// any Signal fields.  Any Node that adds a Signal must define an
   537  	// updated version of this method that calls its embedded parent's
   538  	// version and then calls DisconnectAll() on its Signal fields.
   539  	Disconnect()
   540  
   541  	// DisconnectAll disconnects all the way from me down the tree.
   542  	DisconnectAll()
   543  
   544  	//////////////////////////////////////////////////////////////////////////
   545  	//  Field Value setting with notification
   546  
   547  	// SetField sets given field name to given value, using very robust
   548  	// conversion routines to e.g., convert from strings to numbers, and
   549  	// vice-versa, automatically.  Returns error if not successfully set.
   550  	// wrapped in UpdateStart / End and sets the ValUpdated flag.
   551  	SetField(field string, val interface{}) error
   552  
   553  	//////////////////////////////////////////////////////////////////////////
   554  	//  Deep Copy of Trees
   555  
   556  	// CopyFrom another Ki node.  It is essential that source has Unique names!
   557  	// The Ki copy function recreates the entire tree in the copy, duplicating
   558  	// children etc, copying Props too.  It is very efficient by
   559  	// using the ConfigChildren method which attempts to preserve any existing
   560  	// nodes in the destination if they have the same name and type -- so a
   561  	// copy from a source to a target that only differ minimally will be
   562  	// minimally destructive.  Only copies to same types are supported.
   563  	// Signal connections are NOT copied.  No other Ki pointers are copied,
   564  	// and the field tag copy:"-" can be added for any other fields that
   565  	// should not be copied (unexported, lower-case fields are not copyable).
   566  	CopyFrom(frm Ki) error
   567  
   568  	// Clone creates and returns a deep copy of the tree from this node down.
   569  	// Any pointers within the cloned tree will correctly point within the new
   570  	// cloned tree (see Copy info).
   571  	Clone() Ki
   572  
   573  	// CopyFieldsFrom is the base-level copy method that any copy-intensive
   574  	// nodes should implement directly to explicitly copy relevant fields
   575  	// that should be copied, avoiding any internal pointers etc.
   576  	// This is the performance bottleneck in copying -- the Node version
   577  	// uses generic GenCopyFieldsFrom method using reflection etc
   578  	// which is very slow.  It can be ~10x faster overall to use custom
   579  	// method that explicitly copies each field.  When doing so, you
   580  	// must explicitly call the CopyFieldsFrom method on any embedded
   581  	// Ki types that you inherit from, and, critically, NONE of those
   582  	// can rely on the generic Node-level version.  Furthermore, if the
   583  	// actual end type itself does not define a custom version of this method
   584  	// then the generic one will be called for everything.
   585  	CopyFieldsFrom(frm interface{})
   586  
   587  	//////////////////////////////////////////////////////////////////////////
   588  	//  IO: for JSON and XML formats -- see also Slice
   589  	//  see https://github.com/goki/ki/wiki/Naming for IO naming conventions
   590  
   591  	// WriteJSON writes the tree to an io.Writer, using MarshalJSON -- also
   592  	// saves a critical starting record that allows file to be loaded de-novo
   593  	// and recreate the proper root type for the tree.
   594  	WriteJSON(writer io.Writer, indent bool) error
   595  
   596  	// SaveJSON saves the tree to a JSON-encoded file, using WriteJSON.
   597  	SaveJSON(filename string) error
   598  
   599  	// ReadJSON reads and unmarshals tree starting at this node, from a
   600  	// JSON-encoded byte stream via io.Reader.  First element in the stream
   601  	// must be of same type as this node -- see ReadNewJSON function to
   602  	// construct a new tree.  Uses ConfigureChildren to minimize changes from
   603  	// current tree relative to loading one -- wraps UnmarshalJSON and calls
   604  	// UnmarshalPost to recover pointers from paths.
   605  	ReadJSON(reader io.Reader) error
   606  
   607  	// OpenJSON opens file over this tree from a JSON-encoded file -- see
   608  	// ReadJSON for details, and OpenNewJSON for opening an entirely new tree.
   609  	OpenJSON(filename string) error
   610  
   611  	// WriteXML writes the tree to an XML-encoded byte string over io.Writer
   612  	// using MarshalXML.
   613  	WriteXML(writer io.Writer, indent bool) error
   614  
   615  	// ReadXML reads the tree from an XML-encoded byte string over io.Reader, calls
   616  	// UnmarshalPost to recover pointers from paths.
   617  	ReadXML(reader io.Reader) error
   618  }
   619  
   620  // see node.go for struct implementing this interface
   621  
   622  // IMPORTANT: all types should initialize entry in package kit Types Registry
   623  
   624  // var KiT_TypeName = kit.Types.AddType(&TypeName{})
   625  
   626  // Func is a function to call on ki objects walking the tree -- return Break
   627  // = false means don't continue processing this branch of the tree, but other
   628  // branches can continue.  return Continue = true continues down the tree.
   629  type Func func(k Ki, level int, data interface{}) bool
   630  
   631  // KiType is a Ki reflect.Type, suitable for checking for Type.Implements.
   632  var KiType = reflect.TypeOf((*Ki)(nil)).Elem()
   633  
   634  // IsKi returns true if the given type implements the Ki interface at any
   635  // level of embedded structure.
   636  func IsKi(typ reflect.Type) bool {
   637  	if typ == nil {
   638  		return false
   639  	}
   640  	return kit.EmbedImplements(typ, KiType)
   641  }
   642  
   643  // NewOfType makes a new Ki struct of given type -- must be a Ki type -- will
   644  // return nil if not.
   645  func NewOfType(typ reflect.Type) Ki {
   646  	nkid := reflect.New(typ).Interface()
   647  	kid, ok := nkid.(Ki)
   648  	if !ok {
   649  		log.Printf("ki.NewOfType: type %v cannot be converted into a Ki interface type\n", typ.String())
   650  		return nil
   651  	}
   652  	return kid
   653  }
   654  
   655  // Type returns the underlying struct type of given node
   656  func Type(k Ki) reflect.Type {
   657  	return reflect.TypeOf(k.This()).Elem()
   658  }
   659  
   660  // TypeEmbeds tests whether this node is of the given type, or it embeds
   661  // that type at any level of anonymous embedding -- use Embed to get the
   662  // embedded struct of that type from this node.
   663  func TypeEmbeds(k Ki, t reflect.Type) bool {
   664  	return kit.TypeEmbeds(Type(k), t)
   665  }