Documentation ¶
Overview ¶
Package Ki provides the base element of GoKi Trees: Ki = Tree in Japanese, and "Key" in English -- powerful tree structures supporting scenegraphs, programs, parsing, etc.
The Node struct that implements the Ki interface, which can be used as an embedded type (or a struct field) in other structs to provide core tree functionality, including:
Parent / Child Tree structure -- each Node can ONLY have one parent. Node struct's can also have Node fields -- these are functionally like fixed auto-named children.
Paths for locating Nodes within the hierarchy -- key for many use-cases, including ability to convert pointers to/from strings for IO and robust deep copy and move functions. The path separator is / for children and . for fields.
Apply a function across nodes up or down a tree (natural "me first", breadth-first, depth-first) -- very flexible for tree walking.
Generalized I/O -- can Save and Load the Tree as JSON, XML, etc -- including pointers which are saved using paths and automatically cached-out after loading -- enums also bidirectionally convertable to strings using enum type registry in kit package.
Robust deep copy, clone, move of nodes, with automatic pointer updating.
Signal sending and receiving between Nodes (simlar to Qt Signals / Slots) -- setup connections once and then emit signals to all receivers when relevant event happens.
Robust state updating -- wrap updates in UpdateStart / End, and signals are blocked until the final end, at the highest affected level in the tree, at which point a single update signal is sent -- automatically gives the minimal update.
Properties (as a string-keyed map) with property inheritance, including type-level properties via kit type registry.
Garbage collection is performed at optimized point at end of updates after tree objects have been destroyed (and all pointers reset), minimizing impact and need for unplanned GC interruptions.
Index ¶
- Variables
- func DecodeXMLCharData(d *xml.Decoder) (val string, err error)
- func DecodeXMLCharEl(d *xml.Decoder) (name, val string, err error)
- func DecodeXMLEndEl(d *xml.Decoder, start xml.StartElement) error
- func DecodeXMLStartEl(d *xml.Decoder) (start xml.StartElement, err error)
- func FlatFieldsValueFunc(stru interface{}, ...) bool
- func IsKi(typ reflect.Type) bool
- func KiType() reflect.Type
- type Connection
- type Deleted
- type Flags
- type Func
- type Ki
- type Node
- func (n *Node) AddChild(kid Ki) error
- func (n *Node) AddChildCheck(kid Ki) error
- func (n *Node) AddChildImpl(kid Ki) error
- func (n *Node) AddNewChild(typ reflect.Type, name string) Ki
- func (n *Node) Child(idx int) Ki
- func (n *Node) ChildByName(name string, startIdx int) Ki
- func (n *Node) ChildByType(t reflect.Type, embeds bool, startIdx int) Ki
- func (n *Node) ChildIndex(kid Ki, startIdx int) int
- func (n *Node) ChildIndexByFunc(startIdx int, match func(ki Ki) bool) int
- func (n *Node) ChildIndexByName(name string, startIdx int) int
- func (n *Node) ChildIndexByType(t reflect.Type, embeds bool, startIdx int) int
- func (n *Node) ChildIndexByUniqueName(name string, startIdx int) int
- func (n *Node) Children() Slice
- func (n *Node) ClearFlagMu(flag ...int)
- func (n *Node) Clone() Ki
- func (n *Node) ConfigChildren(config kit.TypeAndNameList, uniqNm bool) (mods, updt bool)
- func (n *Node) CopyFieldsFrom(to interface{}, from interface{})
- func (n *Node) CopyFrom(from Ki) error
- func (n *Node) CopyFromRaw(from Ki) error
- func (n *Node) CopyMakeChildrenFrom(from Ki)
- func (n *Node) CopyPropsFrom(from Ki, deep bool) error
- func (n *Node) Delete(destroy bool)
- func (n *Node) DeleteAllProps(cap int)
- func (n *Node) DeleteChild(child Ki, destroy bool)
- func (n *Node) DeleteChildAtIndex(idx int, destroy bool)
- func (n *Node) DeleteChildByName(name string, destroy bool) Ki
- func (n *Node) DeleteChildren(destroy bool)
- func (n *Node) DeleteProp(key string)
- func (n *Node) Destroy()
- func (n *Node) Disconnect()
- func (n *Node) DisconnectAll()
- func (n *Node) EmbeddedStruct(t reflect.Type) Ki
- func (n *Node) FieldByName(field string) interface{}
- func (n *Node) FieldRoot() Ki
- func (n *Node) FieldTag(field, tag string) string
- func (n *Node) Fields() []uintptr
- func (n *Node) FindPathUnique(path string) Ki
- func (n *Node) Flags() *int64
- func (n *Node) FuncDownBreadthFirst(level int, data interface{}, fun Func)
- func (n *Node) FuncDownDepthFirst(level int, data interface{}, doChildTestFunc Func, fun Func)
- func (n *Node) FuncDownMeFirst(level int, data interface{}, fun Func) bool
- func (n *Node) FuncFields(level int, data interface{}, fun Func)
- func (n *Node) FuncUp(level int, data interface{}, fun Func) bool
- func (n *Node) FuncUpParent(level int, data interface{}, fun Func) bool
- func (n *Node) GetPtrPaths()
- func (n *Node) GoFuncDown(level int, data interface{}, fun Func)
- func (n *Node) GoFuncDownWait(level int, data interface{}, fun Func)
- func (n *Node) GoFuncFields(level int, data interface{}, fun Func)
- func (n *Node) HasChildren() bool
- func (n *Node) HasParent(par Ki) bool
- func (n *Node) Index() int
- func (n *Node) Init(this Ki)
- func (n *Node) InitName(ki Ki, name string)
- func (n *Node) InsertChild(kid Ki, at int) error
- func (n *Node) InsertChildImpl(kid Ki, at int) error
- func (n *Node) InsertNewChild(typ reflect.Type, at int, name string) Ki
- func (n *Node) InsertNewChildUnique(typ reflect.Type, at int, name string) Ki
- func (n *Node) IsDeleted() bool
- func (n *Node) IsDestroyed() bool
- func (n *Node) IsField() bool
- func (n *Node) IsRoot() bool
- func (n *Node) IsUpdating() bool
- func (n *Node) IsUpdatingMu() bool
- func (n *Node) IsValidIndex(idx int) bool
- func (n *Node) KiFieldByName(name string) Ki
- func (n *Node) LoadJSON(b []byte) error
- func (n *Node) LoadJSONFromFile(filename string) error
- func (n *Node) LoadXML(b []byte) error
- func (n *Node) MoveChild(from, to int) error
- func (n *Node) Name() string
- func (n *Node) New() Ki
- func (n *Node) NewOfType(typ reflect.Type) Ki
- func (n *Node) NodeSignal() *Signal
- func (n *Node) OnlySelfUpdate() bool
- func (n *Node) Parent() Ki
- func (n *Node) ParentAllChildren()
- func (n *Node) ParentByName(name string) Ki
- func (n *Node) ParentByType(t reflect.Type, embeds bool) Ki
- func (n *Node) Path() string
- func (n *Node) PathFrom(par Ki) string
- func (n *Node) PathFromUnique(par Ki) string
- func (n *Node) PathUnique() string
- func (n *Node) Prop(key string, inherit, typ bool) interface{}
- func (n *Node) Properties() Props
- func (n *Node) Root() Ki
- func (n *Node) SaveJSON(indent bool) ([]byte, error)
- func (n *Node) SaveJSONToFile(filename string) error
- func (n *Node) SaveXML(indent bool) ([]byte, error)
- func (n *Node) SetChildType(t reflect.Type) error
- func (n *Node) SetField(field string, val interface{}) bool
- func (n *Node) SetFieldDown(field string, val interface{})
- func (n *Node) SetFieldUp(field string, val interface{})
- func (n *Node) SetFlagMu(flag ...int)
- func (n *Node) SetFlagStateMu(on bool, flag ...int)
- func (n *Node) SetNChildren(trgn int, typ reflect.Type, nameStub string) (mods, updt bool)
- func (n *Node) SetName(name string) bool
- func (n *Node) SetNameRaw(name string)
- func (n *Node) SetOnlySelfUpdate()
- func (n *Node) SetParent(parent Ki)
- func (n *Node) SetProp(key string, val interface{})
- func (n *Node) SetPropChildren(key string, val interface{})
- func (n *Node) SetPropUpdate(key string, val interface{})
- func (n *Node) SetProps(props Props, update bool)
- func (n *Node) SetPtrsFmPaths()
- func (n *Node) SetUniqueName(name string)
- func (n Node) String() string
- func (n *Node) ThisCheck() error
- func (n *Node) ThisOk() bool
- func (n *Node) Type() reflect.Type
- func (n *Node) TypeEmbeds(t reflect.Type) bool
- func (n *Node) UniqueName() string
- func (n *Node) UniquifyNames()
- func (n *Node) UnmarshalPost()
- func (n *Node) UpdateEnd(updt bool)
- func (n *Node) UpdateEndNoSig(updt bool)
- func (n *Node) UpdatePtrPaths(oldPath, newPath string, startOnly bool)
- func (n *Node) UpdateReset()
- func (n *Node) UpdateSig() bool
- func (n *Node) UpdateStart() bool
- type NodeSignals
- type Props
- type Ptr
- func (k *Ptr) GetPath()
- func (k Ptr) MarshalJSON() ([]byte, error)
- func (k Ptr) MarshalXML(e *xml.Encoder, start xml.StartElement) error
- func (k *Ptr) PtrFmPath(root Ki) bool
- func (k *Ptr) Reset()
- func (k *Ptr) UnmarshalJSON(b []byte) error
- func (k *Ptr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
- func (k *Ptr) UpdatePath(oldPath, newPath string, startOnly bool)
- type RecvFunc
- type Signal
- func (sig *Signal) Connect(recv Ki, fun RecvFunc) error
- func (sig *Signal) ConnectOnly(recv Ki, fun RecvFunc) error
- func (sig *Signal) Disconnect(recv Ki, fun RecvFunc) bool
- func (sig *Signal) DisconnectAll()
- func (s *Signal) Emit(sender Ki, sig int64, data interface{})
- func (s *Signal) EmitFiltered(sender Ki, sig int64, data interface{}, fun SignalFilterFunc)
- func (s *Signal) EmitGo(sender Ki, sig int64, data interface{})
- func (s *Signal) EmitGoFiltered(sender Ki, sig int64, data interface{}, fun SignalFilterFunc)
- func (s *Signal) EmitTrace(sender Ki, sig int64, data interface{})
- func (sig *Signal) FindConnectionIndex(recv Ki, fun RecvFunc) int
- type SignalFilterFunc
- type Slice
- func (k *Slice) Config(n Ki, config kit.TypeAndNameList, uniqNm bool) (mods, updt bool)
- func (k *Slice) DeleteAtIndex(idx int) error
- func (k *Slice) Elem(idx int) Ki
- func (k *Slice) Index(kid Ki, startIdx int) int
- func (k *Slice) IndexByFunc(startIdx int, match func(ki Ki) bool) int
- func (k *Slice) IndexByName(name string, startIdx int) int
- func (k *Slice) IndexByType(t reflect.Type, embeds bool, startIdx int) int
- func (k *Slice) IndexByUniqueName(name string, startIdx int) int
- func (k *Slice) Insert(ki Ki, idx int)
- func (k Slice) IsValidIndex(idx int) bool
- func (k Slice) MarshalJSON() ([]byte, error)
- func (k Slice) MarshalXML(e *xml.Encoder, start xml.StartElement) error
- func (k *Slice) Move(from, to int) error
- func (k *Slice) NameToIndexMap() map[string]int
- func (k *Slice) TypeAndNames() kit.TypeAndNameList
- func (k *Slice) TypeAndUniqueNames() kit.TypeAndNameList
- func (k *Slice) UniqueNameToIndexMap() map[string]int
- func (k *Slice) UnmarshalJSON(b []byte) error
- func (k *Slice) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
- func (k Slice) ValidIndex(idx int) (int, error)
Constants ¶
This section is empty.
Variables ¶
var DelMgr = Deleted{}
DelMgr is the manager of all deleted items
var KiT_Node = kit.Types.AddType(&Node{}, nil)
must register all new types so type names can be looked up by name -- also props
var KiT_Props = kit.Types.AddType(&Props{}, PropsProps)
var KiT_Ptr = kit.Types.AddType(&Ptr{}, nil)
var KiT_Signal = kit.Types.AddType(&Signal{}, nil)
var PropsProps = Props{ "basic-type": true, }
var SignalTrace bool = false
set this to true to automatically print out a trace of the signals as they are sent
var SignalTraceString *string
set this to a string to receive trace in a string that can be compared for testing otherwise just goes to stdout
var UseJsonIter bool = false
use this to switch between using standard json vs. faster jsoniter right now jsoniter does not continue with the MarshalIndent beyond first level, even when called specifically in the Slice code
Functions ¶
func DecodeXMLCharData ¶
read char data..
func DecodeXMLCharEl ¶
read a start / chardata / end sequence of 3 elements, returning name, val
func DecodeXMLEndEl ¶
func DecodeXMLEndEl(d *xml.Decoder, start xml.StartElement) error
read an end element
func DecodeXMLStartEl ¶
func DecodeXMLStartEl(d *xml.Decoder) (start xml.StartElement, err error)
read a start element token
func FlatFieldsValueFunc ¶
func FlatFieldsValueFunc(stru interface{}, fun func(stru interface{}, typ reflect.Type, field reflect.StructField, fieldVal reflect.Value) bool) bool
Node version of this function from kit/embeds.go
Types ¶
type Connection ¶
type Connection struct { // node that will receive the signal Recv Ki // function on the receiver node that will receive the signal Func RecvFunc }
Connection represents one connection between a signal and a receiving Ki and function to call
func (*Connection) SendSig ¶
func (con *Connection) SendSig(sender Ki, sig int64, data interface{})
SendSig sends the signal over this connection
type Deleted ¶
Deleted manages all the deleted Ki elements, that are destined to then be destroyed, without having an additional pointer on the Ki object
func (*Deleted) DestroyDeleted ¶
func (dm *Deleted) DestroyDeleted()
type Flags ¶
type Flags int32
Flags are bit flags for efficient core state of nodes -- see bitflag package for using these ordinal values to manipulate bit flag field
const ( // this node is a field in its parent node, not a child in children IsField Flags = iota // Updating flag is set at UpdateStart and cleared if we were the first // updater at UpdateEnd Updating // OnlySelfUpdate means that the UpdateStart / End logic only applies to // this node in isolation, not to its children -- useful for a parent node // that has a different functional role than its children OnlySelfUpdate // NodeAdded means a node was added to new parent NodeAdded // NodeCopied means node was copied from other node NodeCopied // NodeMoved means node was moved in the tree, or to a new tree NodeMoved // NodeDeleted means this node has been deleted NodeDeleted // NodeDestroyed means this node has been destroyed -- do not trigger any // more update signals on it NodeDestroyed // ChildAdded means one or more new children were added to the node ChildAdded // ChildMoved means one or more children were moved within the node ChildMoved // ChildDeleted means one or more children were deleted from the node ChildDeleted // ChildrenDeleted means all children were deleted ChildrenDeleted // FieldUpdated means a field was updated FieldUpdated // PropUpdated means a property was set PropUpdated // FlagsN is total number of flags used by base Ki Node -- can extend from // here up to 64 bits FlagsN // Mask for node updates NodeUpdateFlagsMask = (1 << uint32(NodeAdded)) | (1 << uint32(NodeCopied)) | (1 << uint32(NodeMoved)) // Mask for child updates ChildUpdateFlagsMask = (1 << uint32(ChildAdded)) | (1 << uint32(ChildMoved)) | (1 << uint32(ChildDeleted)) | (1 << uint32(ChildrenDeleted)) // Mask for structural changes update flags StruUpdateFlagsMask = NodeUpdateFlagsMask | ChildUpdateFlagsMask | (1 << uint32(NodeDeleted)) // Mask for non-structural, value-only changes update flags ValUpdateFlagsMask = (1 << uint32(FieldUpdated)) | (1 << uint32(PropUpdated)) // Mask for all the update flags -- destroyed is excluded b/c otherwise it // would get cleared UpdateFlagsMask = StruUpdateFlagsMask | ValUpdateFlagsMask )
func StringToFlags ¶
type Func ¶
Func is a function to call on ki objects walking the tree -- return bool = false means don't continue processing this branch of the tree, but other branches can continue
type Ki ¶
type Ki interface { // Init initializes the node -- automatically called during Add/Insert // Child -- sets the This pointer for this node as a Ki interface (pass // pointer to node as this arg) -- Go cannot always access the true // underlying type for structs using embedded Ki objects (when these objs // are receivers to methods) so we need a This interface pointer that // guarantees access to the Ki interface in a way that always reveals the // underlying type (e.g., in reflect calls). Calls Init on Ki fields // within struct, sets their names to the field name, and sets us as their // parent. Init(this Ki) // New creates a new object of this type -- MUST be defined for each // new type instance -- can also set any essential default values when // creating, but the Go style is to use 0 initial values wherever possible // -- do NOT call Init() on it as that will happen automatically later New() Ki // InitName initializes this node and set its name -- used for root nodes // which don't otherwise have their This pointer set (typically happens in // Add, Insert Child) InitName(this Ki, name string) // ThisCheck checks that the This pointer is set and issues a warning to // log if not -- returns error if not set -- called when nodes are added // and inserted ThisCheck() error // ThisOk -- a simpler check for parent access routines where the parent // .This pointer may be validly not set yet -- returns false if .This is // nil ThisOk() bool // Type returns the underlying struct type of this node // (reflect.TypeOf(This).Elem()) Type() reflect.Type // TypeEmbeds tests whether this node is of the given type, or it embeds // that type at any level of anonymous embedding -- use EmbeddedStruct to // get the embedded struct of that type from this node TypeEmbeds(t reflect.Type) bool // EmbeddedStruct returns the embedded struct of given type from this node // (or nil if it does not embed that type, or the type is not a Ki type -- // see kit.EmbeddedStruct for a generic interface{} version EmbeddedStruct(t reflect.Type) Ki // Parent returns the parent of this Ki (Node.Par) -- Ki has strict // one-parent, no-cycles structure -- see SetParent Parent() Ki // HasParent returns true if this node has a parent at any level above it // that is the given node HasParent(par Ki) bool // Child returns the child at given index -- supports negative indexes to // access from end of slice (-1 = last child, etc) -- returns nil if no // children or index is invalid -- use IsValidIndex when unsure -- use // Children()[idx] for fast direct access when index is known to be valid Child(idx int) Ki // Children returns the slice of children (Node.Kids) -- this can be // modified directly (e.g., sort, reorder) but Add* / Delete* functions // should be used to ensure proper tracking Children() Slice // IsValidIndex checks whether the given index is a valid index into // children, within range of 0..len-1 -- see ki.Slice.ValidIndex for // version that transforms negative numbers into indicies from end of // slice, and has explicit error messages IsValidIndex(idx int) bool // Name returns the user-defined name of the object (Node.Nm), for finding // elements, generating paths, IO, etc -- allows generic GUI / Text / Path // / etc representation of Trees Name() string // UniqueName returns a name that is guaranteed to be non-empty and unique // within the children of this node (Node.UniqueNm), but starts with Name // or parents name if Name is empty -- important for generating unique // paths to definitively locate a given node in the tree (see PathUnique, // FindPathUnique) UniqueName() string // SetName sets the name of this node, and its unique name based on this // name, such that all names are unique within list of siblings of this // node (somewhat expensive but important, unless you definitely know that // the names are unique -- see SetNameRaw). Does nothing if name is // already set to that value -- returns false in that case. Does NOT // wrap in UpdateStart / End SetName(name string) bool // SetNameRaw just sets the name and doesn't update the unique name -- // only use if also/ setting unique names in some other way that is // guaranteed to be unique SetNameRaw(name string) // SetUniqueName sets the unique name of this node based on given name // string -- does not do any further testing that the name is indeed // unique -- should generally only be used by UniquifyNames SetUniqueName(name string) // UniquifyNames ensures all of my children have unique, non-empty names // -- duplicates are named sequentially _1, _2 etc, and empty names get a // name based on my name or my type name UniquifyNames() // Flag returns the bit flags for this node -- use bitflag package to // manipulate flags -- see Flags type for standard values used in Ki Node // -- can be extended from FlagsN up to 64 bit capacity Flags() *int64 // SetFlagMu provides a mutex-locked bit flag update -- use this whenever // there might be concurrent access SetFlagMu(flag ...int) // SetFlagState provides a mutex-locked bit flag update -- use this // whenever there might be concurrent access SetFlagStateMu(on bool, flag ...int) // ClearFlag provides a mutex-locked bit flag update -- use this whenever // there might be concurrent access ClearFlagMu(flag ...int) // IsField checks if this is a field on a parent struct (via IsField // Flag), as opposed to a child in Children -- Ki nodes can be added as // fields to structs and they are automatically parented and named with // field name during Init function -- essentially they function as fixed // children of the parent struct, and are automatically included in // FuncDown* traversals, etc -- see also FunFields IsField() bool // IsUpdating checks if node is currently updating IsUpdating() bool // IsUpdatingMu checks if node is currently updating, protected by flag mutex IsUpdatingMu() bool // OnlySelfUpdate checks if this node only applies UpdateStart / End logic // to itself, not its children (which is the default) (via Flag of same // name) -- useful for a parent node that has a different function than // its children OnlySelfUpdate() bool // SetOnlySelfUpdate sets the OnlySelfUpdate flag -- see OnlySelfUpdate // method and flag SetOnlySelfUpdate() // IsDeleted checks if this node has just been deleted (within last update // cycle), indicated by the NodeDeleted flag which is set when the node is // deleted, and is cleared at next UpdateStart call IsDeleted() bool // IsDestroyed checks if this node has been destroyed -- the NodeDestroyed // flag is set at start of Destroy function -- the Signal Emit process // checks for destroyed receiver nodes and removes connections to them // automatically -- other places where pointers to potentially destroyed // nodes may linger should also check this flag and reset those pointers IsDestroyed() bool // Properties (Node.Props) tell the GoGi GUI or other frameworks operating // on Trees about special features of each node -- functions below support // inheritance up Tree -- see kit convert.go for robust convenience // methods for converting interface{} values to standard types Properties() Props // SetProp sets given property key to value val -- initializes property // map if nil SetProp(key string, val interface{}) // SetProps sets a whole set of properties, and optionally sets the // updated flag and triggers an UpdateSig SetProps(props Props, update bool) // SetPropUpdate sets given property key to value val, with update // notification (sets PropUpdated and emits UpdateSig) so other nodes // receiving update signals from this node can update to reflect these // changes SetPropUpdate(key string, val interface{}) // SetPropChildren sets given property key to value val for all Children SetPropChildren(key string, val interface{}) // Prop gets property value from key -- if inherit, then checks all // parents too -- if typ then checks property on type as well (and on // embedded types if inherit is true) -- returns nil if not set Prop(key string, inherit, typ bool) interface{} // DeleteProp deletes property key, safely DeleteProp(key string) // DeleteAllProps deletes all properties on this node -- just makes a new // Props map -- can specify the capacity of the new map (0 is ok -- always // grows automatically anyway) DeleteAllProps(cap int) // CopyPropsFrom copies our properties from another node -- if deep then // does a deep copy -- otherwise copied map just points to same values in // the original map (and we don't reset our map first -- call // DeleteAllProps to do that -- deep copy uses gob encode / decode -- // usually not needed) CopyPropsFrom(from Ki, deep bool) error // SetParent just sets parent of node (and inherits update count from // parent, to keep consistent) -- does NOT remove from existing parent -- // use Add / Insert / Delete Child functions properly move or delete nodes SetParent(parent Ki) // IsRoot tests if this node is the root node -- checks Parent = nil IsRoot() bool // Root returns the root object of this tree (the node with a nil parent) Root() Ki // FieldRoot returns the field root object for this node -- the node that // owns the branch of the tree rooted in one of its fields -- the first // non-Field parent node after the first Field parent node -- can be nil // if no such thing exists for this node FieldRoot() Ki // HasChildren tests whether this node has children (i.e., non-terminal) HasChildren() bool // Index returns our index within our parent object -- caches the last // value and uses that for an optimized search so subsequent calls are // typically quite fast -- returns -1 if we don't have a parent Index() int // SetChildType sets the ChildType used as a default type for creating new // children -- as a property called ChildType --ensures that the type is a // Ki type, and errors if not SetChildType(t reflect.Type) error // AddChild adds a new child at end of children list -- if child is in an // existing tree, it is removed from that parent, and a NodeMoved signal // is emitted for the child -- UniquifyNames is called after adding to // ensure name is unique (assumed to already have a name) AddChild(kid Ki) error // InsertChild adds a new child at given position in children list -- if // child is in an existing tree, it is removed from that parent, and a // NodeMoved signal is emitted for the child -- UniquifyNames is called // after adding to ensure name is unique (assumed to already have a name) InsertChild(kid Ki, at int) error // NewOfType creates a new child of given type -- if nil, uses ChildType, // else uses the same type as this struct NewOfType(typ reflect.Type) Ki // AddNewChild creates a new child of given type -- if nil, uses // ChildType, else type of this struct -- and add at end of children list // -- assigns name (can be empty) and enforces UniqueName AddNewChild(typ reflect.Type, name string) Ki // InsertNewChild creates a new child of given type -- if nil, uses // ChildType, else type of this struct -- and add at given position in // children list -- assigns name (can be empty) and enforces UniqueName InsertNewChild(typ reflect.Type, at int, name string) Ki // InsertNewChildUnique adds a new child at given position in children // list, and gives it a name, using SetNameRaw and SetUniqueName for the // name -- only when names are known to be unique (faster) InsertNewChildUnique(typ reflect.Type, at int, name string) Ki // MoveChild moves child from one position to another in the list of // children (see also corresponding Slice method) MoveChild(from, to int) error // SetNChildren ensures that there are exactly n children, deleting any // extra, and creating any new ones, using AddNewChild with given type and // naming according to nameStubX where X is the index of the child. // // IMPORTANT: returns whether any modifications were made (mods) AND if // that is true, the result from the corresponding UpdateStart call -- // UpdateEnd is NOT called, allowing for further subsequent updates before // you call UpdateEnd(updt) // // Note that this does not ensure existing children are of given type, or // change their names, or call UniquifyNames -- use ConfigChildren for // those cases -- this function is for simpler cases where a parent uses // this function consistently to manage children all of the same type SetNChildren(n int, typ reflect.Type, nameStub string) (mods, updt bool) // ConfigChildren configures children according to given list of // type-and-name's -- attempts to have minimal impact relative to existing // items that fit the type and name constraints (they are moved into the // corresponding positions), and any extra children are removed, and new // ones added, to match the specified config. If uniqNm, then names // represent UniqueNames (this results in Name == UniqueName for created // children). // // IMPORTANT: returns whether any modifications were made (mods) AND if // that is true, the result from the corresponding UpdateStart call -- // UpdateEnd is NOT called, allowing for further subsequent updates before // you call UpdateEnd(updt) ConfigChildren(config kit.TypeAndNameList, uniqNm bool) (mods, updt bool) // ChildIndexByFunc returns index of child based on match function (true // for match, false for not) -- startIdx arg allows for optimized // bidirectional search if you have an idea where it might be -- can be // key speedup for large lists ChildIndexByFunc(startIdx int, match func(ki Ki) bool) int // ChildIndex returns index of child -- startIdx arg allows for optimized // bidirectional search if you have an idea where it might be -- can be // key speedup for large lists ChildIndex(kid Ki, startIdx int) int // ChildIndexByName returns index of child from name -- startIdx arg // allows for optimized bidirectional search if you have an idea where it // might be -- can be key speedup for large lists ChildIndexByName(name string, startIdx int) int // ChildIndexByUniqueName returns index of child from unique name -- // startIdx arg allows for optimized bidirectional search if you have an // idea where it might be -- can be key speedup for large lists ChildIndexByUniqueName(name string, startIdx int) int // ChildIndexByType returns index of child by type -- if embeds is true, // then it looks for any type that embeds the given type at any level of // anonymous embedding -- startIdx arg allows for optimized bidirectional // search if you have an idea where it might be -- can be key speedup for // large lists ChildIndexByType(t reflect.Type, embeds bool, startIdx int) int // ChildByName returns child from name -- startIdx arg allows for // optimized search if you have an idea where it might be -- can be key // speedup for large lists ChildByName(name string, startIdx int) Ki // ChildByType returns child from type (any of types given) -- returns nil // if not found -- if embeds is true, then it looks for any type that // embeds the given type at any level of anonymous embedding -- startIdx // arg allows for optimized bidirectional search if you have an idea where // it might be -- can be key speedup for large lists ChildByType(t reflect.Type, embeds bool, startIdx int) Ki // ParentByName returns parent by name -- returns nil if not found ParentByName(name string) Ki // ParentByType returns parent by type (any of types given) -- returns nil // if not found -- if embeds is true, then it looks for any type that // embeds the given type at any level of anonymous embedding ParentByType(t reflect.Type, embeds bool) Ki // KiFieldByName returns field Ki element by name -- returns nil if not found KiFieldByName(name string) Ki // DeleteChildAtIndex deletes child at given index -- if child's parent = // this node, then will call SetParent(nil), so to transfer to another // list, set new parent first -- destroy will add removed child to deleted // list, to be destroyed later -- otherwise child remains intact but // parent is nil -- could be inserted elsewhere DeleteChildAtIndex(idx int, destroy bool) // DeletChild deletes child node -- if child's parent = this node, then // will call SetParent(nil), so to transfer to another list, set new // parent first -- destroy will add removed child to deleted list, to be // destroyed later -- otherwise child remains intact but parent is nil -- // could be inserted elsewhere DeleteChild(child Ki, destroy bool) // DeleteChildByName deletes child node by name -- returns child -- if // child's parent = this node, then will call SetParent(nil), so to // transfer to another list, set new parent first -- destroy will add // removed child to deleted list, to be destroyed later -- otherwise child // remains intact but parent is nil -- could be inserted elsewhere DeleteChildByName(name string, destroy bool) Ki // DeleteChildren deletes all children nodes -- destroy will add removed // children to deleted list, to be destroyed later -- otherwise children // remain intact but parent is nil -- could be inserted elsewhere, but you // better have kept a slice of them before calling this DeleteChildren(destroy bool) // Delete deletes this node from its parent children list-- destroy will // add removed child to deleted list, to be destroyed later -- otherwise // child remains intact but parent is nil -- could be inserted elsewhere Delete(destroy bool) // Destroy calls DisconnectAll to cut all pointers and signal connections, // and remove all children and their childrens-children, etc Destroy() // FuncFields calls function on all Ki fields within this node FuncFields(level int, data interface{}, fun Func) // GoFuncFields calls concurrent goroutine function on all Ki fields // within this node GoFuncFields(level int, data interface{}, fun Func) // FuncUp calls function on given node and all the way up to its parents, // and so on -- sequentially all in current go routine (generally // necessary for going up, which is typicaly quite fast anyway) -- level // is incremented after each step (starts at 0, goes up), and passed to // function -- returns false if fun aborts with false, else true FuncUp(level int, data interface{}, fun Func) bool // FuncUpParent calls function on parent of node and all the way up to its // parents, and so on -- sequentially all in current go routine (generally // necessary for going up, which is typicaly quite fast anyway) -- level // is incremented after each step (starts at 0, goes up), and passed to // function -- returns false if fun aborts with false, else true FuncUpParent(level int, data interface{}, fun Func) bool // FuncDownMeFirst calls function on this node (MeFirst) and then call // FuncDownMeFirst on all the children -- sequentially all in current go // routine -- level var is incremented before calling children -- if fun // returns false then any further traversal of that branch of the tree is // aborted, but other branches continue -- i.e., if fun on current node // returns false, then returns false and children are not processed // further -- this is the fastest, most natural form of traversal FuncDownMeFirst(level int, data interface{}, fun Func) bool // FuncDownDepthFirst calls FuncDownDepthFirst on all children, then calls // function on this node -- sequentially all in current go routine -- // level var is incremented before calling children -- runs // doChildTestFunc on each child first to determine if it should process // that child, and if that returns true, then it calls FuncDownDepthFirst // on that child FuncDownDepthFirst(level int, data interface{}, doChildTestFunc Func, fun Func) // FuncDownBreadthFirst calls function on all children, then calls // FuncDownBreadthFirst on all the children -- does NOT call on first node // where this method is first called, due to nature of recursive logic -- // level var is incremented before calling chlidren -- if fun returns // false then any further traversal of that branch of the tree is aborted, // but other branches can continue FuncDownBreadthFirst(level int, data interface{}, fun Func) // GoFuncDown calls concurrent goroutine function on given node and all // the way down to its children, and so on -- does not wait for completion // of the go routines -- returns immediately GoFuncDown(level int, data interface{}, fun Func) // GoFuncDownWait calls concurrent goroutine function on given node and // all the way down to its children, and so on -- does wait for the // completion of the go routines before returning GoFuncDownWait(level int, data interface{}, fun Func) // Path returns path to this node from Root(), using regular user-given // Name's (may be empty or non-unique), with nodes separated by / and // fields by . -- only use for informational purposes Path() string // PathUnique returns path to this node from Root(), using unique names, // with nodes separated by / and fields by . -- suitable for reliably // finding this node PathUnique() string // PathFrom returns path to this node from given parent node, using // regular user-given Name's (may be empty or non-unique), with nodes // separated by / and fields by . -- only use for informational purposes PathFrom(par Ki) string // PathFromUnique returns path to this node from given parent node, using // unique names, with nodes separated by / and fields by . -- suitable for // reliably finding this node PathFromUnique(par Ki) string // FindPathUnique returns Ki object at given unique path, starting from // this node (e.g., Root()) -- returns nil if not found FindPathUnique(path string) Ki // NodeSignal returns the main signal for this node that is used for // update, child signals NodeSignal() *Signal // UpdateStart should be called when starting to modify the tree (state or // structure) -- returns whether this node was first to set the Updating // flag (if so, all children have their Updating flag set -- pass the // result to UpdateEnd -- automatically determines the highest level // updated, within the normal top-down updating sequence -- can be called // multiple times at multiple levels -- it is essential to ensure that all // such Start's have an End! Usage: // // updt := n.UpdateStart() // ... code // n.UpdateEnd(updt) // UpdateStart() bool // UpdateEnd should be called when done updating after an UpdateStart, and // passed the result of the UpdateStart call -- if this is true, the // NodeSignalUpdated signal will be emitted and the Updating flag will be // cleared, and DestroyDeleted called -- otherwise it is a no-op UpdateEnd(updt bool) // UpdateEndNoSig is just like UpdateEnd except it does not emit a // NodeSignalUpdated signal -- use this for situations where updating is // already known to be in progress and the signal would be redundant UpdateEndNoSig(updt bool) // UpdateSig just emits a NodeSignalUpdated if the Updating flag is not // set -- use this to trigger an update of a given node when there aren't // any structural changes and you don't need to prevent any lower-level // updates -- much more efficient than a pair of UpdateStart / // UpdateEnd's. Returns true if an update signal was sent. UpdateSig() bool // UpdateReset resets Updating flag for this node and all children -- in // case they are out-of-sync due to more complex tree maninpulations -- // only call at a known point of non-updating.. UpdateReset() // Disconnect disconnects node -- reset all ptrs to nil, and // DisconnectAll() signals -- e.g., for freeing up all connnections so // node can be destroyed and making GC easier Disconnect() // DisconnectAll disconnects all the way from me down the tree DisconnectAll() // SetField sets given field name to given value, using very robust // conversion routines to e.g., convert from strings to numbers, and // vice-versa, automatically -- returns true if successfully set -- // wrapped in UpdateStart / End and sets the FieldUpdated flag SetField(field string, val interface{}) bool // SetFieldDown sets given field name to given value, all the way down the // tree from me -- wrapped in UpdateStart / End SetFieldDown(field string, val interface{}) // SetFieldUp sets given field name to given value, all the way up the // tree from me -- wrapped in UpdateStart / End SetFieldUp(field string, val interface{}) // FieldByName returns field value by name (can be any type of field -- // see KiFieldByName for Ki fields) -- returns nil if not found FieldByName(field string) interface{} // FieldTag returns given field tag for that field, or empty string if not // set FieldTag(field, tag string) string // CopyFrom another Ki node. The Ki copy function recreates the entire // tree in the copy, duplicating children etc. It is very efficient by // using the ConfigChildren method which attempts to preserve any existing // nodes in the destination if they have the same name and type -- so a // copy from a source to a target that only differ minimally will be // minimally destructive. Only copies to same types are supported. // Pointers (Ptr) are copied by saving the current UniquePath and then // SetPtrsFmPaths is called -- no other Ki point. Signal connections are // NOT copied (todo: revisit). No other Ki pointers are copied, and the // field tag copy:"-" can be added for any other fields that should not be // copied (unexported, lower-case fields are not copyable). // // When nodes are copied from one place to another within the same overall // tree, paths are updated so that pointers to items within the copied // sub-tree are updated to the new location there (i.e., the path to the // old loation is replaced with that of the new destination location), // whereas paths outside of the copied location are not changed and point // as before. See also MoveTo function for moving nodes to other parts of // the tree. Sequence of functions is: GetPtrPaths on from, CopyFromRaw, // UpdtPtrPaths, then SetPtrsFmPaths CopyFrom(from Ki) error // Clone creates and returns a deep copy of the tree from this node down. // Any pointers within the cloned tree will correctly point within the new // cloned tree (see Copy info) Clone() Ki // CopyFromRaw performs a raw copy that just does the deep copy of the // bits and doesn't do anything with pointers CopyFromRaw(from Ki) error // GetPtrPaths gets all Ptr path strings -- walks the tree down from // current node and calls GetPath on all Ptr fields -- this is called // prior to copying / moving GetPtrPaths() // UpdatePtrPaths updates Ptr paths, replacing any occurrence of oldPath with // newPath, optionally only at the start of the path (typically true) -- // for all nodes down from this one UpdatePtrPaths(oldPath, newPath string, startOnly bool) // SetPtrsFmPaths walks the tree down from current node and calls // PtrFromPath on all Ptr fields found -- called after Copy, Unmarshal* to // recover pointers after entire structure is in place -- see // UnmarshalPost SetPtrsFmPaths() // SaveJSON saves the tree to a JSON-encoded byte string -- wraps // MarshalJSON SaveJSON(indent bool) ([]byte, error) // SaveJSONToFile saves the tree to a JSON-encoded file SaveJSONToFile(filename string) error // LoadJSON loads the tree from a JSON-encoded byte string -- wraps // UnmarshalJSON and calls UnmarshalPost to recover pointers from paths LoadJSON(b []byte) error // SaveJSONFromFile loads the tree from a JSON-encoded file LoadJSONFromFile(filename string) error // SaveXML saves the tree to an XML-encoded byte string SaveXML(indent bool) ([]byte, error) // LoadXML loads the tree from an XML-encoded byte string, calls // UnmarshalPost to recover pointers from paths LoadXML(b []byte) error // ParentAllChildren walks the tree down from current node and call // SetParent on all children -- needed after an Unmarshal ParentAllChildren() // UnmarshallPost must be called after an Unmarshal -- calls // SetPtrsFmPaths and ParentAllChildren UnmarshalPost() }
The Ki interface provides the core functionality for the GoKi tree -- insipred by Qt QObject in specific and every other Tree everywhere in general.
NOTE: The inability to have a field and a method of the same name makes it so you either have to use private fields in a struct that implements this interface (lowercase) or we have to use different names in the struct vs. interface. We want to export and use the direct fields, which are easy to use, so we have different synonyms.
Other key issues with the Ki design / Go: * All interfaces are implicitly pointers: this is why you have to pass args with & address of
type Node ¶
type Node struct { Nm string `copy:"-" label:"Name" desc:"Ki.Name() user-supplied name of this node -- can be empty or non-unique"` UniqueNm string `` /* 228-byte string literal not displayed */ Flag int64 `copy:"-" json:"-" xml:"-" view:"-" desc:"bit flags for internal node state"` Props Props `` /* 135-byte string literal not displayed */ Par Ki `` /* 154-byte string literal not displayed */ Kids Slice `` /* 217-byte string literal not displayed */ NodeSig Signal `` /* 225-byte string literal not displayed */ This Ki `` /* 259-byte string literal not displayed */ FlagMu sync.Mutex `copy:"-" json:"-" xml:"-" view:"-" desc:"mutex protecting flag updates"` // contains filtered or unexported fields }
The Node implements the Ki interface and provides the core functionality for the GoKi tree -- use the Node as an embedded struct or as a struct field -- the embedded version supports full JSON save / load.
The desc: key for fields is used by the GoGr GUI viewer for help / tooltip info -- add these to all your derived struct's fields. See relevant docs for other such tags controlling a wide range of GUI and other functionality -- Ki makes extensive use of such tags.
func (*Node) AddChildCheck ¶
check if it is safe to add child -- it cannot be a parent of us -- prevent loops!
func (*Node) AddChildImpl ¶
func (*Node) ChildIndexByFunc ¶
func (*Node) ChildIndexByType ¶
func (*Node) ChildIndexByUniqueName ¶
func (*Node) ClearFlagMu ¶
func (*Node) ConfigChildren ¶
func (n *Node) ConfigChildren(config kit.TypeAndNameList, uniqNm bool) (mods, updt bool)
func (*Node) CopyFieldsFrom ¶
func (n *Node) CopyFieldsFrom(to interface{}, from interface{})
copy from primary fields of from to to, recursively following anonymous embedded structs
func (*Node) CopyFromRaw ¶
func (*Node) CopyMakeChildrenFrom ¶
use ConfigChildren to recreate source children
func (*Node) DeleteAllProps ¶
func (*Node) DeleteChild ¶
func (*Node) DeleteChildAtIndex ¶
func (*Node) DeleteChildren ¶
func (*Node) DeleteProp ¶
func (*Node) Disconnect ¶
func (n *Node) Disconnect()
func (*Node) DisconnectAll ¶
func (n *Node) DisconnectAll()
func (*Node) FieldByName ¶
func (*Node) FindPathUnique ¶
func (*Node) FuncDownBreadthFirst ¶
func (*Node) FuncDownDepthFirst ¶
func (*Node) FuncDownMeFirst ¶
func (*Node) FuncFields ¶
func (*Node) GetPtrPaths ¶
func (n *Node) GetPtrPaths()
func (*Node) GoFuncDown ¶
func (*Node) GoFuncDownWait ¶
func (*Node) GoFuncFields ¶
func (*Node) HasChildren ¶
func (*Node) InsertNewChild ¶
func (*Node) InsertNewChildUnique ¶
func (*Node) IsDestroyed ¶
func (*Node) IsUpdating ¶
func (*Node) IsUpdatingMu ¶
func (*Node) IsValidIndex ¶
func (*Node) KiFieldByName ¶
func (*Node) LoadJSONFromFile ¶
func (*Node) NodeSignal ¶
func (*Node) OnlySelfUpdate ¶
func (*Node) ParentAllChildren ¶
func (n *Node) ParentAllChildren()
func (*Node) ParentByName ¶
func (*Node) PathFromUnique ¶
func (*Node) PathUnique ¶
func (*Node) Properties ¶
func (*Node) SaveJSONToFile ¶
func (*Node) SetFieldDown ¶
func (*Node) SetFieldUp ¶
func (*Node) SetFlagStateMu ¶
func (*Node) SetNChildren ¶
func (*Node) SetNameRaw ¶
func (*Node) SetOnlySelfUpdate ¶
func (n *Node) SetOnlySelfUpdate()
func (*Node) SetParent ¶
set parent of node -- does not remove from existing parent -- use Add / Insert / Delete
func (*Node) SetPropChildren ¶
func (*Node) SetPropUpdate ¶
func (*Node) SetPtrsFmPaths ¶
func (n *Node) SetPtrsFmPaths()
func (*Node) SetUniqueName ¶
func (*Node) UniqueName ¶
func (*Node) UniquifyNames ¶
func (n *Node) UniquifyNames()
make sure that the names are unique -- n^2 ish
func (*Node) UnmarshalPost ¶
func (n *Node) UnmarshalPost()
func (*Node) UpdateEndNoSig ¶
func (*Node) UpdatePtrPaths ¶
func (*Node) UpdateReset ¶
func (n *Node) UpdateReset()
func (*Node) UpdateStart ¶
type NodeSignals ¶
type NodeSignals int64
NodeSignals are signals that a Ki node sends about updates to the tree structure using the NodeSignal (convert sig int64 to NodeSignals to get the stringer name).
const ( // NodeSignalNil is a nil signal value NodeSignalNil NodeSignals = iota // NodeSignalUpdated indicates that the node was updated -- the node Flags // accumulate the specific changes made since the last update signal -- // these flags are sent in the signal data -- strongly recommend using // that instead of the flags, which can be subsequently updated by the // time a signal is processed NodeSignalUpdated // NodeSignalDeleting indicates that the node is being deleted from its // parent children list -- this is not blocked by Updating status and is // delivered immediately NodeSignalDeleting // NodeSignalDestroying indicates that the node is about to be destroyed // -- this is a second pass after removal from parent -- all of its // children and Ki fields will be destroyed too -- not blocked by updating // status and delivered immediately NodeSignalDestroying NodeSignalsN )
Standard signal types sent by ki.Node on its NodeSig for tree state changes
func StringToNodeSignals ¶
func StringToNodeSignals(s string) (NodeSignals, error)
func (NodeSignals) String ¶
func (i NodeSignals) String() string
type Props ¶
type Props map[string]interface{}
Props is the type used for holding generic properties -- the actual Go type is a mouthful and not very gui-friendly, and we need some special json methods
func SubProps ¶
SubProps returns a value that contains another props, or nil if it doesn't exist or isn't a Props
func (Props) MarshalJSON ¶
MarshalJSON saves the type information for each struct used in props, as a separate key with the __type: prefix -- this allows the Unmarshal to create actual types
func (*Props) UnmarshalJSON ¶
UnmarshalJSON parses the type information in the map to restore actual objects -- this is super inefficient and really needs a native parser, but props are likely to be relatively small
type Ptr ¶
Ptr provides JSON marshal / unmarshal via saved PathUnique
func (*Ptr) GetPath ¶
func (k *Ptr) GetPath()
GetPath updates the Path field with the current path to the pointer
func (Ptr) MarshalJSON ¶
MarshalJSON gets the current path and saves only the Path directly as value of this struct
func (Ptr) MarshalXML ¶
MarshalXML getes the current path and saves it
func (*Ptr) PtrFmPath ¶
PtrFromPath finds and sets the Ptr value based on the current Path string -- returns true if pointer is found and non-nil
func (*Ptr) UnmarshalJSON ¶
UnarshalJSON loads the Path string directly from saved value -- KiNode must call SetPtrsFmPaths to actually update the pointers, based on the root object in the tree from which trees were generated, after all the initial loading has completed and the structure is all in place
func (*Ptr) UnmarshalXML ¶
UnmarshalXML loads the Path string directly from saved value -- KiNode must call SetPtrsFmPaths to actually update the pointers, based on the root object in the tree from which trees were generated, after all the initial loading has completed and the structure is all in place
func (*Ptr) UpdatePath ¶
UpdatePath replaces any occurrence of oldPath with newPath, optionally only at the start of the path (typically true)
type RecvFunc ¶
RecvFunc is a receiver function type for signals -- gets the full connection information and signal, data as specified by the sender. It is good practice to avoid closures in these functions, which can be numerous and have a long lifetime, by converting the recv, send into their known types and referring to them directly
type Signal ¶
type Signal struct {
Cons []Connection
}
Signal structure -- add one of these to your struct for each signal a node can emit
func (*Signal) Connect ¶
Connect attaches a new receiver to the signal -- checks to make sure connection does not already exist -- error if not ok
func (*Signal) ConnectOnly ¶
ConnectOnly first deletes any existing connections and then attaches a new receiver to the signal -- checks to make sure connection does not already exist -- error if not ok
func (*Signal) Disconnect ¶
Disconnect all connections for receiver and/or function if they exist in our list -- can pass nil for either (or both) to match only on one or the other -- both nil means disconnect from all, but more efficient to use DisconnectAll
func (*Signal) Emit ¶
Emit sends the signal across all the connections to the receivers -- sequential
func (*Signal) EmitFiltered ¶
func (s *Signal) EmitFiltered(sender Ki, sig int64, data interface{}, fun SignalFilterFunc)
EmitFiltered calls function on each item only sends signal if function returns true
func (*Signal) EmitGo ¶
EmitGo concurrent version -- sends the signal across all the connections to the receivers
func (*Signal) EmitGoFiltered ¶
func (s *Signal) EmitGoFiltered(sender Ki, sig int64, data interface{}, fun SignalFilterFunc)
EmitGoFiltered calls function on each item only sends signal if function returns true -- concurrent version
type SignalFilterFunc ¶
type SignalFilterFunc func(ki Ki, idx int, con *Connection) bool
SignalFilterFunc is the function type for filtering signals before they are sent -- returns false to prevent sending, and true to allow sending
type Slice ¶
type Slice []Ki
Slice provides JSON marshal / unmarshal with encoding of underlying types
func (*Slice) Config ¶
Config is a major work-horse routine for minimally-destructive reshaping of a tree structure to fit a target configuration, specified in terms of a type-and-name list. If the node is != nil, then it has UpdateStart / End logic applied to it, only if necessary, as indicated by mods, updt return values
func (*Slice) DeleteAtIndex ¶
DeleteAtIndex deletes item at index -- does not do any further management deleted item -- optimized version for avoiding memory leaks
func (*Slice) Elem ¶
Elem returns element at index, using ValidIndex supporting negative indexing from back of list -- returns nil if index is invalid -- use ValidIndex or IsValidIndex directly to test if unsure
func (*Slice) IndexByFunc ¶
IndexByFunc finds index of item based on match function (true for find, false for not) -- startIdx arg allows for optimized bidirectional find if you have an idea where it might be -- can be key speedup for large lists
func (*Slice) IndexByName ¶
IndexByName returns index of first element that has given name -- startIdx arg allows for optimized bidirectional search if you have an idea where it might be -- can be key speedup for large lists
func (*Slice) IndexByType ¶
IndexByType returns index of element that either is that type or embeds that type -- startIdx arg allows for optimized bidirectional search if you have an idea where it might be -- can be key speedup for large lists
func (*Slice) IndexByUniqueName ¶
IndexByUniqueName returns index of first element that has given unique name -- startIdx arg allows for optimized bidirectional search if you have an idea where it might be -- can be key speedup for large lists
func (Slice) IsValidIndex ¶
IsValidIndex checks whether the given index is a valid index into slice, within range of 0..len-1 -- see ValidIndex for version that transforms negative numbers into indicies from end of slice, and has explicit error messages
func (Slice) MarshalJSON ¶
MarshalJSON saves the length and type, name information for each object in a slice, as a separate struct-like record at the start, followed by the structs for each element in the slice -- this allows the Unmarshal to first create all the elements and then load them
func (Slice) MarshalXML ¶
MarshalXML saves the length and type information for each object in a slice, as a separate struct-like record at the start, followed by the structs for each element in the slice -- this allows the Unmarshal to first create all the elements and then load them
func (*Slice) NameToIndexMap ¶
NameToINdexMap returns a Name to Index map for faster lookup when needing to do a lot of name lookups on same fixed slice
func (*Slice) TypeAndNames ¶
func (k *Slice) TypeAndNames() kit.TypeAndNameList
TypeAndNames returns a kit.TypeAndNameList of elements in the slice -- useful for Ki ConfigChildren
func (*Slice) TypeAndUniqueNames ¶
func (k *Slice) TypeAndUniqueNames() kit.TypeAndNameList
TypeAndUniqueNames returns a kit.TypeAndNameList of elements in the slice using UniqueNames -- useful for Ki ConfigChildren
func (*Slice) UniqueNameToIndexMap ¶
UniqueNameToIndexMap returns a UniqueName to Index map for faster lookup when needing to do a lot of name lookups on same fixed slice
func (*Slice) UnmarshalJSON ¶
UnmarshalJSON parses the length and type information for each object in the slice, creates the new slice with those elements, and then loads based on the remaining bytes which represent each element
func (*Slice) UnmarshalXML ¶
UnmarshalJSON parses the length and type information for each object in the slice, creates the new slice with those elements, and then loads based on the remaining bytes which represent each element
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package atomctr implements basic atomic int64 counter, used e.g., for update counter on Ki Node
|
Package atomctr implements basic atomic int64 counter, used e.g., for update counter on Ki Node |
package bitflag provides simple bit flag setting, checking, and clearing methods that take bit position args as ints (from const int eunum iota's) and do the bit shifting from there -- although a tiny bit slower, the convenience of maintaining ordinal lists of bit positions greatly outweighs that cost -- see kit type registry for further enum management functions
|
package bitflag provides simple bit flag setting, checking, and clearing methods that take bit position args as ints (from const int eunum iota's) and do the bit shifting from there -- although a tiny bit slower, the convenience of maintaining ordinal lists of bit positions greatly outweighs that cost -- see kit type registry for further enum management functions |
Package kit provides various reflect type functions for GoKi system, including: * kit.TypeRegistry (types.go) for associating string names with reflect.Type values, to allow dynamic marshaling of structs, and also bidirectional string conversion of const int iota (enum) types.
|
Package kit provides various reflect type functions for GoKi system, including: * kit.TypeRegistry (types.go) for associating string names with reflect.Type values, to allow dynamic marshaling of structs, and also bidirectional string conversion of const int iota (enum) types. |