wee 0.1.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/INSTALL +7 -0
- data/README +268 -0
- data/Rakefile +26 -0
- data/TODO +116 -0
- data/benchmark/Centrino1300/result.2000.counter.action +45 -0
- data/benchmark/Centrino1300/result.2000.counter.render +43 -0
- data/benchmark/Centrino1300/result.2000.filehandler +43 -0
- data/benchmark/Centrino600/result.2000.counter.action +47 -0
- data/benchmark/Centrino600/result.2000.counter.render +45 -0
- data/benchmark/Centrino600/result.2000.filehandler +43 -0
- data/benchmark/Makefile +48 -0
- data/benchmark/bench.sh +24 -0
- data/benchmark/counter.rb +96 -0
- data/benchmark/filehandler.rb +6 -0
- data/doc/rdoc/classes/Array.html +172 -0
- data/doc/rdoc/classes/Cache.html +126 -0
- data/doc/rdoc/classes/Cache/StorageCache.html +320 -0
- data/doc/rdoc/classes/Cache/Strategy.html +128 -0
- data/doc/rdoc/classes/Cache/Strategy/CapacityBounded.html +269 -0
- data/doc/rdoc/classes/Cache/Strategy/LFU.html +238 -0
- data/doc/rdoc/classes/Cache/Strategy/LFU/Item.html +111 -0
- data/doc/rdoc/classes/Cache/Strategy/LRU.html +238 -0
- data/doc/rdoc/classes/Cache/Strategy/LRU/Item.html +111 -0
- data/doc/rdoc/classes/Cache/Strategy/Unbounded.html +225 -0
- data/doc/rdoc/classes/Cache/Strategy/Unbounded/Item.html +111 -0
- data/doc/rdoc/classes/Enumerable.html +146 -0
- data/doc/rdoc/classes/LiteralMethod.html +196 -0
- data/doc/rdoc/classes/Object.html +178 -0
- data/doc/rdoc/classes/String.html +172 -0
- data/doc/rdoc/classes/Struct.html +174 -0
- data/doc/rdoc/classes/Wee.html +160 -0
- data/doc/rdoc/classes/Wee/AnswerDecoration.html +182 -0
- data/doc/rdoc/classes/Wee/Application.html +337 -0
- data/doc/rdoc/classes/Wee/Brush.html +245 -0
- data/doc/rdoc/classes/Wee/Brush/ActionCallbackMixin.html +149 -0
- data/doc/rdoc/classes/Wee/Brush/ActionMixin.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/ActionURLCallbackMixin.html +157 -0
- data/doc/rdoc/classes/Wee/Brush/AnchorTag.html +210 -0
- data/doc/rdoc/classes/Wee/Brush/AssignMixin.html +141 -0
- data/doc/rdoc/classes/Wee/Brush/CallbackMixin.html +141 -0
- data/doc/rdoc/classes/Wee/Brush/FormTag.html +225 -0
- data/doc/rdoc/classes/Wee/Brush/GenericEncodedTextBrush.html +176 -0
- data/doc/rdoc/classes/Wee/Brush/GenericTagBrush.html +283 -0
- data/doc/rdoc/classes/Wee/Brush/GenericTextBrush.html +176 -0
- data/doc/rdoc/classes/Wee/Brush/ImageButtonTag.html +195 -0
- data/doc/rdoc/classes/Wee/Brush/InputCallbackMixin.html +149 -0
- data/doc/rdoc/classes/Wee/Brush/InputTag.html +172 -0
- data/doc/rdoc/classes/Wee/Brush/Page.html +193 -0
- data/doc/rdoc/classes/Wee/Brush/SelectListTag.html +267 -0
- data/doc/rdoc/classes/Wee/Brush/SelectOptionTag.html +177 -0
- data/doc/rdoc/classes/Wee/Brush/SubmitButtonTag.html +154 -0
- data/doc/rdoc/classes/Wee/Brush/TableDataTag.html +173 -0
- data/doc/rdoc/classes/Wee/Brush/TableHeaderTag.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/TableRowTag.html +277 -0
- data/doc/rdoc/classes/Wee/Brush/TableTag.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/TextAreaTag.html +229 -0
- data/doc/rdoc/classes/Wee/Brush/TextInputTag.html +154 -0
- data/doc/rdoc/classes/Wee/Callback.html +231 -0
- data/doc/rdoc/classes/Wee/CallbackRegistry.html +308 -0
- data/doc/rdoc/classes/Wee/CallbackStream.html +227 -0
- data/doc/rdoc/classes/Wee/Canvas.html +235 -0
- data/doc/rdoc/classes/Wee/Component.html +933 -0
- data/doc/rdoc/classes/Wee/Context.html +111 -0
- data/doc/rdoc/classes/Wee/Decoration.html +338 -0
- data/doc/rdoc/classes/Wee/Delegate.html +247 -0
- data/doc/rdoc/classes/Wee/ErrorPage.html +175 -0
- data/doc/rdoc/classes/Wee/ErrorResponse.html +180 -0
- data/doc/rdoc/classes/Wee/GenericResponse.html +162 -0
- data/doc/rdoc/classes/Wee/HtmlCanvas.html +751 -0
- data/doc/rdoc/classes/Wee/HtmlWriter.html +351 -0
- data/doc/rdoc/classes/Wee/LiteralMethodCallback.html +180 -0
- data/doc/rdoc/classes/Wee/MethodCallback.html +193 -0
- data/doc/rdoc/classes/Wee/Page.html +111 -0
- data/doc/rdoc/classes/Wee/Presenter.html +521 -0
- data/doc/rdoc/classes/Wee/RedirectResponse.html +150 -0
- data/doc/rdoc/classes/Wee/RefreshResponse.html +157 -0
- data/doc/rdoc/classes/Wee/RenderingContext.html +111 -0
- data/doc/rdoc/classes/Wee/Request.html +268 -0
- data/doc/rdoc/classes/Wee/RequestHandler.html +336 -0
- data/doc/rdoc/classes/Wee/Response.html +260 -0
- data/doc/rdoc/classes/Wee/Session.html +469 -0
- data/doc/rdoc/classes/Wee/SimpleIdGenerator.html +198 -0
- data/doc/rdoc/classes/Wee/Snapshot.html +211 -0
- data/doc/rdoc/classes/Wee/StateHolder.html +149 -0
- data/doc/rdoc/classes/Wee/StateRegistry.html +434 -0
- data/doc/rdoc/classes/Wee/StateRegistry/Snapshot.html +320 -0
- data/doc/rdoc/classes/Wee/StateRegistry/WithObject.html +153 -0
- data/doc/rdoc/classes/Wee/Utils.html +111 -0
- data/doc/rdoc/classes/Wee/Utils/LRUCache.html +148 -0
- data/doc/rdoc/classes/Wee/ValueHolder.html +220 -0
- data/doc/rdoc/classes/Wee/WEBrickAdaptor.html +330 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/INSTALL.html +118 -0
- data/doc/rdoc/files/README.html +466 -0
- data/doc/rdoc/files/lib/cache/cache_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/adaptors/webrick_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/application_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/callback_rb.html +107 -0
- data/doc/rdoc/files/lib/wee/component_ext_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/component_rb.html +109 -0
- data/doc/rdoc/files/lib/wee/context_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/core/callback_rb.html +115 -0
- data/doc/rdoc/files/lib/wee/core/component_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/core/decoration_rb.html +133 -0
- data/doc/rdoc/files/lib/wee/core/presenter_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/core/snapshot_rb.html +113 -0
- data/doc/rdoc/files/lib/wee/core/valueholder_rb.html +110 -0
- data/doc/rdoc/files/lib/wee/core_rb.html +131 -0
- data/doc/rdoc/files/lib/wee/decoration_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/holder_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/html_canvas_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/html_writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/idgen_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/page_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/presenter_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/renderer/html/brushes_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/renderer/html/canvas_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/renderer/html/writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/rendering/html/brushes_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/rendering/html/canvas_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/rendering/html/writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/request_rb.html +113 -0
- data/doc/rdoc/files/lib/wee/requesthandler_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/response_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/session_rb.html +109 -0
- data/doc/rdoc/files/lib/wee/snapshot_ext_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/snapshot_rb.html +107 -0
- data/doc/rdoc/files/lib/wee/state_registry_rb.html +110 -0
- data/doc/rdoc/files/lib/wee/stuff_rb.html +144 -0
- data/doc/rdoc/files/lib/wee/utils/cache_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/webrick_rb.html +108 -0
- data/doc/rdoc/files/lib/wee_rb.html +132 -0
- data/doc/rdoc/fr_class_index.html +93 -0
- data/doc/rdoc/fr_file_index.html +51 -0
- data/doc/rdoc/fr_method_index.html +242 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/examples/ObjectSpaceBrowser.rb +199 -0
- data/examples/calendar.rb +366 -0
- data/examples/cc.rb +94 -0
- data/examples/draw.rb +91 -0
- data/examples/example.rb +223 -0
- data/examples/test.rb +66 -0
- data/examples/window.rb +53 -0
- data/lib/cache/cache.rb +9 -0
- data/lib/wee.rb +18 -8
- data/lib/wee/adaptors/webrick.rb +73 -0
- data/lib/wee/application.rb +69 -71
- data/lib/wee/context.rb +2 -12
- data/lib/wee/core.rb +15 -0
- data/lib/wee/core/callback.rb +108 -0
- data/lib/wee/core/component.rb +314 -0
- data/lib/wee/core/decoration.rb +129 -0
- data/lib/wee/core/presenter.rb +132 -0
- data/lib/wee/core/snapshot.rb +21 -0
- data/lib/wee/core/valueholder.rb +19 -0
- data/lib/wee/idgen.rb +13 -0
- data/lib/wee/page.rb +1 -1
- data/lib/wee/renderer/html/brushes.rb +435 -0
- data/lib/wee/renderer/html/canvas.rb +148 -0
- data/lib/wee/{html_writer.rb → renderer/html/writer.rb} +31 -16
- data/lib/wee/request.rb +57 -0
- data/lib/wee/requesthandler.rb +77 -0
- data/lib/wee/response.rb +77 -0
- data/lib/wee/session.rb +70 -64
- data/lib/wee/{snapshot.rb → snapshot_ext.rb} +4 -4
- data/test/components/calltest.rb +16 -0
- data/test/components/counter.rb +17 -0
- data/test/components/messagebox.rb +15 -0
- data/test/components/page.rb +14 -0
- data/test/components/page_decoration.rb +7 -0
- data/test/stress.rb +64 -0
- data/test/test_component.rb +106 -0
- data/test/test_html_canvas.rb +25 -0
- data/test/test_html_writer.rb +27 -0
- data/test/test_request.rb +13 -0
- data/test/utils/cross.rb +65 -0
- data/test/utils/generic_plotter.rb +28 -0
- data/test/utils/gnuplot.rb +31 -0
- data/test/utils/measure_memory.rb +9 -0
- data/test/utils/memory_plotter.rb +10 -0
- data/test/utils/object_plotter.rb +10 -0
- data/test/utils/webrick_background.rb +31 -0
- data/wee.gemspec +22 -0
- metadata +222 -18
- data/lib/wee/component.rb +0 -126
- data/lib/wee/delegate_decoration.rb +0 -22
- data/lib/wee/handler_registry.rb +0 -89
- data/lib/wee/holder.rb +0 -14
- data/lib/wee/html_canvas.rb +0 -379
- data/lib/wee/state_registry.rb +0 -173
- data/lib/wee/stuff.rb +0 -29
- data/lib/wee/webrick.rb +0 -15
data/examples/window.rb
ADDED
@@ -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
|
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
|
-
|
9
|
-
require 'wee/
|
10
|
-
|
11
|
-
require 'wee/
|
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
|
data/lib/wee/application.rb
CHANGED
@@ -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
|
-
|
7
|
-
setup_session_id_generator
|
7
|
+
# The generator used for creating unique request handler id's.
|
8
8
|
|
9
|
-
|
9
|
+
attr_accessor :id_generator
|
10
10
|
|
11
|
-
|
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
|
-
|
17
|
-
@session_cnt = rand(1000_000)
|
18
|
-
end
|
13
|
+
attr_accessor :max_request_handlers
|
19
14
|
|
20
|
-
|
21
|
-
|
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
|
-
|
24
|
-
if
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
69
|
-
|
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
|
-
|
73
|
-
|
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
|
-
|
77
|
-
Marshal.load(File.read(filename))
|
78
|
-
end
|
77
|
+
private
|
79
78
|
|
80
|
-
def
|
81
|
-
|
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
|
-
|
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
|
-
|
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
|