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.
Index ¶
- Variables
- func CopyProps(dest *map[string]interface{}, src map[string]interface{}, copySubProps bool)
- 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
- func SliceDeleteAtIndex(sl *[]Ki, idx int) bool
- func SliceIndexByFunc(sl *[]Ki, startIdx int, match func(k Ki) bool) (int, bool)
- func SliceIndexByName(sl *[]Ki, name string, startIdx int) (int, bool)
- func SliceIndexByType(sl *[]Ki, t reflect.Type, embeds bool, startIdx int) (int, bool)
- func SliceIndexByUniqueName(sl *[]Ki, name string, startIdx int) (int, bool)
- func SliceIndexOf(sl *[]Ki, kid Ki, startIdx int) (int, bool)
- func SliceInsert(sl *[]Ki, k Ki, idx int)
- func SliceIsValidIndex(sl *[]Ki, idx int) bool
- func SliceMove(sl *[]Ki, from, to int) bool
- type BlankProp
- 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, bool)
- func (n *Node) ChildByName(name string, startIdx int) (Ki, bool)
- func (n *Node) Children() *Slice
- func (n *Node) ClearFlag(flag ...int)
- func (n *Node) ClearFlagMask(mask int64)
- 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) bool
- func (n *Node) DeleteChildAtIndex(idx int, destroy bool) bool
- func (n *Node) DeleteChildByName(name string, destroy bool) (Ki, bool)
- 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) Embed(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, bool)
- 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) GoFuncFields(level int, data interface{}, fun Func)
- func (n *Node) HasAllFlags(flag ...int) bool
- func (n *Node) HasAnyFlag(flag ...int) bool
- func (n *Node) HasChildren() bool
- func (n *Node) HasFlag(flag int) bool
- func (n *Node) HasParent(par Ki) bool
- func (n *Node) IndexInParent() (int, bool)
- func (n *Node) Init(this Ki)
- func (n *Node) InitName(k 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) IsValidIndex(idx int) bool
- func (n *Node) KiFieldByName(name string) (Ki, bool)
- func (n *Node) KnownChild(idx int) Ki
- func (n *Node) KnownChildByName(name string, startIdx int) Ki
- func (n *Node) KnownProp(key string) interface{}
- func (n *Node) MoveChild(from, to int) bool
- func (n *Node) Name() string
- func (n *Node) NewOfType(typ reflect.Type) Ki
- func (n *Node) NodeSignal() *Signal
- func (n *Node) OnlySelfUpdate() bool
- func (n *Node) OpenJSON(filename string) error
- func (n *Node) Parent() Ki
- func (n *Node) ParentAllChildren()
- func (n *Node) ParentByName(name string) (Ki, bool)
- func (n *Node) ParentByType(t reflect.Type, embeds bool) (Ki, bool)
- func (n *Node) ParentLevel(par Ki) int
- 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) (interface{}, bool)
- func (n *Node) PropInherit(key string, inherit, typ bool) (interface{}, bool)
- func (n *Node) PropTag() string
- func (n *Node) Properties() *Props
- func (n *Node) ReadJSON(reader io.Reader) error
- func (n *Node) ReadXML(reader io.Reader) error
- func (n *Node) Root() Ki
- func (n *Node) SaveJSON(filename string) error
- func (n *Node) SetChild(kid Ki, idx int, name string) 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) SetFlag(flag ...int)
- func (n *Node) SetFlagMask(mask int64)
- func (n *Node) SetFlagState(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) This() Ki
- func (n *Node) ThisCheck() error
- 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
- func (n *Node) WriteJSON(writer io.Writer, indent bool) error
- func (n *Node) WriteXML(writer io.Writer, indent bool) error
- type NodeSignals
- type PropSlice
- type PropStruct
- 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 (s *Signal) Connect(recv Ki, fun RecvFunc)
- func (s *Signal) ConnectOnly(recv Ki, fun RecvFunc)
- func (s *Signal) Disconnect(recv Ki)
- func (s *Signal) DisconnectAll()
- func (s *Signal) Emit(sender Ki, sig int64, data interface{})
- func (s *Signal) EmitFiltered(sender Ki, sig int64, data interface{}, filtFun SignalFilterFunc)
- func (s *Signal) EmitGo(sender Ki, sig int64, data interface{})
- func (s *Signal) EmitGoFiltered(sender Ki, sig int64, data interface{}, filtFun SignalFilterFunc)
- func (s *Signal) EmitTrace(sender Ki, sig int64, data interface{})
- func (s *Signal) SendSig(recv, sender Ki, sig int64, data interface{})
- type SignalFilterFunc
- type Slice
- func (sl *Slice) Config(n Ki, config kit.TypeAndNameList, uniqNm bool) (mods, updt bool)
- func (sl *Slice) DeleteAtIndex(idx int) bool
- func (sl *Slice) Elem(idx int) (Ki, bool)
- func (sl *Slice) ElemByName(name string, startIdx int) (Ki, bool)
- func (sl *Slice) ElemByType(t reflect.Type, embeds bool, startIdx int) (Ki, bool)
- func (sl *Slice) ElemByUniqueName(name string, startIdx int) (Ki, bool)
- func (sl *Slice) ElemFromEnd(idx int) (Ki, bool)
- func (sl *Slice) IndexByFunc(startIdx int, match func(k Ki) bool) (int, bool)
- func (sl *Slice) IndexByName(name string, startIdx int) (int, bool)
- func (sl *Slice) IndexByType(t reflect.Type, embeds bool, startIdx int) (int, bool)
- func (sl *Slice) IndexByUniqueName(name string, startIdx int) (int, bool)
- func (sl *Slice) IndexOf(kid Ki, startIdx int) (int, bool)
- func (sl *Slice) Insert(k Ki, idx int)
- func (sl Slice) IsValidIndex(idx int) bool
- func (sl *Slice) KnownElemByName(name string, startIdx int) Ki
- func (sl Slice) MarshalJSON() ([]byte, error)
- func (sl Slice) MarshalXML(e *xml.Encoder, start xml.StartElement) error
- func (sl *Slice) Move(from, to int) bool
- func (sl *Slice) NameToIndexMap() map[string]int
- func (sl *Slice) TypeAndNames() kit.TypeAndNameList
- func (sl *Slice) TypeAndUniqueNames() kit.TypeAndNameList
- func (sl *Slice) UniqueNameToIndexMap() map[string]int
- func (sl *Slice) UnmarshalJSON(b []byte) error
- func (sl *Slice) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
Constants ¶
This section is empty.
Variables ¶
var DelMgr = Deleted{}
DelMgr is the manager of all deleted items
var JSONTypePrefix = []byte("{\"ki.RootType\": ")
JSONTypePrefix is the first thing output in a ki tree JSON output file, specifying the type of the root node of the ki tree -- this info appears all on one { } bracketed line at the start of the file, and can also be used to identify the file as a ki tree JSON file
var JSONTypeSuffix = []byte("}\n")
JSONTypeSuffix is just the } and \n at the end of the prefix line
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
SignalTrace can be set to true to automatically print out a trace of the signals as they are sent
var SignalTraceString *string
SignalTraceString can be set to a string that will then accumulate the trace of signals sent, for use in testing -- otherwise the trace just goes to stdout
var UniquifyPreserveNameLimit = 100
UniquifyPreserveNameLimit is the number of children below which a more expensive approach is taken to uniquify the names to guarantee unique paths, which preserves the original name wherever possible -- formatting of index assumes this limit is less than 1000
Functions ¶
func CopyProps ¶
CopyProps copies properties from source to destination map. If copySubProps is true, then any values that are Props or PropSlice are copied too *dest can be nil, in which case it is created.
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
func IsKi ¶
IsKi returns true if the given type implements the Ki interface at any level of embedded structure.
func SliceDeleteAtIndex ¶
SliceDeleteAtIndex deletes item at index -- does not do any further management deleted item -- optimized version for avoiding memory leaks. returns false if index is invalid.
func SliceIndexByFunc ¶
SliceIndexByFunc finds index of item based on match function (which must return true for a find match, false for not). Returns false if not found. startIdx arg allows for optimized bidirectional find if you have an idea where it might be -- can be key speedup for large lists -- pass -1 to start in the middle (good default)
func SliceIndexByName ¶
SliceIndexByName returns index of first element that has given name, false if not found. See IndexOf for info on startIdx
func SliceIndexByType ¶
SliceIndexByType returns index of element that either is that type or embeds that type, false if not found. See IndexOf for info on startIdx.
func SliceIndexByUniqueName ¶
SliceIndexByUniqueName returns index of first element that has given unique name, false if not found. See IndexOf for info on startIdx.
func SliceIndexOf ¶
SliceIndexOf returns index of element in list, false if not there. startIdx arg allows for optimized bidirectional find if you have an idea where it might be -- can be key speedup for large lists -- pass -1 to start in the middle (good default).
func SliceInsert ¶
SliceInsert item at index -- does not do any parent updating etc -- use Ki/Node method unless you know what you are doing.
func SliceIsValidIndex ¶
SliceIsValidIndex checks whether the given index is a valid index into slice, within range of 0..len-1.
Types ¶
type BlankProp ¶
type BlankProp struct{}
BlankProp is an empty property, for when there isn't any need for the value
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 ( // IsField indicates a 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 // NodeUpdateFlagsMask is a mask for all node updates. NodeUpdateFlagsMask = (1 << uint32(NodeAdded)) | (1 << uint32(NodeCopied)) | (1 << uint32(NodeMoved)) // ChildUpdateFlagsMask is a mask for all child updates. ChildUpdateFlagsMask = (1 << uint32(ChildAdded)) | (1 << uint32(ChildMoved)) | (1 << uint32(ChildDeleted)) | (1 << uint32(ChildrenDeleted)) // StruUpdateFlagsMask is a mask for all structural changes update flags. StruUpdateFlagsMask = NodeUpdateFlagsMask | ChildUpdateFlagsMask | (1 << uint32(NodeDeleted)) // ValUpdateFlagsMask is a mask for all non-structural, value-only changes update flags. ValUpdateFlagsMask = (1 << uint32(FieldUpdated)) | (1 << uint32(PropUpdated)) // UpdateFlagsMask is a Mask for all the update flags -- destroyed is // excluded b/c otherwise it would get cleared. UpdateFlagsMask = StruUpdateFlagsMask | ValUpdateFlagsMask )
func (*Flags) FromString ¶
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) // InitName initializes this node and set its name -- used for root nodes // which don't otherwise have their This pointer set (otherwise typically // happens in Add, Insert Child). InitName(this Ki, name string) // This returns the Ki interface that guarantees access to the Ki // interface in a way that always reveals the underlying type // (e.g., in reflect calls). Returns nil if node is nil, // has been destroyed, or is improperly constructed. This() Ki // 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 // 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 Embed to get the // embedded struct of that type from this node. TypeEmbeds(t reflect.Type) bool // Embed 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.Embed for a generic interface{} version. Embed(t reflect.Type) Ki // 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() // Parent returns the parent of this Ki (Node.Par) -- Ki has strict // one-parent, no-cycles structure -- see SetParent. Parent() Ki // 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 -- i.e., 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 // IndexInParent 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 false if we don't have a parent. IndexInParent() (int, bool) // ParentLevel finds a given potential parent node recursively up the // hierarchy, returning level above current node that the parent was // found, and -1 if not found. ParentLevel(par Ki) int // HasParent checks if given node is a parent of this one (i.e., // ParentLevel(par) != -1). HasParent(par Ki) bool // ParentByName finds first parent recursively up hierarchy that matches // given name -- returns false if not found. ParentByName(name string) (Ki, bool) // ParentByType finds parent recursively up hierarchy, by type, and // returns false 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, bool) // KiFieldByName returns field Ki element by name -- returns false if not found. KiFieldByName(name string) (Ki, bool) // HasChildren tests whether this node has children (i.e., non-terminal). HasChildren() bool // Children returns a pointer to the slice of children (Node.Kids) -- use // methods on ki.Slice for further ways to access (ByName, ByType, etc). // Slice can be modified directly (e.g., sort, reorder) but Add* / Delete* // methods on parent node should be used to ensure proper tracking. Children() *Slice // Child returns the child at given index -- false if index is invalid. // See methods on ki.Slice for more ways to acces. Child(idx int) (Ki, bool) // KnownChild returns the child at given index without checking index -- // use when index is known to be good. KnownChild(idx int) Ki // ChildByName returns first element that has given name, false if not // found. startIdx arg allows for optimized bidirectional find if you have // an idea where it might be -- can be key speedup for large lists -- pass // -1 to start in the middle (good default). ChildByName(name string, startIdx int) (Ki, bool) // KnownChildByName returns first element that has given name, without // returning the bool check value -- use when named element is known to // exist, and will be directly converted to another type, so the multiple // return values are cumbersome. nil is returned if it actually does not // exist. See ChildByName for info on startIdx. KnownChildByName(name string, startIdx int) Ki // 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()) -- if this node is not the root, then the path // to this node is subtracted from the start of the path. returns false if // not found. FindPathUnique(path string) (Ki, bool) // 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 // SetChild sets child at given index to be the given item -- if name is // non-empty then it sets the name of the child as well -- just calls Init // (or InitName) on the child, and SetParent -- does NOT uniquify the // names -- this is for high-volume child creation -- call UniquifyNames // afterward if needed, but better to ensure that names are unique up front. SetChild(kid Ki, idx int, name string) error // MoveChild moves child from one position to another in the list of // children (see also corresponding Slice method). Returns false if // either index is invalid. MoveChild(from, to int) bool // 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) // DeleteChildAtIndex deletes child at given index (returns false for // invalid 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) bool // DeleteChild deletes child node, returning false if not found in // Children. If child's parent = this node, then will call // SetParent(nil), so to transfer to another list, set new parent // first. See DeleteChildAtIndex for destroy info. DeleteChild(child Ki, destroy bool) bool // DeleteChildByName deletes child node by name -- returns child, false // if not found -- if child's parent = this node, then will call // SetParent(nil), so to transfer to another list, set new parent first. // See DeleteChildAtIndex for destroy info. DeleteChildByName(name string, destroy bool) (Ki, bool) // 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() // Flag returns an atomically safe copy of the bit flags for this node -- // can use bitflag package to check lags. // See Flags type for standard values used in Ki Node -- // can be extended from FlagsN up to 64 bit capacity. // Note that we must always use atomic access as *some* things need to be atomic, // and with bits, that means that *all* access needs to be atomic, // as you cannot atomically update just a single bit. Flags() int64 // HasFlag checks if flag is set // using atomic, safe for concurrent access HasFlag(flag int) bool // HasAnyFlag checks if *any* of a set of flags is set (logical OR) // using atomic, safe for concurrent access HasAnyFlag(flag ...int) bool // HasAllFlags checks if *all* of a set of flags is set (logical AND) // using atomic, safe for concurrent access HasAllFlags(flag ...int) bool // SetFlag sets the given flag(s) // using atomic, safe for concurrent access SetFlag(flag ...int) // SetFlagState sets the given flag(s) to given state // using atomic, safe for concurrent access SetFlagState(on bool, flag ...int) // SetFlagMask sets the given flags as a mask // using atomic, safe for concurrent access SetFlagMask(mask int64) // ClearFlag clears the given flag(s) // using atomic, safe for concurrent access ClearFlag(flag ...int) // ClearFlagMask clears the given flags as a bitmask // using atomic, safe for concurrent access ClearFlagMask(mask int64) // 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 // 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. Prop(key string) (interface{}, bool) // KnownProp gets property value from key that is known to exist -- // returns nil if it actually doesn't -- less cumbersome for conversions. KnownProp(key string) interface{} // PropInherit gets property value from key with options for inheriting // property from parents and / or type-level properties. If inherit, then // checks all parents. If typ then checks property on type as well // (registered via KiT type registry). Returns false if not set anywhere. PropInherit(key string, inherit, typ bool) (interface{}, bool) // DeleteProp deletes property key on this node. 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 means set to // nil instead of making a new one -- most efficient if potentially no // properties will be set). 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 // PropTag returns the name to look for in type properties, for types // that are valid options for values that can be set in Props. For example // in GoGi, it is "style-props" which is then set for all types that can // be used in a style (colors, enum options, etc) PropTag() string // 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 children -- 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) // 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) // or // updt := n.UpdateStart() // defer n.UpdateEnd(updt) // ... code 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. Signal connections are NOT copied. 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() // WriteJSON writes the tree to an io.Writer, using MarshalJSON -- also // saves a critical starting record that allows file to be loaded de-novo // and recreate the proper root type for the tree. WriteJSON(writer io.Writer, indent bool) error // SaveJSON saves the tree to a JSON-encoded file, using WriteJSON. SaveJSON(filename string) error // ReadJSON reads and unmarshals tree starting at this node, from a // JSON-encoded byte stream via io.Reader. First element in the stream // must be of same type as this node -- see ReadNewJSON function to // construct a new tree. Uses ConfigureChildren to minimize changes from // current tree relative to loading one -- wraps UnmarshalJSON and calls // UnmarshalPost to recover pointers from paths. ReadJSON(reader io.Reader) error // OpenJSON opens file over this tree from a JSON-encoded file -- see // ReadJSON for details, and OpenNewJSON for opening an entirely new tree. OpenJSON(filename string) error // WriteXML writes the tree to an XML-encoded byte string over io.Writer // using MarshalXML. WriteXML(writer io.Writer, indent bool) error // ReadXML reads the tree from an XML-encoded byte string over io.Reader, calls // UnmarshalPost to recover pointers from paths. ReadXML(reader io.Reader) error // ParentAllChildren walks the tree down from current node and call // SetParent on all children -- needed after an Unmarshal. ParentAllChildren() // UnmarshalPost 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.
func NewOfType ¶
NewOfType makes a new Ki struct of given type -- must be a Ki type -- will return nil if not.
func OpenNewJSON ¶
OpenNewJSON opens a new Ki tree from a JSON-encoded file, using type information at start of file to create an object of the proper type
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 `` /* 219-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 */ Ths Ki `` /* 379-byte string literal not displayed */ // 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 GoGi 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) ClearFlagMask ¶
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) DeleteChildByName ¶
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) FuncDownBreadthFirst ¶
func (*Node) FuncDownDepthFirst ¶
func (*Node) FuncDownMeFirst ¶
func (*Node) FuncFields ¶
func (*Node) GetPtrPaths ¶
func (n *Node) GetPtrPaths()
func (*Node) GoFuncDown ¶
func (*Node) GoFuncFields ¶
func (*Node) HasAllFlags ¶
func (*Node) HasAnyFlag ¶
func (*Node) HasChildren ¶
func (*Node) IndexInParent ¶
func (*Node) InsertNewChild ¶
func (*Node) InsertNewChildUnique ¶
func (*Node) IsDestroyed ¶
func (*Node) IsUpdating ¶
func (*Node) IsValidIndex ¶
func (*Node) KnownChild ¶
func (*Node) NodeSignal ¶
func (*Node) OnlySelfUpdate ¶
func (*Node) ParentAllChildren ¶
func (n *Node) ParentAllChildren()
func (*Node) ParentLevel ¶
func (*Node) PathFromUnique ¶
func (*Node) PathUnique ¶
func (*Node) PropInherit ¶
func (*Node) Properties ¶
func (*Node) SetFieldDown ¶
func (*Node) SetFieldUp ¶
func (*Node) SetFlagMask ¶
func (*Node) SetFlagState ¶
func (*Node) SetNChildren ¶
func (*Node) SetNameRaw ¶
func (*Node) SetOnlySelfUpdate ¶
func (n *Node) SetOnlySelfUpdate()
func (*Node) SetPropChildren ¶
func (*Node) SetPropUpdate ¶
func (*Node) SetPtrsFmPaths ¶
func (n *Node) SetPtrsFmPaths()
func (*Node) SetUniqueName ¶
func (Node) String ¶
String implements the fmt.stringer interface -- returns the PathUnique of the node
func (*Node) UniqueName ¶
func (*Node) UniquifyNames ¶
func (n *Node) UniquifyNames()
UniquifyNames makes sure that the names are unique -- the "deluxe" version preserves the regular User-given name but is relatively expensive (creates a map), so is only used below a certain size (UniquifyPreserveNameLimit = 100), above which the index is appended, guaranteeing uniqueness at the cost of making paths longer and less user-friendly
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 (*NodeSignals) FromString ¶
func (i *NodeSignals) FromString(s string) error
func (NodeSignals) String ¶
func (i NodeSignals) String() string
type PropSlice ¶
type PropSlice []PropStruct
PropSlice is a slice of PropStruct, for when order is important within a subset of properties (maps do not retain order) -- can set the value of a property to a PropSlice to create an ordered list of property values.
func SliceProps ¶
SliceProps returns a value that contains a PropSlice, or nil and false if it doesn't exist or isn't a PropSlice
func SliceTypeProps ¶
SliceTypeProps returns a value that contains a PropSlice, or nil and false if it doesn't exist or isn't a PropSlice -- for TypeProps, uses locking
type PropStruct ¶
type PropStruct struct { Name string Value interface{} }
PropStruct is a struct of Name and Value, for use in a PropSlice to hold properties that require order information (maps do not retain any order)
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 and false if it doesn't exist or isn't a Props
func SubTypeProps ¶
SubTypeProps returns a value that contains another props, or nil and false if it doesn't exist or isn't a Props -- for TypeProps, uses locking
func (*Props) CopyFrom ¶
CopyFrom copies properties from source to receiver destination map. If copySubProps is true, then any values that are Props or PropSlice are copied too *dest can be nil, in which case it is created.
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 map[Ki]RecvFunc `view:"-" json:"-" xml:"-" desc:"map of receivers and their functions"` Mu sync.RWMutex `` /* 132-byte string literal not displayed */ }
Signal implements general signal passing between Ki objects, like Qt's Signal / Slot system.
This design pattern separates three different factors: * when to signal that something has happened * who should receive that signal * what should the receiver do in response to the signal
Keeping these three things entirely separate greatly simplifies the overall logic.
A receiver connects in advance to a given signal on a sender to receive its signals -- these connections are typically established in an initialization step. There can be multiple different signals on a given sender, and to make more efficient use of signal connections, the sender can also send an int64 signal value that further discriminates the nature of the event, as documented in the code associated with the sender (typically an enum is used). Furthermore, arbitrary data as an interface{} can be passed as well.
The Signal uses a map indexed by the receiver pointer to hold the connections -- this means that there can only be one such connection per receiver, and the order of signal emission to different receiveres will be random.
Typically an inline anonymous closure receiver function is used to keep all the relevant code in one place. Due to the typically long-standing nature of these connections, it is more efficient to avoid capturing external variables, and rely instead on appropriately interpreting the sent argument values. e.g.:
send := sender.EmbeddedStruct(KiT_SendType).(*SendType)
is guaranteed to result in a usable pointer to the sender of known type at least SendType, in a case where that sender might actually embed that SendType (otherwise if it is known to be of a given type, just directly converting as such is fine)
func (*Signal) Connect ¶
Connect attaches a new receiver and function to the signal -- only one such connection per receiver can be made, so any existing connection to that receiver will be overwritten
func (*Signal) ConnectOnly ¶
ConnectOnly first deletes any existing connections and then attaches a new receiver to the signal
func (*Signal) Disconnect ¶
Disconnect disconnects (deletes) the connection for a given receiver
func (*Signal) DisconnectAll ¶
func (s *Signal) DisconnectAll()
DisconnectAll removes all connections
func (*Signal) Emit ¶
Emit sends the signal across all the connections to the receivers -- sequentially but in random order due to the randomization of map iteration
func (*Signal) EmitFiltered ¶
func (s *Signal) EmitFiltered(sender Ki, sig int64, data interface{}, filtFun SignalFilterFunc)
EmitFiltered calls function on each potential receiver, and only sends signal if function returns true
func (*Signal) EmitGo ¶
EmitGo is the concurrent version of Emit -- sends the signal across all the connections to the receivers as separate goroutines
func (*Signal) EmitGoFiltered ¶
func (s *Signal) EmitGoFiltered(sender Ki, sig int64, data interface{}, filtFun SignalFilterFunc)
EmitGoFiltered is the concurrent version of EmitFiltered -- calls function on each potential receiver, and only sends signal if function returns true (filtering is sequential iteration over receivers)
type SignalFilterFunc ¶
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 is just a slice of ki elements: []Ki, providing methods for accessing elements in the slice, and 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. returns false if index is invalid.
func (*Slice) ElemByName ¶
ElemByName returns first element that has given name, false if not found. See IndexOf for info on startIdx.
func (*Slice) ElemByType ¶
ElemByType returns index of element that either is that type or embeds that type, false if not found. See IndexOf for info on startIdx.
func (*Slice) ElemByUniqueName ¶
ElemByUniqueName returns index of first element that has given unique name, false if not found. See IndexOf for info on startIdx.
func (*Slice) ElemFromEnd ¶
ElemFromEnd returns element at index from end of slice (0 = last element, 1 = 2nd to last, etc), returning false if invalid index
func (*Slice) IndexByFunc ¶
IndexByFunc finds index of item based on match function (which must return true for a find match, false for not). Returns false if not found. startIdx arg allows for optimized bidirectional find if you have an idea where it might be -- can be key speedup for large lists -- pass -1 to start in the middle (good default)
func (*Slice) IndexByName ¶
IndexByName returns index of first element that has given name, false if not found. See IndexOf for info on startIdx
func (*Slice) IndexByType ¶
IndexByType returns index of element that either is that type or embeds that type, false if not found. See IndexOf for info on startIdx.
func (*Slice) IndexByUniqueName ¶
IndexByUniqueName returns index of first element that has given unique name, false if not found. See IndexOf for info on startIdx.
func (*Slice) IndexOf ¶
IndexOf returns index of element in list, false if not there. startIdx arg allows for optimized bidirectional find if you have an idea where it might be -- can be key speedup for large lists -- pass -1 to start in the middle (good default).
func (*Slice) Insert ¶
Insert item at index -- does not do any parent updating etc -- use Ki/Node method unless you know what you are doing.
func (Slice) IsValidIndex ¶
IsValidIndex checks whether the given index is a valid index into slice, within range of 0..len-1.
func (*Slice) KnownElemByName ¶
KnownElemByName returns first element that has given name, without returning the bool check value -- when named element is known to exist, and will be directly converted to another type, so the multiple return values are cumbersome. nil is returned if it actually does not exist. See IndexOf for info on startIdx.
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) Move ¶
Move element from one position to another. Returns false if either index is invalid.
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 (sl *Slice) TypeAndNames() kit.TypeAndNameList
TypeAndNames returns a kit.TypeAndNameList of elements in the slice -- useful for Ki ConfigChildren.
func (*Slice) TypeAndUniqueNames ¶
func (sl *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 floats provides a standard Floater interface and all the std math functions defined on Floater types.
|
package floats provides a standard Floater interface and all the std math functions defined on Floater types. |
package ints provides a standard Inter interface and basic functions defined on Inter types that support core things like Max, Min, Abs.
|
package ints provides a standard Inter interface and basic functions defined on Inter types that support core things like Max, Min, Abs. |
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. |
package nptime provides a non-pointer version of the time.Time struct that does not have the location pointer information that time.Time has, which is more efficient from a memory management perspective, in cases where you have a lot of time values being kept: https://segment.com/blog/allocation-efficiency-in-high-performance-go-services/
|
package nptime provides a non-pointer version of the time.Time struct that does not have the location pointer information that time.Time has, which is more efficient from a memory management perspective, in cases where you have a lot of time values being kept: https://segment.com/blog/allocation-efficiency-in-high-performance-go-services/ |