wee 0.1.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. data/INSTALL +7 -0
  2. data/README +268 -0
  3. data/Rakefile +26 -0
  4. data/TODO +116 -0
  5. data/benchmark/Centrino1300/result.2000.counter.action +45 -0
  6. data/benchmark/Centrino1300/result.2000.counter.render +43 -0
  7. data/benchmark/Centrino1300/result.2000.filehandler +43 -0
  8. data/benchmark/Centrino600/result.2000.counter.action +47 -0
  9. data/benchmark/Centrino600/result.2000.counter.render +45 -0
  10. data/benchmark/Centrino600/result.2000.filehandler +43 -0
  11. data/benchmark/Makefile +48 -0
  12. data/benchmark/bench.sh +24 -0
  13. data/benchmark/counter.rb +96 -0
  14. data/benchmark/filehandler.rb +6 -0
  15. data/doc/rdoc/classes/Array.html +172 -0
  16. data/doc/rdoc/classes/Cache.html +126 -0
  17. data/doc/rdoc/classes/Cache/StorageCache.html +320 -0
  18. data/doc/rdoc/classes/Cache/Strategy.html +128 -0
  19. data/doc/rdoc/classes/Cache/Strategy/CapacityBounded.html +269 -0
  20. data/doc/rdoc/classes/Cache/Strategy/LFU.html +238 -0
  21. data/doc/rdoc/classes/Cache/Strategy/LFU/Item.html +111 -0
  22. data/doc/rdoc/classes/Cache/Strategy/LRU.html +238 -0
  23. data/doc/rdoc/classes/Cache/Strategy/LRU/Item.html +111 -0
  24. data/doc/rdoc/classes/Cache/Strategy/Unbounded.html +225 -0
  25. data/doc/rdoc/classes/Cache/Strategy/Unbounded/Item.html +111 -0
  26. data/doc/rdoc/classes/Enumerable.html +146 -0
  27. data/doc/rdoc/classes/LiteralMethod.html +196 -0
  28. data/doc/rdoc/classes/Object.html +178 -0
  29. data/doc/rdoc/classes/String.html +172 -0
  30. data/doc/rdoc/classes/Struct.html +174 -0
  31. data/doc/rdoc/classes/Wee.html +160 -0
  32. data/doc/rdoc/classes/Wee/AnswerDecoration.html +182 -0
  33. data/doc/rdoc/classes/Wee/Application.html +337 -0
  34. data/doc/rdoc/classes/Wee/Brush.html +245 -0
  35. data/doc/rdoc/classes/Wee/Brush/ActionCallbackMixin.html +149 -0
  36. data/doc/rdoc/classes/Wee/Brush/ActionMixin.html +146 -0
  37. data/doc/rdoc/classes/Wee/Brush/ActionURLCallbackMixin.html +157 -0
  38. data/doc/rdoc/classes/Wee/Brush/AnchorTag.html +210 -0
  39. data/doc/rdoc/classes/Wee/Brush/AssignMixin.html +141 -0
  40. data/doc/rdoc/classes/Wee/Brush/CallbackMixin.html +141 -0
  41. data/doc/rdoc/classes/Wee/Brush/FormTag.html +225 -0
  42. data/doc/rdoc/classes/Wee/Brush/GenericEncodedTextBrush.html +176 -0
  43. data/doc/rdoc/classes/Wee/Brush/GenericTagBrush.html +283 -0
  44. data/doc/rdoc/classes/Wee/Brush/GenericTextBrush.html +176 -0
  45. data/doc/rdoc/classes/Wee/Brush/ImageButtonTag.html +195 -0
  46. data/doc/rdoc/classes/Wee/Brush/InputCallbackMixin.html +149 -0
  47. data/doc/rdoc/classes/Wee/Brush/InputTag.html +172 -0
  48. data/doc/rdoc/classes/Wee/Brush/Page.html +193 -0
  49. data/doc/rdoc/classes/Wee/Brush/SelectListTag.html +267 -0
  50. data/doc/rdoc/classes/Wee/Brush/SelectOptionTag.html +177 -0
  51. data/doc/rdoc/classes/Wee/Brush/SubmitButtonTag.html +154 -0
  52. data/doc/rdoc/classes/Wee/Brush/TableDataTag.html +173 -0
  53. data/doc/rdoc/classes/Wee/Brush/TableHeaderTag.html +146 -0
  54. data/doc/rdoc/classes/Wee/Brush/TableRowTag.html +277 -0
  55. data/doc/rdoc/classes/Wee/Brush/TableTag.html +146 -0
  56. data/doc/rdoc/classes/Wee/Brush/TextAreaTag.html +229 -0
  57. data/doc/rdoc/classes/Wee/Brush/TextInputTag.html +154 -0
  58. data/doc/rdoc/classes/Wee/Callback.html +231 -0
  59. data/doc/rdoc/classes/Wee/CallbackRegistry.html +308 -0
  60. data/doc/rdoc/classes/Wee/CallbackStream.html +227 -0
  61. data/doc/rdoc/classes/Wee/Canvas.html +235 -0
  62. data/doc/rdoc/classes/Wee/Component.html +933 -0
  63. data/doc/rdoc/classes/Wee/Context.html +111 -0
  64. data/doc/rdoc/classes/Wee/Decoration.html +338 -0
  65. data/doc/rdoc/classes/Wee/Delegate.html +247 -0
  66. data/doc/rdoc/classes/Wee/ErrorPage.html +175 -0
  67. data/doc/rdoc/classes/Wee/ErrorResponse.html +180 -0
  68. data/doc/rdoc/classes/Wee/GenericResponse.html +162 -0
  69. data/doc/rdoc/classes/Wee/HtmlCanvas.html +751 -0
  70. data/doc/rdoc/classes/Wee/HtmlWriter.html +351 -0
  71. data/doc/rdoc/classes/Wee/LiteralMethodCallback.html +180 -0
  72. data/doc/rdoc/classes/Wee/MethodCallback.html +193 -0
  73. data/doc/rdoc/classes/Wee/Page.html +111 -0
  74. data/doc/rdoc/classes/Wee/Presenter.html +521 -0
  75. data/doc/rdoc/classes/Wee/RedirectResponse.html +150 -0
  76. data/doc/rdoc/classes/Wee/RefreshResponse.html +157 -0
  77. data/doc/rdoc/classes/Wee/RenderingContext.html +111 -0
  78. data/doc/rdoc/classes/Wee/Request.html +268 -0
  79. data/doc/rdoc/classes/Wee/RequestHandler.html +336 -0
  80. data/doc/rdoc/classes/Wee/Response.html +260 -0
  81. data/doc/rdoc/classes/Wee/Session.html +469 -0
  82. data/doc/rdoc/classes/Wee/SimpleIdGenerator.html +198 -0
  83. data/doc/rdoc/classes/Wee/Snapshot.html +211 -0
  84. data/doc/rdoc/classes/Wee/StateHolder.html +149 -0
  85. data/doc/rdoc/classes/Wee/StateRegistry.html +434 -0
  86. data/doc/rdoc/classes/Wee/StateRegistry/Snapshot.html +320 -0
  87. data/doc/rdoc/classes/Wee/StateRegistry/WithObject.html +153 -0
  88. data/doc/rdoc/classes/Wee/Utils.html +111 -0
  89. data/doc/rdoc/classes/Wee/Utils/LRUCache.html +148 -0
  90. data/doc/rdoc/classes/Wee/ValueHolder.html +220 -0
  91. data/doc/rdoc/classes/Wee/WEBrickAdaptor.html +330 -0
  92. data/doc/rdoc/created.rid +1 -0
  93. data/doc/rdoc/files/INSTALL.html +118 -0
  94. data/doc/rdoc/files/README.html +466 -0
  95. data/doc/rdoc/files/lib/cache/cache_rb.html +101 -0
  96. data/doc/rdoc/files/lib/wee/adaptors/webrick_rb.html +108 -0
  97. data/doc/rdoc/files/lib/wee/application_rb.html +112 -0
  98. data/doc/rdoc/files/lib/wee/callback_rb.html +107 -0
  99. data/doc/rdoc/files/lib/wee/component_ext_rb.html +101 -0
  100. data/doc/rdoc/files/lib/wee/component_rb.html +109 -0
  101. data/doc/rdoc/files/lib/wee/context_rb.html +101 -0
  102. data/doc/rdoc/files/lib/wee/core/callback_rb.html +115 -0
  103. data/doc/rdoc/files/lib/wee/core/component_rb.html +108 -0
  104. data/doc/rdoc/files/lib/wee/core/decoration_rb.html +133 -0
  105. data/doc/rdoc/files/lib/wee/core/presenter_rb.html +112 -0
  106. data/doc/rdoc/files/lib/wee/core/snapshot_rb.html +113 -0
  107. data/doc/rdoc/files/lib/wee/core/valueholder_rb.html +110 -0
  108. data/doc/rdoc/files/lib/wee/core_rb.html +131 -0
  109. data/doc/rdoc/files/lib/wee/decoration_rb.html +101 -0
  110. data/doc/rdoc/files/lib/wee/holder_rb.html +101 -0
  111. data/doc/rdoc/files/lib/wee/html_canvas_rb.html +108 -0
  112. data/doc/rdoc/files/lib/wee/html_writer_rb.html +108 -0
  113. data/doc/rdoc/files/lib/wee/idgen_rb.html +101 -0
  114. data/doc/rdoc/files/lib/wee/page_rb.html +101 -0
  115. data/doc/rdoc/files/lib/wee/presenter_rb.html +112 -0
  116. data/doc/rdoc/files/lib/wee/renderer/html/brushes_rb.html +101 -0
  117. data/doc/rdoc/files/lib/wee/renderer/html/canvas_rb.html +101 -0
  118. data/doc/rdoc/files/lib/wee/renderer/html/writer_rb.html +108 -0
  119. data/doc/rdoc/files/lib/wee/rendering/html/brushes_rb.html +101 -0
  120. data/doc/rdoc/files/lib/wee/rendering/html/canvas_rb.html +101 -0
  121. data/doc/rdoc/files/lib/wee/rendering/html/writer_rb.html +108 -0
  122. data/doc/rdoc/files/lib/wee/request_rb.html +113 -0
  123. data/doc/rdoc/files/lib/wee/requesthandler_rb.html +101 -0
  124. data/doc/rdoc/files/lib/wee/response_rb.html +108 -0
  125. data/doc/rdoc/files/lib/wee/session_rb.html +109 -0
  126. data/doc/rdoc/files/lib/wee/snapshot_ext_rb.html +101 -0
  127. data/doc/rdoc/files/lib/wee/snapshot_rb.html +107 -0
  128. data/doc/rdoc/files/lib/wee/state_registry_rb.html +110 -0
  129. data/doc/rdoc/files/lib/wee/stuff_rb.html +144 -0
  130. data/doc/rdoc/files/lib/wee/utils/cache_rb.html +108 -0
  131. data/doc/rdoc/files/lib/wee/webrick_rb.html +108 -0
  132. data/doc/rdoc/files/lib/wee_rb.html +132 -0
  133. data/doc/rdoc/fr_class_index.html +93 -0
  134. data/doc/rdoc/fr_file_index.html +51 -0
  135. data/doc/rdoc/fr_method_index.html +242 -0
  136. data/doc/rdoc/index.html +24 -0
  137. data/doc/rdoc/rdoc-style.css +208 -0
  138. data/examples/ObjectSpaceBrowser.rb +199 -0
  139. data/examples/calendar.rb +366 -0
  140. data/examples/cc.rb +94 -0
  141. data/examples/draw.rb +91 -0
  142. data/examples/example.rb +223 -0
  143. data/examples/test.rb +66 -0
  144. data/examples/window.rb +53 -0
  145. data/lib/cache/cache.rb +9 -0
  146. data/lib/wee.rb +18 -8
  147. data/lib/wee/adaptors/webrick.rb +73 -0
  148. data/lib/wee/application.rb +69 -71
  149. data/lib/wee/context.rb +2 -12
  150. data/lib/wee/core.rb +15 -0
  151. data/lib/wee/core/callback.rb +108 -0
  152. data/lib/wee/core/component.rb +314 -0
  153. data/lib/wee/core/decoration.rb +129 -0
  154. data/lib/wee/core/presenter.rb +132 -0
  155. data/lib/wee/core/snapshot.rb +21 -0
  156. data/lib/wee/core/valueholder.rb +19 -0
  157. data/lib/wee/idgen.rb +13 -0
  158. data/lib/wee/page.rb +1 -1
  159. data/lib/wee/renderer/html/brushes.rb +435 -0
  160. data/lib/wee/renderer/html/canvas.rb +148 -0
  161. data/lib/wee/{html_writer.rb → renderer/html/writer.rb} +31 -16
  162. data/lib/wee/request.rb +57 -0
  163. data/lib/wee/requesthandler.rb +77 -0
  164. data/lib/wee/response.rb +77 -0
  165. data/lib/wee/session.rb +70 -64
  166. data/lib/wee/{snapshot.rb → snapshot_ext.rb} +4 -4
  167. data/test/components/calltest.rb +16 -0
  168. data/test/components/counter.rb +17 -0
  169. data/test/components/messagebox.rb +15 -0
  170. data/test/components/page.rb +14 -0
  171. data/test/components/page_decoration.rb +7 -0
  172. data/test/stress.rb +64 -0
  173. data/test/test_component.rb +106 -0
  174. data/test/test_html_canvas.rb +25 -0
  175. data/test/test_html_writer.rb +27 -0
  176. data/test/test_request.rb +13 -0
  177. data/test/utils/cross.rb +65 -0
  178. data/test/utils/generic_plotter.rb +28 -0
  179. data/test/utils/gnuplot.rb +31 -0
  180. data/test/utils/measure_memory.rb +9 -0
  181. data/test/utils/memory_plotter.rb +10 -0
  182. data/test/utils/object_plotter.rb +10 -0
  183. data/test/utils/webrick_background.rb +31 -0
  184. data/wee.gemspec +22 -0
  185. metadata +222 -18
  186. data/lib/wee/component.rb +0 -126
  187. data/lib/wee/delegate_decoration.rb +0 -22
  188. data/lib/wee/handler_registry.rb +0 -89
  189. data/lib/wee/holder.rb +0 -14
  190. data/lib/wee/html_canvas.rb +0 -379
  191. data/lib/wee/state_registry.rb +0 -173
  192. data/lib/wee/stuff.rb +0 -29
  193. data/lib/wee/webrick.rb +0 -15
