Code Monkey home page Code Monkey logo

ki's Issues

Getting started documentation?

There's a lot of documentation regarding advanced features, but it is a little ridiculous there is no documentation anywhere on how to even initialize the basic tree structure.

Maybe, I'm dumb, but I can't even build the tree let alone try the advanced signaling features.

get rid of Unique names and other complexity

Now that the relevant use-cases are more mature, maintaining the parallel construct of unique names separate from regular names seems like the wrong solution -- too complex and not needed for vast majority of cases.

by far most cases are already unique, generated by program.

not all cases depend on uniqueness.

simpler to just add a uniqueness checker, and uniquifier routine, to be used as needed.

The case where you need a "plain" name that is repeated and a unique name separately is very rare and mainly about gui interacting with the tree -- not a typical case.

This then removes difference between *Fast routines, etc

Also, remove some of the lesser-used routines -- e.g., Type(), TypeEmbeds() can be separate functions not interfaces.

Ki fields of type ki.Ki are not handled correctly

Struct Ki fields that implement ki.Ki are treated as pseudo-children of nodes, but fields that are actually stored as type ki.Ki are not given the same treatment. This behavior should be made consistent or clearly documented with reasoning.

add a version of config children that supports BOTH unique names and regular names

simplest soln would be to have a delimiter (e.g., ':' ) and put UniqueName:Name into name field of TypeNameList, and then use that.

In giv.TreeView, under GoPi, we're swapping two nodes that have the same regular names -- so treeview doesn't update. in general, tree view should be fully robust with unique names, but it should display regular names...

Remove support for automatic Ki field children

A fix for #16 is to just remove all KiField support entirely.

KiField exists to support multiple different "families" (step children), which is really useful for the giv.TreeView which has "proper" children that are the other tree nodes (which thus remain in 1-to-1 correspondence with the tree structure being represented), but it also has widget "Parts" children. Putting the Parts in a separate container solves this problem. It is also conceivable that other container-like widgets (e.g., Frames) might need some part elements too.

To be consistent, all GoGi Widget parts are managed via the Parts KiField. There is a lot of special code there for managing and styling the parts, etc, and it does seem to make sense overall to have these separated out from regular Children, which are generally supposed to be more generic & flexibly constructed, and could go down indefinitely deep etc.

The only places that KiFields are used:

  • FuncDown calls in node.go -- it is fine for the node itself to call FuncDown on its Parts or other such KiFields manually, in the relevant function. This way it is explicit, and can be omitted where irrelevant, etc. The cost is an additional manual function call..

  • FindPath where the path element has a '.' -- we can just add a FindPathField interface method that gets called in this case, so it is up to the type to deal with it.

  • InitNode in admin.go -- this can be replaced with manual calls in OnInit or OnAdd, happening at the right time and place instead of automatically.

I'm pretty sure Parts is the main use-case for this, although a few other Ki-type fields were probably relying on the automatic InitNode calls.

Overall, this will be much simpler and cleaner, and the vast majority of cases don't need the KiFields so it just makes sense. There may be something overlooked here but there is only one way to find out..

Signal type: int64 or uint64 or Enum?

First, NodeSignals is not a bitflag -- just a regular enum. Fixes several tests.

Currently, the RecvFunc specifies sig int64. Should we change that to enums.Enum so it automagically works for any kind of enum, without having to do the type conversion that all such code is currently doing?

The cost of doing so is that an interface is always a pointer, so we're changing from a simple basic data value to a pointer everywhere. This could put more of a drag on the GC.

I don't think that cost is worth it for a single line conversion -- it is also useful to get the specific enum instead of a generic Enum, so you have visibility in IDE about possible values etc.

So, bottom line: keep it as it is?

figure out how to auto-call UnmarshalPost after UnmarshalJSON

right now, if Ki trees are embedded in other objects and loaded from JSON, you have to manually call UnmarshalPost, because it is only the separate ReadJSON that calls unmarshal.

Issue is that json.Unmarshall on the obj will call its UnmarshalJSON method if we define it there, so perhaps we need to have it trigger on some other element in Ki somehow that then does it?

embed generator and new type registry

From #18

