Pins
Pins are building blocks of Ports. Pins can be thought of gates of components as they are the most primitive type for data transfer inside and outside the components. There are two types of pins: Outpin and Inpin. The data flows from inside of the components to its outside through Outpin while data flow from outside of the components to its inside through Inpin.
Connection and Disconnection of Pins
In Jusdl, signal flow modelling approach is adopted(see Modeling and Simulation for more information on modelling approach in Jusdl). In this approach, the components drive each other and data flow is unidirectional. The unidirectional data movement is carried out though the Links. A Link connects Outpins to Inpins, and the data flow is from Outpin to Inpin.
As the data movement is from Outpin to Inpin, connection of an Inpin to an Outpin gives a MethodError.
For example, let us construct and Outpin and Inpins and connect the together.
julia> using Jusdl # hide
julia> op = Outpin()
Outpin(eltype:Float64, isbound:false)
julia> ip = Inpin()
Inpin(eltype:Float64, isbound:false)
julia> link = connect(op, ip)
Link(state:open, eltype:Float64, isreadable:false, iswritable:false)Note connect(op, ip) connects op and ip through a Link can return the constructed link. The connection of pins can be monitored.
julia> isconnected(op, ip)
trueThe constructed link can be accessed though the pins.
julia> op.links[1] === link
true
julia> ip.link === link
trueThe connected links Outpin and Inpin can be disconnected using disconnect function. When disconnected, the data transfer from the Outpin to Inpin is not possible.
Data Flow Through Pins
The data flow from an Outpin to an Inpin. However for data flow through a pin, a running task must be bound the channel of the link of the pin. See the example below.
julia> t = @async while true
take!(ip) === NaN && break
end
Task (runnable) @0x00007fa670d73a90As the task t is bound the channel of the link data can flow through op and ip.
julia> put!(op, 1.)
julia> put!(op, 2.)
julia> put!(op, 3.)Note that t is a taker job. As the taker job t takes data from op, we were able to put values into op. The converse is also possible.
julia> op2, ip2 = Outpin(), Inpin()
(Outpin(eltype:Float64, isbound:false), Inpin(eltype:Float64, isbound:false))
julia> link2 = connect(op2, ip2)
Link(state:open, eltype:Float64, isreadable:false, iswritable:false)
julia> t2 = @async for item in 1 : 5
put!(op2, item)
end
Task (runnable) @0x00007fa674c10760
julia> take!(ip2)
1.0
julia> take!(ip2)
2.0Note that in both of the cases given above the data flow is always from an Outpin to an Inpin.
It is not possible to take data from an Outpin and put into Inpin. Thus, take!(pin::Outpoin) and put!(pin::Inpin) throws a method error.
Full API
Jusdl.AbstractPin — TypeJusdl.Inpin — TypeInpin{T}()Constructs and InPut pin. The data flow from Inpin is inwards to the pin i.e., data is read from links of InPort.
Jusdl.Outpin — TypeOutpin{T}()Constructs and OutPut pin. The data flow from Outpin is outwards from the pin i.e., data is written from OutPort to its links.
Jusdl.connect — Methodconnect(outpin::Link, inpin::Link)Connects outpin to inpin. When connected, any element that is put into outpin is also put into inpin.
connect(outpin::AbstractVector{<:Link}, inpin::AbstractVector{<:Link})Connects each link in outpin to each link in inpin one by one. See also: disconnect
Example
julia> op, ip = Outpin(), Inpin();
julia> l = connect(op, ip)
Link(state:open, eltype:Float64, isreadable:false, iswritable:false)
julia> l in op.links
true
julia> ip.link === l
trueJusdl.disconnect — Methoddisconnect(link1::Link, link2::Link)Disconnects link1 and link2. The order of arguments is not important. See also: connect
Jusdl.isbound — Methodisbound(pin::AbstractPin)Returns true if outpin is bound to a Link.
Jusdl.isconnected — Methodisconnected(link1, link2)Returns true if link1 is connected to link2. The order of the arguments are not important. See also connect, disconnect
Jusdl.UnconnectedLinkError — TypeUnconnectedLinkError <: ExceptionException thrown when the links are not connected to each other.
Base.bind — Methodbind(link::Link, pin)Binds link to pin. When bound, data written into or read from pin is written into or read from link.
Base.eltype — Methodeltype(pin::AbstractPin)Returns element typef of pin.
Base.put! — Methodput!(pin::Outpin, val)Puts val to pin. val is put into the links of pin.
To take data from pin, a running task that puts data must be bound to link of pin.
Example
julia> op = Outpin();
julia> l = Link();
julia> bind(l, op);
julia> t = @async while true
val = take!(l)
val === NaN && break
println("Took " * string(val))
end;
julia> put!(op, 1.)
Took 1.0
julia> put!(op, 3.)
Took 3.0
julia> put!(op, NaN)Base.take! — Methodtake!(pin::Inpin)Takes data from pin. The data is taken from the links of pin.
To take data from pin, a running task that puts data must be bound to link of pin.
Example
julia> ip = Inpin();
julia> l = Link();
julia> bind(l, ip);
julia> t = @async for item in 1 : 5
put!(l, item)
end;
julia> take!(ip)
1.0
julia> take!(ip)
2.0