@@ -0,0 +1,53 @@
1
+ class Wee::Window < Wee::Component
2
+
3
+ def initialize(title, pos, child)
4
+ super()
5
+ @title = title
6
+ @child = child
7
+ @status = :normal
8
+ self.children << @child
9
+ @pos = pos
10
+ end
11
+
12
+ def process_callbacks(callback_stream)
13
+ return if @status == :closed
14
+ super
15
+ end
16
+
17
+ def minimize
18
+ @status = :minimized
19
+ end
20
+
21
+ def maximize
22
+ @status = :normal
23
+ end
24
+
25
+ def close
26
+ @status = :closed
27
+ end
28
+
29
+ def render
30
+ return if @status == :closed
31
+
32
+ r.table.cellspacing(0).style("border:solid 1px grey; position: relative; top: #{@pos}; left: #{200+@pos.to_i}").with do
33
+ r.table_row.style("background-color: lightblue; width: 100%").with do
34
+ r.table_data.style("text-align: left; width: 66%").with(@title)
35
+ r.table_data.style("text-align: right").with do
36
+ if @status == :minimized
37
+ r.anchor.callback{maximize}.with("#")
38
+ else
39
+ r.anchor.callback{minimize}.with("_")
40
+ end
41
+ r.space
42
+ r.anchor.callback{close}.with("X")
43
+ end
44
+ end
45
+ r.table_row do
46
+ r.table_data.colspan(2).with do
47
+ r.render(@child) if @status == :normal
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ end
data/lib/cache/cache.rb CHANGED
@@ -1,3 +1,12 @@
1
+ unless Enumerable.instance_methods.include?("min_by")
2
+ # for Ruby 1.8
3
+ module Enumerable
4
+ def min_by(&block)
5
+ min {|i,j| block.call(i) <=> block.call(j) }
6
+ end
7
+ end
8
+ end
9
+
1
10
  # Abstract super class of all cache implementations.
2
11
  class Cache; end
3
12
 
data/lib/wee.rb CHANGED
@@ -1,11 +1,21 @@
1
- module Wee; end
1
+ module Wee
2
+ Version = "0.3.1"
3
+ end
4
+
5
+ require 'wee/core'
2
6
 
3
- require 'wee/application'
4
- require 'wee/component'
5
- require 'wee/delegate_decoration'
6
7
  require 'wee/context'
8
+ require 'wee/application'
9
+ require 'wee/requesthandler'
10
+ require 'wee/request'
11
+ require 'wee/response'
7
12
  require 'wee/session'
8
- require 'wee/holder'
9
- require 'wee/html_writer'
10
- require 'wee/html_canvas'
11
- require 'wee/stuff'
13
+
14
+ require 'wee/snapshot_ext'
15
+
16
+ require 'wee/renderer/html/writer'
17
+ require 'wee/renderer/html/brushes'
18
+ require 'wee/renderer/html/canvas'
19
+ Wee::DefaultRenderer = Wee::HtmlCanvas
20
+
21
+ require 'wee/idgen'
@@ -0,0 +1,73 @@
1
+ require 'webrick'
2
+
3
+ # Example of usage:
4
+ #
5
+ # require 'wee/adaptors/webrick'
6
+ # s = WEBrick::HTTPServer.new(:Port => 2000)
7
+ # s.mount '/app', Wee::WEBrickAdaptor, application
8
+ #
9
+ # trap("INT") { s.shutdown; exit }
10
+ # s.start
11
+ #
12
+ # Or when using the convenience methods:
13
+ #
14
+ # require 'wee/adaptors/webrick'
15
+ # Wee::WEBrickAdaptor.
16
+ # register('/app' => application).
17
+ # register('/cnt' => application2).
18
+ # start(:Port => 2000)
19
+ #
20
+
21
+ class Wee::WEBrickAdaptor < WEBrick::HTTPServlet::AbstractServlet
22
+
23
+ # Convenience method
24
+ def self.start(options={})
25
+ server = WEBrick::HTTPServer.new({:Port => 2000}.update(options))
26
+ trap("INT") { server.shutdown }
27
+
28
+ (@apps||[]).each do |path, app|
29
+ server.mount(path, self, path, app)
30
+ end
31
+
32
+ (@mounts||[]).each do |args, block|
33
+ server.mount(*args, &block)
34
+ end
35
+
36
+ yield server if block_given?
37
+
38
+ server.start
39
+ server
40
+ end
41
+
42
+ # Convenience method
43
+ def self.register(hash)
44
+ @apps ||= []
45
+ hash.each do |path, application|
46
+ @apps << [path, application]
47
+ end
48
+ self
49
+ end
50
+
51
+ def mount(*args, &block)
52
+ @mounts ||= []
53
+ @mounts << [args, block]
54
+ self
55
+ end
56
+
57
+ def initialize(server, mount_path, application)
58
+ super(server)
59
+ @mount_path = mount_path
60
+ @application = application
61
+ end
62
+
63
+ def handle_request(req, res)
64
+ context = Wee::Context.new(Wee::Request.new(@mount_path, req.path, req.header, req.query))
65
+ @application.handle_request(context)
66
+ res.status = context.response.status
67
+ res.body = context.response.content
68
+ context.response.header.each { |k,v| res.header[k] = v }
69
+ end
70
+
71
+ alias do_GET handle_request
72
+ alias do_POST handle_request
73
+ end
@@ -1,91 +1,89 @@
1
+ # A Wee::Application manages all Wee::RequestHandler's of a single application,
2
+ # where most of the time the request handlers are Wee::Session objects. It
3
+ # dispatches the request to the correct handler by examining the request.
4
+
1
5
  class Wee::Application
2
- attr_accessor :name, :path
3
- attr_accessor :session_store, :session_class
4
- attr_accessor :dumpfile
5
6
 
6
- def initialize(&block)
7
- setup_session_id_generator
7
+ # The generator used for creating unique request handler id's.
8
8
 
9
- block.call(self)
9
+ attr_accessor :id_generator
10
10
 
11
- if [@name, @path, @session_class, @session_store, @dumpfile].any? {|i| i.nil?}
12
- raise ArgumentError, "missing name, path, session_class, session_store or dumpfile"
13
- end
14
- end
11
+ # The maximum number of request handlers
15
12
 
16
- def setup_session_id_generator
17
- @session_cnt = rand(1000_000)
18
- end
13
+ attr_accessor :max_request_handlers
19
14
 
20
- def handle_request(req, res)
21
- hash = parse_url(req)
15
+ # Get or set the default request handler. The default request handler is used
16
+ # if no request handler id is given in a request.
22
17
 
23
- session_id = hash['s']
24
- if session_id.nil?
25
- # TODO:
26
- # gen session, or assign default session (by default, do not show).
27
- # but for a default session, we have to have thread-safe components (without @context=... hack)
28
-
29
- session = @session_class.new
30
- session_id = gen_unique_session_id
31
- @session_store[session_id] = session
32
- end
33
-
34
- session = @session_store[session_id]
35
- if session.nil?
36
- # TODO: redirect to session-less page, or do whatever
37
- error_invalid_session(req, res); return
18
+ def default_request_handler(&block)
19
+ if block.nil?
20
+ @default_request_handler
21
+ else
22
+ @default_request_handler = block
38
23
  end
39
-
40
- context = Wee::Context.new(req, res, session, session_id)
41
- context.application = self
42
- context.session = session
43
- context.page_id = hash['p']
44
- context.handler_id = hash['h']
45
- context.resource_id = hash['r']
46
- session.handle_request(context)
47
- end
48
-
49
- # TODO: UrlModel, which knows how to create and parse URLs
50
- def gen_handler_url(session_id, page_id, handler_id)
51
- [
52
- self.path,
53
- ['s', session_id].join(':'),
54
- ['p', page_id].join(':'),
55
- ['h', handler_id].join(':')
56
- ].join('/')
57
24
  end
58
25
 
59
- def gen_resource_url(session_id, page_id, resource_id)
60
- [
61
- self.path,
62
- ['s', session_id].join(':'),
63
- ['p', page_id].join(':'),
64
- ['r', resource_id].join(':')
65
- ].join('/')
66
- end
26
+ # Creates a new application. The block is used to initialize the attributes:
27
+ #
28
+ # Wee::Application.new {|app|
29
+ # app.default_request_handler { MySession.new }
30
+ # app.id_generator = Wee::SimpleIdGenerator.new
31
+ # app.max_request_handlers = 1000
32
+ # }
67
33
 
68
- def error_invalid_session(req, res)
69
- Wee::ErrorPage.new('Invalid Session').respond(Wee::Context.new(req,res,nil,nil))
34
+ def initialize(&block)
35
+ @request_handlers = Hash.new
36
+ block.call(self)
37
+ @id_generator ||= Wee::SimpleIdGenerator.new(rand(1_000_000))
38
+ if @default_request_handler.nil?
39
+ raise ArgumentError, "No default request handler specified"
40
+ end
41
+ @mutex = Mutex.new
70
42
  end
71
-
72
- def store_to_disk(dumpfile=nil)
73
- File.open(dumpfile||@dumpfile, 'w+b') {|f| f << Marshal.dump(self) }
43
+
44
+ # TODO: we have to use mutexes here
45
+ # NOTE that id_generator must be thread-safe!
46
+ # TODO: test for max_request_handlers
47
+
48
+ def handle_request(context)
49
+ @mutex.synchronize do
50
+ request_handler_id = context.request.request_handler_id
51
+ request_handler = @request_handlers[request_handler_id]
52
+
53
+ if request_handler_id.nil?
54
+ # No id was given -> create new id and handler
55
+ request_handler_id = unique_request_handler_id()
56
+ request_handler = @default_request_handler.call
57
+ request_handler.id = request_handler_id
58
+ request_handler.application = self
59
+ @request_handlers[request_handler_id] = request_handler
60
+
61
+ context.response = Wee::RedirectResponse.new(context.request.build_url(request_handler_id))
62
+ return
63
+
64
+ elsif request_handler.nil?
65
+ # A false request handler id was given. This might indicate that a
66
+ # request handler has expired.
67
+ request_handler_expired(context)
68
+ return
69
+ end
70
+
71
+ request_handler.handle_request(context)
72
+ end
73
+ rescue => exn
74
+ context.response = Wee::ErrorResponse.new(exn)
74
75
  end
75
76
 
76
- def self.load_from_disk(filename)
77
- Marshal.load(File.read(filename))
78
- end
77
+ private
79
78
 
80
- def shutdown
81
- store_to_disk
79
+ def unique_request_handler_id
80
+ id = @id_generator.next.to_s
81
+ raise "failed to create unique request handler id" if @request_handlers.include?(id)
82
+ return id
82
83
  end
83
84
 
84
- private
85
-
86
- # TODO: that's insecure. it's just for development!
87
- def gen_unique_session_id
88
- (@session_cnt += 1).to_s
85
+ def request_handler_expired(context)
86
+ context.response = Wee::RefreshResponse.new("Invalid or expired request handler!", context.request.application_path)
89
87
  end
90
88
 
91
89
  end
data/lib/wee/context.rb CHANGED
@@ -1,12 +1,2 @@
1
- class Wee::Context
2
- attr_accessor :application
3
- attr_accessor :request, :response, :session, :session_id
4
- attr_accessor :page_id, :handler_id, :resource_id
5
- attr_accessor :handler_registry
6
-
7
- def initialize(request, response, session, session_id)
8
- @request, @response, @session, @session_id, @root = request, response, session, session_id
9
- end
10
- end
11
-
12
- class Wee::RenderingContext < Struct.new(:context, :document); end
1
+ class Wee::Context < Struct.new(:request, :response); end
2
+ class Wee::RenderingContext < Struct.new(:request, :response, :callbacks, :document); end
data/lib/wee/core.rb ADDED
@@ -0,0 +1,15 @@
1
+ # The only dependencies of the core classes are:
2
+ #
3
+ # * Wee::Session.current in class Wee::Presenter#session
4
+ # * Wee::DefaultRenderer in Wee::Presenter#renderer_class
5
+ #
6
+
7
+ # independent files
8
+ require 'wee/core/valueholder'
9
+ require 'wee/core/snapshot'
10
+ require 'wee/core/callback'
11
+
12
+ # dependent files
13
+ require 'wee/core/presenter'
14
+ require 'wee/core/decoration'
15
+ require 'wee/core/component'
@@ -0,0 +1,108 @@
1
+ # The callback registry is the central datastructure where all components of a
2
+ # session register their callbacks.
3
+ #
4
+ # The format of the internal datastructure is:
5
+ #
6
+ # @callbacks[type][callback_id] => callback
7
+ # @obj_to_id_map[type][object] => [id*]
8
+
9
+ class Wee::CallbackRegistry
10
+
11
+ def initialize(id_generator)
12
+ @idgen = id_generator
13
+ @callbacks = Hash.new
14
+ @obj_to_id_map = Hash.new
15
+ end
16
+
17
+ # Register +callback+ for +object+ under +type+ and return a unique callback id.
18
+
19
+ def register_for(object, type=nil, &callback)
20
+ c = (@callbacks[type] ||= Hash.new)
21
+ o = (@obj_to_id_map[type] ||= Hash.new)
22
+ cid = @idgen.next.to_s
23
+ raise "duplicate callback id" if c.has_key?(cid)
24
+ c[cid] = callback
25
+ (o[object] ||= []) << cid
26
+ return cid
27
+ end
28
+
29
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
30
+ # :section: Friend methods for Wee::CallbackStream
31
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
32
+
33
+ def get_ids_for(object, type=nil)
34
+ if o = @obj_to_id_map[type]
35
+ o[object] || []
36
+ else
37
+ []
38
+ end
39
+ end
40
+
41
+ def get_callback_for(id, type=nil)
42
+ if c = @callbacks[type]
43
+ c[id]
44
+ else
45
+ raise
46
+ end
47
+ end
48
+
49
+ def all_of_type(type=nil)
50
+ if c = @callbacks[type]
51
+ c
52
+ else
53
+ raise
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+
60
+ # The intersection of registered callbacks and those that occured.
61
+
62
+ class Wee::CallbackStream
63
+
64
+ #
65
+ # [<tt>callbacks</tt>]
66
+ # A Wee::CallbackRegistry
67
+ #
68
+ # [<tt>ids_and_values</tt>]
69
+ # A hash that contains all callback ids together with their values that
70
+ # occurend in a request, e.g. { id => value }.
71
+
72
+ def initialize(callbacks, ids_and_values)
73
+ @callbacks = callbacks
74
+ @ids_and_values = ids_and_values
75
+ @ids = @ids_and_values.keys
76
+ end
77
+
78
+ def with_callbacks_for(object, type)
79
+ matching_ids = @callbacks.get_ids_for(object, type) & @ids
80
+ matching_ids.each do |id|
81
+ yield @callbacks.get_callback_for(id, type), @ids_and_values[id]
82
+ end
83
+ @ids -= matching_ids
84
+ end
85
+
86
+ # Returns a [callback, value] array of all callbacks of +type+ for which an
87
+ # id was given.
88
+
89
+ def all_of_type(type)
90
+ a = []
91
+ @callbacks.all_of_type(type).each {|id, callback|
92
+ a << [callback, @ids_and_values[id]] if @ids_and_values.include?(id)
93
+ }
94
+ return a
95
+ end
96
+
97
+ end
98
+
99
+ # A serializable callback.
100
+ class Wee::LiteralMethodCallback
101
+ def initialize(obj, method_id=:call)
102
+ @obj, @method_id = obj, method_id
103
+ end
104
+
105
+ def call(*args)
106
+ @obj.send(@method_id, *args)
107
+ end
108
+ end