make a new embed repo that has embedgen generator to automatically create a map from type name to any interface (with option to specify the base interface type name -- e.g., ki.Ki) for all embedded struct types -- uses that to impl func Embed(tpNm string) (any, bool) method for type, and defines Embedder interface with this method. This will be significantly faster than the current reflection-based ki.Embed method.

Two considerations:

  • We want to avoid using strings (error-prone, relatively expensive as a map key) for accessing embedded types.
  • We might still want to be able to get a type from a string name, for saving / loading arbitrary Ki trees, where the type name for every struct is saved and then used at load time to create the objects.

Plan: make a simple lightweight ki-specific Type and TypeRegistry, with unique uint64 handles for key types, which are used as map keys for the embed function. This means that Embed must be specific to Ki and not a general-purpose tool.

in goki/ki repo, in the one top-level 'ki' package #18:

var (
    // TypeIDCounter is atomically incremented for assigning new Type.ID numbers
    TypeIDCounter uint64

    // TypeRegistry provides a way to look up types from string short names (package.Type, e.g., gi.Button)
    TypeRegistry = map[string]*Type{}
)

// Type represents a Ki type
type Type struct {
    Name string `desc:"type name, using the short form (e.g., gi.Button)"`
    ID uint64 `desc:"unique type ID number -- use as a key handle for embed map"`
    Instance Ki `desc:"instance of the Ki type -- call Clone() on this to make a new token"`
}

// NewType creates a new Type for given instance.  This call is auto-generated for each Ki type.
func NewType(nm string, inst Ki) *Type {
    inst.InitName(inst, nm)
    tp := &Type{Name: nm, Instance: inst}
    tp.ID = atomic.AddUint64(&TypeIDCounter, 1)
    TypeRegistry[nm] = tp
    return tp
}

// example auto-gen code for each Ki type:

// var TypeButton = ki.NewType("gi.Button", &Button{})
// func NewButton(parent ki.Ki, name string) *Button {
//    if parent == nil {
//        b := &Button{}; b.InitName(b, name); return b
//    } else {
//        return parent.AddNewChild(TypeButton, name).(*Button)
//    }
// }
// func (k *Button) NewInstance() ki.Ki { b := &Button{}; b.InitNode(b); return b }
// var ButtonEmbeds map[uint64]ki.Ki
// func (k *Button) Embed(tp *ki.Type) ki.Ki {
//    if ButtonEmbeds == nil {
//        ButtonEmbeds = make(map[uint64]ki.Ki)
//        ButtonEmbeds[TypeWidget.ID] = &k.Widget // note: must do delayed construction of global embeds var to get valid IDs
//        ...
//    }
//    return ButtonEmbeds[tp.ID] // will be nil if not there -- for known embeds it is *much* easier to be able to use return directly in inline expressions, so not using the additional bool here
// }

// NewInstance returns a new instance of given type
// Note: otherwise impossible to generate new instance generically, unless using reflection
func (tp *Type) NewInstance() Ki {
    return tp.Instance.NewInstance()
}

// ReflectType returns the reflect type of a given Ki Type
func (tp *Type) ReflectType() reflect.Type {
    return reflect.TypeOf(tp.Instance).Elem()
}

// TypeByName returns a ki Type by name (package.Type, e,g. gi.Button), or error if not found
func TypeByName(nm string) (*Type, error) {
   tp, ok := TypeRegistry[nm]
   if !ok {
      return nil, fmt.Errorf("Ki Type: %s not found", nm)
    }
    return tp, nil
}

// note:  replace all instances of reflect.Type in ki code with this ki.Type

Use Enumer and BitEnumer interfaces instead of enums type registry?

Basic Enumer would just require FromString method -- very easy. Add a kit.SetEnumFromString that just checks for the interface and calls it directly. Much simpler than what is there now.

BitEnumer FromStringBits would call a kit.BitFlagsFromString method -- it just parses the | and uses FromString.

The main missing part here would be the alt strings -- need to see exactly what this is, but it may just be lower case versions?

Support "derived" enums

It is easy to add a function that grabs all the enum vals from a parent type -- may have issues with ordering but hopefully included packages are initialized before includers?

but the problem becomes making the gui aware of which derived type is relevant for a given class -- can set this in class type properties presumably. key test case is the ki.Flags field.

Remove Signals mechanism, replace with On* methods

With the recent rewrite of GoGi, we are no longer using any of the NodeSignals!

Furthermore, having the Signal system in this base Ki drives the need to make it fully general-purpose, which means it is not great for any specific purpose: too many different args, not tailored for what is needed.

Thus, we should add a more specifically tailored signaling system to GoGi for sending Button etc signals, and also add "On*" hooks in Ki for where the current signals are being sent, so if someone wants to send signals at that point, they can easily do so.

Only ki should remain in ki repo for v2

with the new generator strategy in v2 vs. reflection in v1, and separate enums, goki tools etc repos, can we get rid of all the rest of what is in ki, putting whatever is still needed in separate repos? Thus, ki could have just the Ki & Node code right in the top level and be much simpler looking.

  • kigen->ordmap can be put in separate ordmap repo
  • SetRobust and all the other reflect stuff used in giv value views (a lot of kit) could be put in a separate repo with a clever name about being reflect helpers etc. how much of this reflection can be replaced with generic functions now?
  • ints, etc are no longer needed post-generics / can be replaced appropriately.

to start down this path, only put ki in v2 under goki.dev, and use existing github for all the v1 stuff until we manage to sort it all out..

Removing Type Props support. Should we remove Props entirely?

There are a few places in the gi code where ki.TypeProps (renamed to CheckTypeProps) was being used as an arg to the PropInherit method, but no evidence that it was actually being set in any type. In principle, all such type props should be set through comment directives now, using gti, so I'm removing support for this option.

This is also consistent with the removal of prop-based styling in gi, such that props are not systematically used there.

This raises the question: should we support Props at all?

Minimalism says: remove!

But.. some kind of flexible meta-data is often useful, and the cost is minimal: a nil map pointer for everyone who doesn't use it, and a few additional methods.

Should we rename it to MetaData instead of Props?

Ideas for new "Func" methods and signatures

Signatures

  • First, data and starting level are definitely NOT needed.

  • also, if you need level, then you should store that on your node. it is not worth burdening everyone with this extra arg that is almost always ignored. Will retain a version of FuncDownMeFirst that keeps the level and can use that also for setting level.

  • Getting rid of Func as a type. Instead just func(k Ki) bool

Names

Wikipedia identifies 3 depth-first orders:

  • Pre-order = FuncDownMeFirst
  • Post-order = FuncDownMeLast
  • In-order -- not relevant to non-binary tree..

Walk is a generally good term for traversal. Here are concise versions:

  • WalkPre
  • WalkPost
  • WalkBreadth
  • WalkPreLevel -- version that has the level
  • WalkUp is the up-going one

Incorrect initialization order of Ki fields

Currently, any Ki fields for a node are initialized and inserted before the node itself is inserted. For example, suppose you have a node called A. You initialize node A with InitNode and then add a child, node B, who has a field node C (such that the full path of node C should be A/B.C). AddNewChild calls InitNode on node B, which calls InitNode and SetParent on node C as part of the Ki fields logic. However, SetParent has not yet been called on node B, as the initialization of Ki fields (such as node C) happens before the setting of the parent. Therefore, OnAdd is called for node C before it is called for node B, despite node B being higher in the tree. This means that, despite being in OnAdd, in which you expect to have your parents defined, node C has a parent without a name or parents. Node C has no way to know what its grandparents or other extended parents are, as the tree ends at node B. Furthermore, calling Path on node C results in /.C, when it should result in A/B.C.

missing dirs.AllFiles() and dirs.HasFile()

I am not able to compile examples of goki and after same searching I have found that dirs.AllFiles() and dirs.HasFile() are missing in my:

~/go/pkg/mod/github.com/goki/[email protected]/dirs/dirs.go

in ~/go/src/github.com/goki/ki/dirs/dirs.go both functions are available.

I am just learning the go language so I dont know what happend.

Even if I delete package (and files from pkg/mod directory) and install it again with go get ...it comes to same state.

What I am doing wrong please?

Here is example code:
`package main

import (
"fmt"

"github.com/goki/ki/dirs"

)

func main() {

fmt.Println(dirs.GoSrcDir("."))

// does not work with:
// undefined: dirs.AllFiles [15,13]
// err, xs := dirs.AllFiles("")

}`

Thank you.
Petr

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.