model

package
v0.0.2-0...-a5fe278 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2021 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package model has the model types: graph, channel, node...

Index

Constants

This section is empty.

Variables

View Source
var (
	// PartTypes translates part type strings into useful information.
	PartTypes = make(map[string]*PartType)

	// PartTypesByCategory has an extra layer of map for grouping by category.
	PartTypesByCategory = make(map[string]map[string]*PartType)
)
View Source
var TestGraphs = map[string]*Graph{
	"non-command": {
		FilePath:    "filepath",
		URLPath:     "urlpath",
		Name:        "non-command",
		PackagePath: "package/path",
		IsCommand:   false,
	},
	"command": {
		FilePath:    "filepath",
		URLPath:     "urlpath",
		Name:        "command",
		PackagePath: "package/path",
		IsCommand:   true,
	},
	"has a node and a channel": {
		FilePath:    "filepath",
		URLPath:     "urlpath",
		Name:        "has a node and a channel",
		PackagePath: "package/path",
		IsCommand:   false,
		Nodes: map[string]*Node{
			"foo": {
				Part: &FakePart{nil, "", "", "", pin.Map{
					"output": {
						Name:      "output",
						Type:      "int",
						Direction: pin.Output,
					},
				},
				},
				Name:         "foo",
				Enabled:      true,
				Multiplicity: "1",
				Wait:         true,
				Connections: map[string]string{
					"output": "bar",
				},
			},
		},
		Channels: map[string]*Channel{
			"bar": {
				Name:     "bar",
				Type:     source.MustNewType("", "int"),
				Capacity: 0,
			},
		},
	},
	"has a disabled node": {
		FilePath:    "filepath",
		URLPath:     "urlpath",
		Name:        "has a disabled node",
		PackagePath: "package/path",
		IsCommand:   false,
		Nodes: map[string]*Node{
			"foo": {
				Part: &FakePart{nil, "", "", "", pin.Map{
					"output": {
						Name:      "output",
						Type:      "int",
						Direction: pin.Output,
					},
				},
				},
				Name:         "foo",
				Enabled:      false,
				Multiplicity: "1",
				Wait:         false,
				Connections: map[string]string{
					"output": "nil",
				},
			},
		},
	},
	"has a node with multiplicity > 1": {
		FilePath:    "filepath",
		URLPath:     "urlpath",
		Name:        "has a node with multiplicity > 1",
		PackagePath: "package/path",
		IsCommand:   false,
		Nodes: map[string]*Node{
			"foo": {
				Part: &FakePart{nil, "", "", "", pin.Map{
					"output": {
						Name:      "output",
						Type:      "int",
						Direction: pin.Output,
					},
				}},
				Name:         "foo",
				Enabled:      true,
				Multiplicity: "50",
				Wait:         true,
				Connections: map[string]string{
					"output": "nil",
				},
			},
		},
	},
	"has a node that isn't waited for": {
		FilePath:    "filepath",
		URLPath:     "urlpath",
		Name:        "has a node that isn't waited for",
		PackagePath: "package/path",
		IsCommand:   false,
		Nodes: map[string]*Node{
			"foo": {
				Part: &FakePart{nil, "", "", "", pin.Map{
					"output": {
						Name:      "output",
						Type:      "int",
						Direction: pin.Output,
					},
				}},
				Name:         "foo",
				Enabled:      true,
				Multiplicity: "1",
				Wait:         false,
				Connections: map[string]string{
					"output": "nil",
				},
			},
		},
	},
}

TestGraphs contains graphs that are useful for testing.

Functions

func Mangle

func Mangle(name string) string

Mangle turns an arbitrary name into a similar-looking identifier.

func RegisterPartType

func RegisterPartType(name, category string, pt *PartType)

RegisterPartType adds a part type to the PartTypes map. This should be used by part types during init.

Types

type Channel

type Channel struct {
	Name     string       `json:"-"`
	Type     *source.Type `json:"-"`
	Capacity int          `json:"cap"`

	// Cache of pins this channel is attached to
	Pins map[NodePin]struct{} `json:"-"`
}

Channel represents connections between pins.

func (*Channel) AddPin

func (c *Channel) AddPin(node, pin string)

AddPin is sugar for `c.Pins[NodePin{Node: node, Pin: pin}] = struct{}{}`. It doesn't update the node.

func (*Channel) HasPin

func (c *Channel) HasPin(node, pin string) bool

HasPin is sugar for `_, found := c.Pins[NodePin{Node: node, Pin: pin}]; found`.

func (*Channel) RemovePin

func (c *Channel) RemovePin(node, pin string)

RemovePin is sugar for `delete(c.Pins, NodePin{Node: node, Pin: pin})`. It doesn't update the node. If the channel now has fewer than 2 pins, it can be deleted, but RemovePin does not do that.

type FakePart

type FakePart struct {
	Impts []string `json:"imports"`
	Head  string   `json:"head"`
	Body  string   `json:"body"`
	Tail  string   `json:"tail"`
	Pns   pin.Map  `json:"pins"`
}

FakePart fakes a part type for testing purposes.

func (*FakePart) Clone

func (f *FakePart) Clone() Part

Clone returns a shallow copy.

func (*FakePart) Impl

func (f *FakePart) Impl(*Node) PartImpl

Impl returns Head, Body, Tail.

func (*FakePart) Pins

func (f *FakePart) Pins() pin.Map

Pins returns Pns.

func (*FakePart) TypeKey

func (f *FakePart) TypeKey() string

TypeKey returns "Fake".

type Graph

type Graph struct {
	FilePath    string              `json:"-"` // path to the JSON source
	URLPath     string              `json:"-"` // path in the URL
	Name        string              `json:"name"`
	PackagePath string              `json:"package_path"`
	IsCommand   bool                `json:"is_command"`
	Nodes       map[string]*Node    `json:"nodes"`    // name -> node
	Channels    map[string]*Channel `json:"channels"` // name -> channel
	// contains filtered or unexported fields
}

Graph represents a package / program / collection of nodes and channels.

func LoadJSON

func LoadJSON(r io.Reader, filePath, urlPath string) (*Graph, error)

LoadJSON loads a JSON-encoded Graph from an io.Reader.

func NewGraph

func NewGraph(filePath, urlPath, pkgPath string) *Graph

NewGraph returns a new empty graph associated with a file path.

func (*Graph) AllImports

func (g *Graph) AllImports() []string

AllImports combines all desired imports into one slice. It doesn't fix conflicting names, but dedupes any whole lines, trims whitespace and removes blank lines. go/format will put them in sorted order later. TODO: Put nodes in separate files to solve all import issues.

func (*Graph) Check

func (g *Graph) Check() error

Check checks over the graph for any errors.

func (*Graph) DeleteChannel

func (g *Graph) DeleteChannel(ch *Channel)

DeleteChannel cleans up any connections and then deletes a channel.

func (*Graph) DeleteNode

func (g *Graph) DeleteNode(n *Node, cleanupChans bool)

DeleteNode cleans up any connections and then deletes a node. If cleanupChans is set, it then deletes any channels which have less than 2 pins left as a result of deleting the node.

func (*Graph) Go

func (g *Graph) Go() (string, error)

Go outputs the Go language view of the graph.

func (*Graph) InferTypes

func (g *Graph) InferTypes() error

InferTypes resolves the types of channels and generic pins.

func (*Graph) Inits

func (g *Graph) Inits() map[string]string

Inits returns a map of part type keys to init sections for those parts that need it.

func (*Graph) JSON

func (g *Graph) JSON() (string, error)

JSON returns the JSON view of the graph.

func (*Graph) PackageName

func (g *Graph) PackageName() string

PackageName extracts the name of the package from the package path ("full" package name).

func (*Graph) RawGo

func (g *Graph) RawGo() (string, error)

RawGo outputs the unformatted Go language view of the graph.

func (*Graph) RefreshChannelsPins

func (g *Graph) RefreshChannelsPins()

RefreshChannelsPins refreshes the Pins cache of all channels. Use this when node names or pin definitions might have changed.

func (*Graph) RenameNode

func (g *Graph) RenameNode(n *Node, newName string)

RenameNode renames the node and fixes up references.

func (*Graph) WriteGoTo

func (g *Graph) WriteGoTo(w io.Writer) error

WriteGoTo writes the Go language view of the graph to the io.Writer.

func (*Graph) WriteJSONTo

func (g *Graph) WriteJSONTo(w io.Writer) error

WriteJSONTo writes nicely-formatted JSON to the given Writer.

func (*Graph) WriteRawGoTo

func (g *Graph) WriteRawGoTo(w io.Writer) error

WriteRawGoTo writes the Go language view of the graph to the io.Writer, without gofmt-ing.

type Node

type Node struct {
	Part         Part
	Name         string
	Comment      string
	Enabled      bool
	Multiplicity string
	Wait         bool
	X, Y         float64
	Connections  map[string]string // Pin name -> channel name
	Impl         PartImpl          // Final implementation after type inference

	TypeParams map[string]*source.Type // Local type parameter -> stringy type
	PinTypes   map[string]*source.Type // Pin name -> inferred type of pin
}

Node models a goroutine. This is the "real" model type for nodes. It can be marshalled and unmarshalled to JSON sensibly.

func (*Node) Copy

func (n *Node) Copy() *Node

Copy returns a copy of this node, but with an empty name, nil connections, and a clone of the Part.

func (*Node) ExpandedMult

func (n *Node) ExpandedMult() string

