Skip to content

Instantly share code, notes, and snippets.

@paniq
Last active August 29, 2015 14:06
Show Gist options
  • Select an option

  • Save paniq/9b25418647945f5777f7 to your computer and use it in GitHub Desktop.

Select an option

Save paniq/9b25418647945f5777f7 to your computer and use it in GitHub Desktop.
Noodles Model
=============
For my noodles graph programming I ended up rewriting the model.
I used to have several separate classes for each type: Type, Function, Call,
Argument, Result, Module, Scope, Link.
Then I realized I first need to have an extensible data descriptor model which
is general enough to permit building the above classes as specialized data - and
maybe more.
Therefore I folded all these classes back into one, the Node, which is
comparable to a DOMObject or a JSONObject, with a few changes
particular to the models application:
* the data is not edited in text form, so there is no "language" for this,
just an API for (visual) editing, whose behavior must be
configurable/hintable.
* the data structure can be split over several files, usually in a tree-like
dependency structure.
* references need to be loosely coupled and overridable.
* configurable directed links/edges between nodes are required.
* a metadata/type/inheritance system is selectively required.
All in all, the result is comparable to my earlier Datenwerk system, with a few
major simplifications and amendments.
Here's a description of the features of the model:
Tree Structure
--------------
As with DOM/JSON, the node is a tree node, in that it has one parent and a list
of children, and that it is deleted when its parent is deleted.
Parent-children relationships are implicit and hard-referenced, in that they can
be implemented with a native pointer. There are soft references which I'll talk
about later.
All root nodes of loaded documents are attached to a constant, unrenameable,
unreparentable and undeletable single root node named "#" that exists only
during runtime and must not be saved.
Data
----
A node can have a hard reference to a piece of data, which is neither typed
nor specified; in DOM terms, we would call this "CDATA". Typically, it can be
a number, a string or text block, a boolean, a table, an object, a sound buffer,
an image buffer, etc. The type of the data is opaque to the model and only
of relevance to particular applications. It is deleted with its owner.
Typically, a user would tag this node with a child node or metanode describing
its type, or the type would be implicitly inferrable from context;
visualizations would have specific requirements as to how to make this
data reflectable.
Names
-----
Each node carries a non-empty name, which is comparable to DOM id's, but the
node name is only unique within the scope, similar to files in directories.
To reference a node, one needs the full path originating from the "#" node, in
form of a list of node names;
A name can either be readable and user-defined, or a random id (e.g. uuid) in
cases where the node has no textual representation and requires no repairable
linkability. Random ids need to be prefixed with "#" to distinguish them from
readable names. This has an effect on visualization and soft-reference rules.
We call user-defined names explicit names and random ids implicit names.
Paths
-----
A path is what constitutes a so-called soft reference.
Path name resolution is *not* the same as in most file systems. The name
resolution for the first path element travels upwards, treating the tree
structure as scope, comparable to namespace resolution in C, C++, Java, Lua,
Javascript, and a few others. From then on it resolves down, descending
into child nodes.
Therefore, relative paths can directly start from the first commonly shared
parent node, if the parent is not immediate.
That means, if two nodes in upper scopes share the same name, the path
will always resolve to the node in the nearest scope.
Metanodes
---------
A node can use another node as a metanode, comparable to instances of classes
in C++, Python or Java; prototypes in Javascript; and metatables in Lua.
Metanodes are soft-referenced, which means they are referenced with a path,
in this case ideally a path with 1 to 2 elements.
If the path to a metanode can not be resolved, the node is marked as incomplete
by the editor, and will lose all of the styling and behavior imposed by the
metanode until the reference is restored. A metanode path can not contain
implicit names.
Aliases
-------
When a path is resolved down and the path iterator can not find a child node
with the given name, it will continue the search in the node's metanode
instead.
This way, one can import, alias or typedef nodes across widely separated
scopes.
Links
-----
This is the new bit that to my knowledge isn't a part of any mainstream object
descriptor format I know, and which adds noodle-ability to this model.
A node can be attached between two other nodes, called a source and a sink,
describing a directional graph, which effectively turns the node into an edge,
or link (not to be confused with HTML/XML links).
Source and sink are referenced weakly; neither needs to share the same scope
as the link.
Deletion rules are tricky: if either source or sink path can not be resolved,
and the first unresolvable path name is implicit, the node is deleted. If both
paths can not be resolved, explicit or not, the node is always deleted.
There are some more theoretical implications for links as nodes, for which
I know no immediate use cases:
Because links are nodes, a link can have child nodes and a metanode. A node
can also use a link as a metanode.
Because links are nodes, links can link links. This theoretically allows to
build link cascades and sierpinski triangles, but I don't know what those are
good for.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment