noflo
Version:
Flow-Based Programming environment for JavaScript
220 lines (184 loc) • 6.66 kB
text/coffeescript
# NoFlo - Flow-Based Programming for JavaScript
# (c) 2014-2017 Flowhub UG
# NoFlo may be freely distributed under the MIT license
#
# Input Port (inport) implementation for NoFlo components
BasePort = require './BasePort'
IP = require './IP'
platform = require './Platform'
class InPort extends BasePort
constructor: (options, process) ->
= null
if not process and typeof options is 'function'
process = options
options = {}
options ?= {}
options.buffered ?= false
options.control ?= false
options.triggering ?= true
if not process and options and options.process
process = options.process
delete options.process
if process
platform.deprecated 'InPort process callback is deprecated. Please use Process API or the InPort handle option'
unless typeof process is 'function'
throw new Error 'process must be a function'
= process
if options.handle
platform.deprecated 'InPort handle callback is deprecated. Please use Process API'
unless typeof options.handle is 'function'
throw new Error 'handle must be a function'
= options.handle
delete options.handle
super options
# Assign a delegate for retrieving data should this inPort
attachSocket: (socket, localId = null) ->
# have a default value.
if
if
socket.setDataDelegate => new IP 'data', .default
else
socket.setDataDelegate => .default
socket.on 'connect', =>
'connect', socket, localId
socket.on 'begingroup', (group) =>
'begingroup', group, localId
socket.on 'data', (data) =>
data
'data', data, localId
socket.on 'endgroup', (group) =>
'endgroup', group, localId
socket.on 'disconnect', =>
'disconnect', socket, localId
socket.on 'ip', (ip) =>
ip, localId
handleIP: (ip, id) ->
return if
return if .control and ip.type isnt 'data'
ip.owner =
ip.index = id if
buf = ip
buf.push ip
buf.shift() if .control and buf.length > 1
if
ip,
'ip', ip, id
handleSocketEvent: (event, payload, id) ->
# Handle buffering the old way
if
.push
event: event
payload: payload
id: id
# Notify receiver
if
event, id, if
event, id
else
event, if
event
return
if
if
event, payload, id,
else
event, payload,
# Emit port event
return event, payload, id if
event, payload
hasDefault: ->
return .default isnt undefined
prepareBuffer: ->
= []
= {} if
= {}
= if then {} else []
prepareBufferForIP: (ip) ->
if
if ip.scope?
[ip.scope] = [] unless ip.scope of
[ip.scope][ip.index] = [] unless ip.index of [ip.scope]
return [ip.scope][ip.index]
if ip.initial
[ip.index] = [] unless ip.index of
return [ip.index]
[ip.index] = [] unless ip.index of
return [ip.index]
if ip.scope?
[ip.scope] = [] unless ip.scope of
return [ip.scope]
if ip.initial
return
return
validateData: (data) ->
return unless .values
if .values.indexOf(data) is -1
throw new Error "Invalid data='#{data}' received, not in [#{@options.values}]"
# Returns the next packet in the (legacy) buffer
receive: ->
platform.deprecated 'InPort.receive is deprecated. Use InPort.get instead'
unless
throw new Error 'Receive is only possible on buffered ports'
.shift()
# Returns the number of data packets in a (legacy) buffered inport
contains: ->
platform.deprecated 'InPort.contains is deprecated. Use InPort.has instead'
unless
throw new Error 'Contains query is only possible on buffered ports'
.filter((packet) -> return true if packet.event is 'data').length
getBuffer: (scope, idx, initial = false) ->
if
if scope?
return undefined unless scope of
return undefined unless idx of [scope]
return [scope][idx]
if initial
return undefined unless idx of
return [idx]
return undefined unless idx of
return [idx]
if scope?
return undefined unless scope of
return [scope]
if initial
return
return
getFromBuffer: (scope, idx, initial = false) ->
buf = scope, idx, initial
return undefined unless buf?.length
return if .control then buf[buf.length - 1] else buf.shift()
# Fetches a packet from the port
get: (scope, idx) ->
res = scope, idx
return res if res isnt undefined
# Try to find an IIP instead
null, idx, true
hasIPinBuffer: (scope, idx, validate, initial = false) ->
buf = scope, idx, initial
return false unless buf?.length
for packet in buf
return true if validate packet
false
hasIIP: (idx, validate) ->
null, idx, validate, true
# Returns true if port contains packet(s) matching the validator
has: (scope, idx, validate) ->
unless
validate = idx
idx = null
return true if scope, idx, validate
return true if idx, validate
false
# Returns the number of data packets in an inport
length: (scope, idx) ->
buf = scope, idx
return 0 unless buf
return buf.length
# Tells if buffer has packets or not
ready: (scope, idx) ->
return > 0
# Clears inport buffers
clear: ->
module.exports = InPort