ExpandedMult expands Multiplicity into an expression that uses calls runtime.NumCPU.

func (*Node) Identifier

func (n *Node) Identifier() string

Identifier turns the name into a similar-looking identifier.

func (*Node) MarshalJSON

func (n *Node) MarshalJSON() ([]byte, error)

MarshalJSON encodes the node and part as JSON.

func (*Node) PinFullTypes

func (n *Node) PinFullTypes() map[string]string

PinFullTypes is a map from pin names to full resolved types: pinName <-chan someType or pinName chan<- someType. Requires InferTypes to have been called.

func (*Node) RefreshConnections

func (n *Node) RefreshConnections()

RefreshConnections filters n.Connections to ensure only pins defined by the part are in the map, and any new ones are mapped to "nil".

func (*Node) RefreshImpl

func (n *Node) RefreshImpl()

RefreshImpl refreshes Impl from the Part.

func (*Node) UnmarshalJSON

func (n *Node) UnmarshalJSON(j []byte) error

UnmarshalJSON decodes the node and part as JSON.

func (*Node) UsesInstanceNum

func (n *Node) UsesInstanceNum() bool

UsesInstanceNum returns true if the body uses the "instanceNum"

func (*Node) UsesMultiplicity

func (n *Node) UsesMultiplicity() bool

UsesMultiplicity returns true if multiplicity != 1 or the head/body/tail use the multiplicity variable.

type NodePin

type NodePin struct{ Node, Pin string }

NodePin is a simple tuple of node name, pin name.

func (NodePin) String

func (np NodePin) String() string

type Part

type Part interface {
	// Clone returns a copy of this part.
	Clone() Part

	// Impl returns Go source code implementing the part.
	//
	// It is called with a pointer to the node that itself has a pointer back to
	// this part, so the part can vary its implementation based on the node
	// properties. Do not modify the node. Parts are expected to use the name,
	// multiplicity, and type parameters from the node responsibly. Node names
	// are generally used for exporting Prometheus metrics, and multiplicity
	// can be used to add or eliminate locking around shared data structures.
	//
	// The imports are combined with other imports needed for the file.
	//
	// For the node itself, the head, body, and tail are used.
	// The head is executed, then the body is executed (# Multiplicity
	// instances of the body concurrently), then the tail (once the body/bodies
	// are finished).
	//
	// This allows cleanly closing channels for nodes with Multiplicity > 1.
	// The tail is deferred so that the body can use "return" and it is still
	// executed.
	//
	// The types map indicates inferred types which the part is responsible
	// for interpolating into the output as needed.
	Impl(n *Node) PartImpl

	// Pins returns any pins - "channel arguments" - to the part.
	// inputs and outputs map argument names to types (the "<-chan" /
	// "chan<-" part of the type is implied). The map must be keyed
	// by name.
	Pins() pin.Map

	// TypeKey returns the "type" of part.
	TypeKey() string
}

Part abstracts the implementation of a node. Concrete implementations should be able to be marshalled to and unmarshalled from JSON sensibly.

type PartImpl

type PartImpl struct {
	Imports          []string
	Head, Body, Tail string
	NeedsInit        bool // true if this node needs infrastructure set up by PartType.Init
}

PartImpl wraps the mostly-formed Go source code that can be inserted into the template.

type PartJSON

type PartJSON struct {
	Part json.RawMessage `json:"part,omitempty"`
	Type string          `json:"part_type,omitempty"`
}

PartJSON is a convenient JSON-plus-type-key type.

func MarshalPart

func MarshalPart(p Part) (*PartJSON, error)

MarshalPart turns a rich Part into JSON-with-type.

func (*PartJSON) Unmarshal

func (pj *PartJSON) Unmarshal() (Part, error)

Unmarshal converts the JSON into a Part, via the type key.

type PartPanel

type PartPanel struct {
	Name   string
	Editor template.HTML
}

PartPanel describes one panel of the editor interface specific to a part type.

type PartType

type PartType struct {
	// New must return a new instance of this particular part, preferably
	// with good default settings.
	New func() Part

	// Init will contain package level var and init blocks specific to this
	// type. It is included only once per part type for nodes where the part
	// impl has NeedsInit = true.
	Init string

	// Panels defines the UI for controlling the settings of the part.
	Panels []PartPanel
}

PartType has metadata common to a type of part, and is a part factory for the type.

type TypeIncompatibilityError

type TypeIncompatibilityError struct {
	Summary string
	Source  error
	Channel *Channel
	Pin     NodePin
}

TypeIncompatibilityError is used when types mismatch during inference. TODO(josh): Make this useful to feed into the error panel.

func (*TypeIncompatibilityError) Error

func (e *TypeIncompatibilityError) Error() string

Directories

Path Synopsis
Package pin has types for describing pins (connection points).
Package pin has types for describing pins (connection points).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL