flok 0.0.102 → 0.0.103

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/app/drivers/chrome/pipe.rb +66 -51
  4. data/app/drivers/chrome/src/controller.js +20 -1
  5. data/app/drivers/chrome/src/hook.js +10 -12
  6. data/app/drivers/chrome/src/net.js +4 -4
  7. data/app/drivers/chrome/src/sockio.js +2 -2
  8. data/app/drivers/chrome/src/ui.js +18 -15
  9. data/app/kern/mod/event.js +3 -1
  10. data/app/kern/mod/hook.js +13 -1
  11. data/app/kern/mod/ui.js +71 -0
  12. data/docs/controllers.md +14 -0
  13. data/docs/dispatch.md +4 -2
  14. data/docs/kernel_api.md +1 -0
  15. data/docs/kernel_handbook/find_view.md +34 -0
  16. data/docs/kernel_handbook/hooks.md +12 -1
  17. data/docs/mod/controller.md +5 -2
  18. data/docs/mod/hook.md +4 -3
  19. data/docs/mod/persist.md +1 -1
  20. data/docs/mod/ui.md +1 -0
  21. data/docs/user_handbook/hooks.md +38 -14
  22. data/flok.gemspec +2 -0
  23. data/lib/flok/user_compiler.rb +18 -2
  24. data/lib/flok/user_compiler_templates/ctable.js.erb +1 -0
  25. data/lib/flok/user_hook_generators/goto.rb +32 -4
  26. data/lib/flok/version.rb +1 -1
  27. data/spec/env/iface.rb +38 -0
  28. data/spec/env/kern.rb +4 -0
  29. data/spec/iface/driver/controller_spec.rb +25 -6
  30. data/spec/iface/driver/dispatch_spec.rb +7 -0
  31. data/spec/iface/driver/hook_spec.rb +83 -7
  32. data/spec/iface/driver/net_spec.rb +50 -41
  33. data/spec/iface/driver/persist_spec.rb +47 -4
  34. data/spec/iface/driver/ping_spec.rb +1 -1
  35. data/spec/iface/driver/rtc_spec.rb +2 -2
  36. data/spec/iface/driver/sockio_spec.rb +4 -3
  37. data/spec/iface/driver/timer_spec.rb +20 -0
  38. data/spec/iface/driver/ui_spec.rb +27 -4
  39. data/spec/kern/assets/find_view/controller0.rb +24 -0
  40. data/spec/kern/assets/find_view/controller1.rb +35 -0
  41. data/spec/kern/assets/find_view/controller1a.rb +37 -0
  42. data/spec/kern/assets/find_view/controller2.rb +23 -0
  43. data/spec/kern/assets/find_view/controller3.rb +38 -0
  44. data/spec/kern/assets/find_view/controller4.rb +38 -0
  45. data/spec/kern/assets/find_view/controller5.rb +52 -0
  46. data/spec/kern/assets/find_view/controller6.rb +37 -0
  47. data/spec/kern/assets/find_view/controller7.rb +37 -0
  48. data/spec/kern/assets/find_view/controller8.rb +53 -0
  49. data/spec/kern/assets/find_view/controller9.rb +67 -0
  50. data/spec/kern/assets/hook_entry_points/controller0.rb +13 -1
  51. data/spec/kern/assets/push_count.rb +42 -0
  52. data/spec/kern/controller_spec.rb +34 -0
  53. data/spec/kern/find_view_spec.rb +269 -0
  54. data/spec/kern/hook_entry_points_and_manifest_spec.rb +60 -0
  55. data/spec/kern/hook_user_generators_spec.rb +100 -0
  56. data/spec/lib/helpers.rb +1 -2
  57. metadata +58 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c9638b060e87d9e0e19a63fdbeb014c4955a3c55
4
- data.tar.gz: 5f040e2f1eb8ed097787120bd32c77a31d756d47
3
+ metadata.gz: 6d3dd5275337abe10712fa3347a698c60819ff78
4
+ data.tar.gz: e126f18d24e069176e485f6db5327c407dafad71
5
5
  SHA512:
