on 577fc17 help sign in
elk/libraries/Native/Ports.js
83 lines 2.6 kB history raw
1Elm.Native.Ports = {};
2Elm.Native.Ports.make = function(elm) {
3 elm.Native = elm.Native || {};
4 elm.Native.Ports = elm.Native.Ports || {};
5 if (elm.Native.Ports.values) return elm.Native.Ports.values;
7 var Signal = Elm.Signal.make(elm);
9 function incomingSignal(converter) {
10 converter.isSignal = true;
11 return converter;
12 }
14 function outgoingSignal(converter) {
15 return function(signal) {
16 var subscribers = []
17 function subscribe(handler) {
18 subscribers.push(handler);
19 }
20 function unsubscribe(handler) {
21 subscribers.pop(subscribers.indexOf(handler));
22 }
23 A2( Signal.lift, function(value) {
24 var val = converter(value);
25 var len = subscribers.length;
26 for (var i = 0; i < len; ++i) {
27 subscribers[i](val);
28 }
29 }, signal);
30 return { subscribe:subscribe, unsubscribe:unsubscribe };
31 }
32 }
34 function portIn(name, converter) {
35 var jsValue = elm.ports.incoming[name];
36 if (jsValue === undefined) {
37 throw new Error("Initialization Error: port '" + name +
38 "' was not given an input!");
39 }
40 elm.ports.uses[name] += 1;
41 try {
42 var elmValue = converter(jsValue);
43 } catch(e) {
44 throw new Error("Initialization Error on port '" + name + "': \n" + e.message);
45 }
47 // just return a static value if it is not a signal
48 if (!converter.isSignal) {
49 return elmValue;
50 }
52 // create a signal if necessary
53 var signal = Signal.constant(elmValue);
54 function send(jsValue) {
55 try {
56 var elmValue = converter(jsValue);
57 } catch(e) {
58 throw new Error("Error sending to port '" + name + "': \n" + e.message);
59 }
60 setTimeout(function() {
61 elm.notify(signal.id, elmValue);
62 }, 0);
63 }
64 elm.ports.outgoing[name] = { send:send };
65 return signal;
66 }
68 function portOut(name, converter, value) {
69 try {
70 elm.ports.outgoing[name] = converter(value);
71 } catch(e) {
72 throw new Error("Initialization Error on port '" + name + "': \n" + e.message);
73 }
74 return value;
75 }
77 return elm.Native.Ports.values = {
78 incomingSignal: incomingSignal,
79 outgoingSignal: outgoingSignal,
80 portOut: portOut,
81 portIn: portIn
82 };
83};