type # ports
PortKind = enum
Bool, Int, Float, String
PortType = concept c
(c is bool or
c is int or
c is float or
c is string)
NumericPort = concept c
c is PortType
c is int or c is float
type # parameters
Parameter[T: PortType] = object
name: string
value: T
when T is NumericPort:
minVal, maxVal: T
proc newParameter[T: PortType](name: string, value: T): Parameter[T] =
result = Parameter(name:name, value:value)
proc newParameter[T: NumericPort](name: string, value, min, max: T): Parameter[T] =
result = Parameter(name:name, value:value, minVal:min, maxVal:max)
type
Inlet = ref object of RootObj
name*: string
module*: Module
outlet*: Outlet
case kind*: PortKind
of Bool:
boolParam*: bool
of Int:
intParam*: int
of Float:
floatParam*: float
of String:
stringParam*: string
Outlet = ref object of RootObj
name*: string
module*: Module
inlet*: Inlet
kind*: PortKind
Module = ref object of RootObj
size: utils.Size
nInputs, nOutputs: int
inlets: seq[Inlet]
outlets: seq[Outlet]
proc newModule(): Module =
result = new(Module)
result.nInputs = 0
result.nOutputs = 0
result.inlets = newSeq[Inlet]()
result.outlets = newSeq[Outlet]()
proc registerInlet(self: Module, name: string, value: PortType): Inlet =
result = new(Inlet)
result.name = name
result.module = self
when value is bool:
result.kind = Bool
result.boolParam = value
when value is int:
result.kind = Int
result.intParam = value
when value is float:
result.kind = Float
result.floatParam = value
when value is string:
result.kind = String
result.stringParam = value
self.inlets.add(result)
proc registerOutlet(self: Module, name: string, kind: PortKind): Outlet =
result = new(Outlet)
result.name = name
result.module = self
result.kind = kind
self.outlets.add(result)
proc `$` (self: Inlet): string =
case self.kind:
of Bool: return $(self.boolParam)
of Int: return $(self.intParam)
of Float: return $(self.floatParam)
of String: return $(self.stringParam)
proc connect(self: Outlet, target: Inlet): bool =
result = true
if self.kind != target.kind:
return false
self.inlet = target
target.outlet = self
var
boolOut = m.registerOutlet("toggle", Bool)
boolIn = m2.registerInlet("toggle", false)
floatIn = m2.registerInlet("freq", 440.0)
boolParam = newParameter("toggle", false)
floatParam = newParameter("freq", 440.0, 0.0, 20000.0)