6
- metadata.gz: 285f33c37d3768ec61720d91e0ea690cd4dee909aeeb9bdabf1f783b6c50dc48b09472aa72070d63a5d8c6942f33e5a09f7ca5c2e4c7faf35fbbdf71de348abb
7
- data.tar.gz: c95c3272086f6aed12b5b302bd94f408dbfcd468e9e028f661d7f1b61c6bf1ca3a9f40aecc051004508b22a7cf932222b226fb02ddae40824cf56ab3c4200562
6
+ metadata.gz: baaa0fb3c2b68b3460e892d0f8d1c084e2d20eea45baaf29ff1ed8232bacd67cbd1aa0362a6fc725fd57be77519593c56021042c48d17a6b22c3b1d52ae2f1e3
7
+ data.tar.gz: ee1f06e6d0210adf94dbb9a7780945a4f9a9c37a1b39ac15d1b85512c2cecb678fdb064f9248da5406e49ccf9f5071383e32b7c60ceda860d86705cd93adc42e
@@ -0,0 +1,3 @@
1
+ [submodule "app/drivers/apple"]
2
+ path = app/drivers/apple
3
+ url = git@github.com:sotownsend/flok-apple.git
@@ -15,69 +15,84 @@ class InteractiveServer
15
15
 
16
16
  #Will take over any remaining IO
17
17
  def begin_pipe
18
- tmp = Tempfile.new(SecureRandom.hex)
19
- path = tmp.path
20
- tmp.close!
21
- File.write path, @app_js
18
+ puts "LOADED"
22
19
 
23
- p = Open3.popen3 "boojs #{path}" do |inp, out, err, t|
24
- pid = t[:pid]
25
- begin
26
- loop do
27
- results = select([out, err, STDIN], [])
28
- if results[0].include? err
29
- err_msg = err.readline
30
- $stderr.puts err_msg
31
- #exit 1 unless err_msg =~ /[debug]/
32
- end
20
+ _begin_pipe
21
+ end
22
+
23
+ def _begin_pipe
24
+ catch(:is_restarting) do
25
+ tmp = Tempfile.new(SecureRandom.hex)
26
+ path = tmp.path
27
+ tmp.close!
28
+ File.write path, @app_js
29
+
30
+ p = Open3.popen3 "boojs #{path}" do |inp, out, err, t|
31
+ pid = t[:pid]
32
+ begin
33
+ loop do
34
+ results = select([out, err, STDIN], [])
35
+ if results[0].include? err
36
+ err_msg = err.readline
37
+ $stderr.puts err_msg
38
+ #exit 1 unless err_msg =~ /[debug]/
39
+ end
40
+
41
+ if results[0].include? STDIN
42
+ begin
43
+ q = gets.strip
44
+
45
+ if q == "HARD_RESTART"
46
+ throw :is_restarting
47
+ elsif q == "RESTART"
48
+ inp.puts "$__RESTART__"
33
49
 
34
- if results[0].include? STDIN
35
- begin
36
- q = gets.strip
37
- if q == "RESTART"
38
- inp.puts "$__RESTART__"
50
+ begin
51
+ #Wait for restart to respond 'ok'
52
+ Timeout::timeout(10) do
53
+ restart_res = out.readline
54
+ raise "Restart of phantomjs did not return '__RESTART_OK__' like expected, returned: #{restart_res.inspect}" unless restart_res == "$__RESTART_OK__\n"
39
55
 
40
- begin
41
- #Wait for restart to respond 'ok'
42
- Timeout::timeout(10) do
43
- restart_res = out.readline
44
- raise "Restart of phantomjs did not return '__RESTART_OK__' like expected, returned: #{restart_res.inspect}" unless restart_res == "$__RESTART_OK__\n"
56
+ puts "RESTART OK"
57
+ end
58
+ rescue Timeout::Error
59
+ raise "Restart of boojs did not happen within 5 seconds"
60
+ rescue EOFError
61
+ #Sleep for a second to let the error pipe fill up from boojs, this error
62
+ #will then be displayed and then we will crash
63
+ sleep 3
64
+ $stderr.puts err.read
65
+ raise "boojs encountered an error"
45
66
  end
46
- rescue Timeout::Error
47
- raise "Restart of boojs did not happen within 5 seconds"
48
- rescue EOFError
49
- #Sleep for a second to let the error pipe fill up from boojs, this error
50
- #will then be displayed and then we will crash
51
- sleep 3
52
- $stderr.puts err.read
53
- raise "boojs encountered an error"
54
- end
55
67
 
56
- puts "RESTART OK"
57
- else
58
- inp.puts "if_dispatch(JSON.parse('#{q}'))"
68
+ else
69
+ inp.puts "if_dispatch(JSON.parse('#{q}'))"
70
+ end
71
+ rescue Errno::EIO
72
+ #Can't say anything here, we don't have a pipe
73
+ exit 1
74
+ rescue NoMethodError
75
+ exit 1
59
76
  end
60
- rescue Errno::EIO
61
- #Can't say anything here, we don't have a pipe
62
- exit 1
63
- rescue NoMethodError
64
- exit 1
65
77
  end
66
- end
67
78
 
68
- if results[0].include? out
69
- res = out.readline
70
- $stdout.puts res
71
- $stdout.flush
79
+ if results[0].include? out
80
+ res = out.readline
81
+ $stdout.puts res
82
+ $stdout.flush
83
+ end
84
+ end
85
+ ensure
86
+ begin
87
+ Process.kill :INT, pid
88
+ rescue Errno::ESRCH
72
89
  end
73
- end
74
- ensure
75
- begin
76
- Process.kill :INT, pid
77
- rescue Errno::ESRCH
78
90
  end
79
91
  end
80
92
  end
93
+
94
+ puts "RESTART OK"
95
+ _begin_pipe
81
96
  end
82
97
 
83
98
  #JS Functions#####################################################
@@ -159,9 +159,28 @@ function if_spec_controller_init() {
159
159
  }
160
160
  }
161
161
 
162
+ var TestControllerContext = function() {
163
+ this.base = FlokController; this.base(); self = this;
164
+
165
+ this.init = function() {
166
+ self.send("context", self.context)
167
+ }
168
+
169
+ self.action = function(from, to) {
170
+ self.send("action_rcv", {from: from, to:to});
171
+ }
172
+
173
+ self.event = function(name, info) {
174
+ self.send("custom_rcv", {name:name, info:info})
175
+ }
176
+ }
177
+
178
+
162
179
  //Register the new controller
163
180
  $(document).ready(function() {
164
- regController("__test__", TestController);
181
+ regController("spec_blank", TestController);
182
+ regController("spec_one_spot", TestController);
183
+ regController("spec_blank_sends_context", TestControllerContext);
165
184
  });
166
185
  }
167
186
 
@@ -1,23 +1,11 @@
1
1
  //Driver side interface
2
2
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3
3
  function if_hook_event(name, info) {
4
- <% if @debug %>
5
- if_hook_spec_dump_rcvd_events_log.push({name: name, info: info});
6
- <% end %>
7
-
8
4
  //Call the appropriate registered handler
9
5
  if (hookEventHandlers[name] !== undefined) {
10
6
  hookEventHandlers[name](info);
11
7
  }
12
8
  }
13
-
14
- <% if @debug %>
15
- //Track all events sent to if_hook_event
16
- var if_hook_spec_dump_rcvd_events_log = []
17
- function if_hook_spec_dump_rcvd_events() {
18
- int_dispatch([1, "if_hook_spec_dump_rcvd_events_res", if_hook_spec_dump_rcvd_events_log]);
19
- }
20
- <% end %>
21
9
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
22
10
 
23
11
  //User helpers
@@ -27,3 +15,13 @@ function onHookEvent(eventName, handler) {
27
15
  hookEventHandlers[eventName] = handler;
28
16
  }
29
17
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
18
+
19
+ <% if @debug %>
20
+ onHookEvent("test", function(info) {
21
+ int_dispatch([1, "hook_dump_res", {name: "test", info: info}]);
22
+ });
23
+
24
+ onHookEvent("test2", function(info) {
25
+ int_dispatch([1, "hook_dump_res", {name: "test2", info: info}]);
26
+ });
27
+ <% end %>
@@ -11,8 +11,8 @@ if_net_req = function(verb, url, params, tp_base) {
11
11
  success: function(data) {
12
12
  int_dispatch([3, "int_net_cb", tp_base, true, data]);
13
13
  },
14
- error: function(xhr, textStatus, err) {
15
- int_dispatch([3, "int_net_cb", tp_base, false, textStatus]);
16
- }
17
- })
14
+ error: function(xhr, textStatus, err) {
15
+ int_dispatch([3, "int_net_cb", tp_base, false, textStatus]);
16
+ }
17
+ })
18
18
  }
@@ -17,7 +17,7 @@ function if_sockio_fwd(sp, event_name, bp) {
17
17
  });
18
18
  } else {
19
19
  <% if @debug %>
20
- console.error("Couldnt fwd sockio with sp: " + sp + " (It dspn't exist)");
20
+ console.error("Couldnt fwd sockio with sp: " + sp + " (It does not exist)");
21
21
  <% end %>
22
22
  }
23
23
  }
@@ -30,7 +30,7 @@ function if_sockio_send(sp, event_name, info) {
30
30
  socket.emit(event_name, info);
31
31
  } else {
32
32
  <% if @debug %>
33
- console.error("Couldnt fwd sockio with sp: " + sp + " (It dspn't exist)");
33
+ console.error("Couldnt fwd sockio with sp: " + sp + " (It does not exist)");
34
34
  <% end %>
35
35
  }
