83 lines
2.6 KiB
JavaScript
83 lines
2.6 KiB
JavaScript
Elm.Native.Ports = {};
|
|
Elm.Native.Ports.make = function(elm) {
|
|
elm.Native = elm.Native || {};
|
|
elm.Native.Ports = elm.Native.Ports || {};
|
|
if (elm.Native.Ports.values) return elm.Native.Ports.values;
|
|
|
|
var Signal = Elm.Signal.make(elm);
|
|
|
|
function incomingSignal(converter) {
|
|
converter.isSignal = true;
|
|
return converter;
|
|
}
|
|
|
|
function outgoingSignal(converter) {
|
|
return function(signal) {
|
|
var subscribers = []
|
|
function subscribe(handler) {
|
|
subscribers.push(handler);
|
|
}
|
|
function unsubscribe(handler) {
|
|
subscribers.pop(subscribers.indexOf(handler));
|
|
}
|
|
A2( Signal.lift, function(value) {
|
|
var val = converter(value);
|
|
var len = subscribers.length;
|
|
for (var i = 0; i < len; ++i) {
|
|
subscribers[i](val);
|
|
}
|
|
}, signal);
|
|
return { subscribe:subscribe, unsubscribe:unsubscribe };
|
|
}
|
|
}
|
|
|
|
function portIn(name, converter) {
|
|
var jsValue = elm.ports.incoming[name];
|
|
if (jsValue === undefined) {
|
|
throw new Error("Initialization Error: port '" + name +
|
|
"' was not given an input!");
|
|
}
|
|
elm.ports.uses[name] += 1;
|
|
try {
|
|
var elmValue = converter(jsValue);
|
|
} catch(e) {
|
|
throw new Error("Initialization Error on port '" + name + "': \n" + e.message);
|
|
}
|
|
|
|
// just return a static value if it is not a signal
|
|
if (!converter.isSignal) {
|
|
return elmValue;
|
|
}
|
|
|
|
// create a signal if necessary
|
|
var signal = Signal.constant(elmValue);
|
|
function send(jsValue) {
|
|
try {
|
|
var elmValue = converter(jsValue);
|
|
} catch(e) {
|
|
throw new Error("Error sending to port '" + name + "': \n" + e.message);
|
|
}
|
|
setTimeout(function() {
|
|
elm.notify(signal.id, elmValue);
|
|
}, 0);
|
|
}
|
|
elm.ports.outgoing[name] = { send:send };
|
|
return signal;
|
|
}
|
|
|
|
function portOut(name, converter, value) {
|
|
try {
|
|
elm.ports.outgoing[name] = converter(value);
|
|
} catch(e) {
|
|
throw new Error("Initialization Error on port '" + name + "': \n" + e.message);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
return elm.Native.Ports.values = {
|
|
incomingSignal: incomingSignal,
|
|
outgoingSignal: outgoingSignal,
|
|
portOut: portOut,
|
|
portIn: portIn
|
|
};
|
|
};
|