36
36
  }
@@ -1,5 +1,6 @@
1
1
  //Create a new surface based on a prototype name and information.
2
2
  //Store that view in our own pointer table that uses selectors
3
+
3
4
  //Both spots and views
4
5
  if_ui_tp_to_selector = {};
5
6
 
@@ -113,21 +114,23 @@ function if_free_view(vp) {
113
114
  //Spec related////////////////////////////////////////////////
114
115
  function if_ui_spec_init() {
115
116
  //Set the body HTML
116
- var body_html = " \
117
- <div id='root'></div> \
118
- \
119
- <div id='prototypes' style='display: none'> \
120
- <div class='view' data-name='spec_blank'> \
121
- </div> \
122
- <div class='view' data-name='spec_one_spot'> \
123
- <div class='spot' data-name='content'></div> \
124
- </div> \
125
- <div class='view' data-name='spec_two_spot'> \
126
- <div class='spot' data-name='a'></div> \
127
- <div class='spot' data-name='b'></div> \
128
- </div> \
129
- </div> \
130
- \
117
+ var body_html = " \
118
+ <div id='root'></div> \
119
+ \
120
+ <div id='prototypes' style='display: none'> \
121
+ <div class='view' data-name='spec_blank'> \
122
+ </div> \
123
+ <div class='view' data-name='spec_blank_sends_context'> \
124
+ </div> \
125
+ <div class='view' data-name='spec_one_spot'> \
126
+ <div class='spot' data-name='content'></div> \
127
+ </div> \
128
+ <div class='view' data-name='spec_two_spot'> \
129
+ <div class='spot' data-name='a'></div> \
130
+ <div class='spot' data-name='b'></div> \
131
+ </div> \
132
+ </div> \
133
+ \
131
134
  "
132
135
  $("body").html(body_html);
133
136
  }
@@ -6,7 +6,9 @@ edefer_q = [];
6
6
 
7
7
  function int_event(ep, event_name, info) {
8
8
  <% if @debug %>
9
- if (ep.constructor !== String && ep.constructor !== Number) { throw "int_event was given either something that wasn't a string or number for ep: '" + (ep.constructor) + "' and the value was: '" + ep + "'"};
9
+ if (ep) {
10
+ if (ep.constructor !== String && ep.constructor !== Number) { throw "int_event was given either something that wasn't a string or number for ep: '" + (ep.constructor) + "' and the value was: '" + ep + "'"};
11
+ }
10
12
  <% end %>
11
13
 
12
14
  var f = evt[ep];
@@ -1 +1,13 @@
1
- //Stub
1
+ //goto hook generator expects this callback to be received usually for completion
2
+ function hook_goto_completion_cb(ep, ename, info) {
3
+ var views_to_free_id = ep;
4
+ var our_views_to_free = views_to_free[ep];
5
+
6
+ delete views_to_free[ep];
7
+ dereg_evt(ep);
8
+
9
+ for (var key in our_views_to_free) {
10
+ var bp = our_views_to_free[key];
11
+ main_q.push([1, "if_free_view", bp]);
12
+ }
13
+ }
@@ -1,2 +1,73 @@
1
1
  function int_embed_surface(sp) {
2
2
  }
3
+
4
+ function find_view(bp, spider) {
5
+ var res = {};
6
+ _find_view(bp, spider, res);
7
+
8
+ return res;
9
+ }
10
+
11
+ function _find_view(bp, spider, shared) {
12
+ var leaf = spider["__leaf__"];
13
+ if (leaf) {
14
+ shared[leaf] = bp
15
+ }
16
+
17
+ var ctable = tel_deref(bp);
18
+ var embeds = ctable.embeds;
19
+
20
+ for (var x = 0; x < embeds.length; ++x) {
21
+ for (var i = 0; i < embeds[x].length; ++i) {
22
+ //Pull info about the entry (subview)
23
+ var entry_bp = embeds[x][i];
24
+ var entry_cinfo = tel_deref(entry_bp); // The sub controller's info
25
+ var entry_ctable = entry_cinfo.cte; // The sub controller's ctable static
26
+ var entry_name = entry_ctable.name; // The sub controller's name
27
+
28
+ //Direct match found
29
+ var direct_match = spider[entry_name];
30
+ var dot_match = spider["."];
31
+ var plus_match = spider["+"];
32
+
33
+ if (direct_match) {
34
+ _find_view(entry_bp, direct_match, shared);
35
+ }
36
+
37
+ if (dot_match) {
38
+ _find_view(entry_bp, dot_match, shared);
39
+ }
40
+
41
+ if (plus_match) {
42
+ _find_view(entry_bp, plus_match, shared);
43
+ var partial_plus = {
44
+ "+": plus_match
45
+ }
46
+ _find_view(entry_bp, partial_plus, shared);
47
+ }
48
+ }
49
+ }
50
+
51
+ ////For all spots
52
+ //for (var x = 0; x < embeds.length; ++x) {
53
+ ////Search
54
+ //for (var i = 0; i < embeds[x].length; ++i) {
55
+ ////Lookup ctable for the embed
56
+ //var _ctable = tel_deref(embeds[x][i]);
57
+
58
+ ////Get it's name
59
+ //var name = _ctable.cte.name;
60
+
61
+ ////Does it match something in our spider?
62
+ //if (spider[_ctable.cte.name]) {
63
+ //output[spider[_ctable.cte.name].__leaf__] = embeds[x][i];
64
+ //} else if (spider["."]) {
65
+ //output[spider["."].__leaf__] = embeds[x][i];
66
+ //}
67
+ //}
68
+ //}
69
+ //return output;
70
+ }
71
+
72
+ //Used by the delayed free views typically for the GOTO hook specifically
73
+ var views_to_free = {};
@@ -55,6 +55,20 @@ controller "tab_controller" do
55
55
  }
56
56
  end
57
57
 
58
+ #Navigation stacks often have multiple entry points, 'back' may differ
59
+ #in action depending on whether it is the highest in the stack, you
60
+ #may use the 'push_count' variable to get the current level of the
61
+ #hierarchy you are on
62
+ macro :my_stack_macro do
63
+ on "back_clicked", %{
64
+ //If the push_level is 0, then we cannot Pop
65
+ if (push_count === 0) {
66
+ Raise("back_clicked");
67
+ } else {
68
+ Pop();
69
+ }
70
+ }
71
+ end
58
72
 
59
73
  #Optional
60
74
  #Called after on_entry, but before any action is entered. This is a pseudo
@@ -14,14 +14,16 @@ There are various stages of message processing so it can be confusing as to what
14
14
  1. The disptach mechanism, `int_dispatch`, is always called by the client synchronously, and the javascript core will always respond synchronously to `if_disptach`.
15
15
  2. The client `if_dispatch` handler will then process the main queue on it's same synchronous thread and then dispatch, asynchronously, the remaining queues; the queues may either each dispatch messages asynchronously or synchronously w.r.t to the original queue. (out of order and parallel are supported)
16
16
 
17
- Additionally, it is **never** ok to downgrade an asynchronous request to a synchronous request. Some functions, particularly the `vm` and
18
- `controller` systems rely on ordering. You can also **never** downgrade a synhcronous request to an asynchronous request. Synchronous requests must be done in order and on a single thread; additionally, they can be UI requests which are typically handled on the main thread.
17
+ Additionally, it is **never** ok to upgrade a synchronous request to an asynchronous request. Some functions, particularly the `vm` and
18
+ `controller` systems rely on ordering. Synchronous requests must be done in order and on a single thread; additionally, they can be UI requests which are typically handled on the main thread.
19
19
 
20
20
  For example, if we dispatch on the `main` queue a disk read request, flok would expect that the disk read would block the javascript core and return execution as soon as the disk read completed. Flok would also presume that the disk read was done at the fastest
21
21
  and highest priority of IO and CPU.
22
22
 
23
23
  Flok would expect that same disk requets, dispatched on an asynhcronous queue, like `disk`, that the request would not execute on the same thread of execution and could execute out of order.
24
24
 
25
+ **To re-iterate, `main` is the only synchronous queue; the other queues may be asynchronous but must be dispatched asynchronously; (they may also be asynchronous in nature)**
26
+
25
27
  ##The standard Flok queues (resources) are defined with the labels:
26
28
  0. `main` - User-interface displaying, etc.
27
29
  1. `net` - Downloading, Uploading, Get requests, etc.
@@ -38,6 +38,7 @@ instead.
38
38
  * `_embed(vc_name, sp, context, event_gw)` - Embed a view controller in a surface-pointer. Following the rules of the ui device, embedded to a sp of
39
39
  0 is the master root view. Returns base pointer. `event_gw` is a pointer to a `vc`. If it is null, then any events coming in will not be sent to
40
40
  somewhere else if they do not match any 'on' for the current action.
41
+ * `find_view(bp, spider_payload)` - Traverses the hierarchy within some controller (`bp`) and returns the named entries. See [find_view_specifics](./kernel_handbook/find_view.md) for how this works.
41
42
 
42
43
  ##Timers
43
44
  * See [./callout.md](Callout) for how to register a timer