waves 0.8.2 → 0.9.0

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 (166) hide show
  1. data/bin/waves +4 -3
  2. data/doc/VERSION +1 -1
  3. data/lib/waves.rb +52 -40
  4. data/lib/{caches → waves/caches}/file.rb +3 -1
  5. data/lib/waves/caches/memcached.rb +56 -0
  6. data/lib/{caches → waves/caches}/simple.rb +6 -7
  7. data/lib/{caches → waves/caches}/synchronized.rb +15 -1
  8. data/lib/{commands → waves/commands}/console.rb +4 -4
  9. data/lib/{commands → waves/commands}/generate.rb +6 -5
  10. data/lib/{commands → waves/commands}/help.rb +0 -0
  11. data/lib/{commands → waves/commands}/server.rb +1 -1
  12. data/lib/{dispatchers → waves/dispatchers}/base.rb +17 -31
  13. data/lib/waves/dispatchers/default.rb +19 -0
  14. data/lib/{ext → waves/ext}/float.rb +0 -0
  15. data/lib/{ext → waves/ext}/hash.rb +0 -0
  16. data/lib/{ext → waves/ext}/integer.rb +16 -1
  17. data/lib/{ext → waves/ext}/kernel.rb +3 -7
  18. data/lib/{ext → waves/ext}/module.rb +3 -3
  19. data/lib/{ext → waves/ext}/object.rb +2 -0
  20. data/lib/waves/ext/string.rb +73 -0
  21. data/lib/{ext → waves/ext}/symbol.rb +0 -1
  22. data/lib/{ext → waves/ext}/tempfile.rb +0 -0
  23. data/lib/waves/ext/time.rb +5 -0
  24. data/lib/{foundations → waves/foundations}/classic.rb +9 -21
  25. data/lib/{foundations → waves/foundations}/compact.rb +15 -20
  26. data/lib/waves/foundations/rest.rb +311 -0
  27. data/lib/waves/helpers/basic.rb +13 -0
  28. data/lib/{helpers → waves/helpers}/doc_type.rb +3 -0
  29. data/lib/waves/helpers/form.rb +94 -0
  30. data/lib/waves/helpers/formatting.rb +14 -0
  31. data/lib/waves/layers/mvc.rb +65 -0
  32. data/lib/{layers → waves/layers}/mvc/controllers.rb +0 -0
  33. data/lib/{layers → waves/layers}/mvc/extensions.rb +23 -11
  34. data/lib/{layers → waves/layers}/orm/migration.rb +0 -0
  35. data/lib/{layers → waves/layers}/orm/providers/active_record.rb +2 -5
  36. data/lib/{layers → waves/layers}/orm/providers/active_record/migrations/empty.rb.erb +0 -0
  37. data/lib/{layers → waves/layers}/orm/providers/active_record/tasks/generate.rb +1 -1
  38. data/lib/{layers → waves/layers}/orm/providers/active_record/tasks/schema.rb +1 -1
  39. data/lib/{layers → waves/layers}/orm/providers/data_mapper.rb +0 -0
  40. data/lib/{layers → waves/layers}/orm/providers/filebase.rb +0 -0
  41. data/lib/{layers → waves/layers}/orm/providers/sequel.rb +28 -29
  42. data/lib/{layers → waves/layers}/orm/providers/sequel/migrations/empty.rb.erb +0 -0
  43. data/lib/{layers → waves/layers}/orm/providers/sequel/tasks/generate.rb +1 -1
  44. data/lib/{layers → waves/layers}/orm/providers/sequel/tasks/schema.rb +2 -0
  45. data/lib/waves/layers/rack/rack_cache.rb +32 -0
  46. data/lib/waves/layers/renderers/erubis.rb +52 -0
  47. data/lib/waves/layers/renderers/haml.rb +67 -0
  48. data/lib/waves/layers/renderers/markaby.rb +41 -0
  49. data/lib/waves/layers/text/inflect/english.rb +42 -0
  50. data/lib/waves/matchers/accept.rb +47 -0
  51. data/lib/waves/matchers/ext.rb +27 -0
  52. data/lib/waves/matchers/path.rb +72 -0
  53. data/lib/waves/matchers/query.rb +43 -0
  54. data/lib/waves/matchers/request.rb +86 -0
  55. data/lib/waves/matchers/requested.rb +31 -0
  56. data/lib/{matchers → waves/matchers}/resource.rb +8 -1
  57. data/lib/waves/matchers/traits.rb +30 -0
  58. data/lib/waves/matchers/uri.rb +69 -0
  59. data/lib/waves/media/mime_types.rb +542 -0
  60. data/lib/waves/renderers/mixin.rb +9 -0
  61. data/lib/waves/request/accept.rb +92 -0
  62. data/lib/{runtime → waves/request}/request.rb +77 -61
  63. data/lib/waves/resources/file_mixin.rb +11 -0
  64. data/lib/{resources → waves/resources}/mixin.rb +42 -44
  65. data/lib/waves/resources/paths.rb +132 -0
  66. data/lib/waves/response/client_errors.rb +10 -0
  67. data/lib/waves/response/packaged.rb +19 -0
  68. data/lib/waves/response/redirects.rb +35 -0
  69. data/lib/{runtime → waves/response}/response.rb +29 -11
  70. data/lib/{runtime → waves/response}/response_mixin.rb +30 -17
  71. data/lib/waves/runtime/applications.rb +18 -0
  72. data/lib/{runtime → waves/runtime}/configuration.rb +31 -25
  73. data/lib/waves/runtime/console.rb +24 -0
  74. data/lib/{runtime → waves/runtime}/logger.rb +3 -3
  75. data/lib/{runtime → waves/runtime}/mocks.rb +2 -2
  76. data/lib/waves/runtime/rackup.rb +37 -0
  77. data/lib/waves/runtime/runtime.rb +48 -0
  78. data/lib/waves/runtime/server.rb +33 -0
  79. data/lib/{servers → waves/servers}/base.rb +0 -0
  80. data/lib/{servers → waves/servers}/mongrel.rb +0 -0
  81. data/lib/{servers → waves/servers}/webrick.rb +0 -0
  82. data/lib/{tasks → waves/tasks}/gem.rb +0 -0
  83. data/lib/{tasks → waves/tasks}/generate.rb +0 -0
  84. data/lib/waves/views/cassy.rb +173 -0
  85. data/lib/{views → waves/views}/errors.rb +8 -7
  86. data/lib/waves/views/mixin.rb +23 -0
  87. data/lib/waves/views/templated.rb +40 -0
  88. data/samples/basic/basic_startup.rb +70 -0
  89. data/samples/basic/config.ru +9 -0
  90. data/samples/blog/configurations/development.rb +17 -16
  91. data/samples/blog/configurations/production.rb +0 -11
  92. data/samples/blog/resources/entry.rb +3 -3
  93. data/samples/blog/resources/map.rb +10 -3
  94. data/samples/blog/startup.rb +4 -3
  95. data/templates/classic/Rakefile +28 -29
  96. data/templates/classic/configurations/default.rb.erb +8 -3
  97. data/templates/classic/configurations/development.rb.erb +1 -20
  98. data/templates/classic/configurations/production.rb.erb +2 -16
  99. data/templates/classic/public/images/favicon.ico +0 -0
  100. data/templates/classic/resources/server.rb.erb +9 -0
  101. data/templates/classic/startup.rb.erb +3 -3
  102. data/templates/classic/views/css.rb.erb +14 -0
  103. data/templates/classic/views/default.rb.erb +17 -0
  104. data/templates/classic/views/errors.rb.erb +10 -0
  105. data/templates/classic/views/pages.rb.erb +14 -0
  106. data/templates/compact/startup.rb.erb +8 -3
  107. data/test/ext/object.rb +55 -0
  108. data/test/ext/shortcuts.rb +73 -0
  109. data/test/helpers.rb +17 -0
  110. data/test/match/accept.rb +78 -0
  111. data/test/match/ext.rb +156 -0
  112. data/test/match/methods.rb +22 -0
  113. data/test/match/params.rb +33 -0
  114. data/test/match/path.rb +106 -0
  115. data/test/match/query.rb +60 -0
  116. data/test/match/request.rb +91 -0
  117. data/test/match/requested.rb +149 -0
  118. data/test/match/uri.rb +136 -0
  119. data/test/process/request.rb +75 -0
  120. data/test/process/resource.rb +53 -0
  121. data/test/resources/path.rb +166 -0
  122. data/test/runtime/configurations.rb +19 -0
  123. data/test/runtime/request.rb +63 -0
  124. data/test/runtime/response.rb +85 -0
  125. data/test/views/views.rb +40 -0
  126. metadata +243 -157
  127. data/lib/caches/memcached.rb +0 -40
  128. data/lib/dispatchers/default.rb +0 -25
  129. data/lib/ext/string.rb +0 -20
  130. data/lib/helpers/basic.rb +0 -11
  131. data/lib/helpers/extended.rb +0 -21
  132. data/lib/helpers/form.rb +0 -42
  133. data/lib/helpers/formatting.rb +0 -30
  134. data/lib/helpers/layouts.rb +0 -37
  135. data/lib/helpers/model.rb +0 -37
  136. data/lib/helpers/view.rb +0 -22
  137. data/lib/layers/inflect/english.rb +0 -67
  138. data/lib/layers/mvc.rb +0 -54
  139. data/lib/layers/renderers/erubis.rb +0 -60
  140. data/lib/layers/renderers/haml.rb +0 -47
  141. data/lib/layers/renderers/markaby.rb +0 -29
  142. data/lib/matchers/accept.rb +0 -21
  143. data/lib/matchers/base.rb +0 -30
  144. data/lib/matchers/content_type.rb +0 -17
  145. data/lib/matchers/path.rb +0 -67
  146. data/lib/matchers/query.rb +0 -21
  147. data/lib/matchers/request.rb +0 -27
  148. data/lib/matchers/traits.rb +0 -19
  149. data/lib/matchers/uri.rb +0 -20
  150. data/lib/renderers/mixin.rb +0 -36
  151. data/lib/resources/paths.rb +0 -34
  152. data/lib/runtime/console.rb +0 -23
  153. data/lib/runtime/mime_types.rb +0 -536
  154. data/lib/runtime/monitor.rb +0 -32
  155. data/lib/runtime/runtime.rb +0 -67
  156. data/lib/runtime/server.rb +0 -20
  157. data/lib/runtime/session.rb +0 -27
  158. data/lib/runtime/worker.rb +0 -86
  159. data/lib/views/mixin.rb +0 -62
  160. data/samples/blog/blog.db +0 -0
  161. data/samples/blog/log/waves.production +0 -3
  162. data/templates/classic/resources/map.rb.erb +0 -8
  163. data/templates/classic/templates/errors/not_found_404.mab +0 -7
  164. data/templates/classic/templates/errors/server_error_500.mab +0 -7
  165. data/templates/classic/templates/layouts/default.mab +0 -14
  166. data/templates/classic/tmp/sessions/.gitignore +0 -0
@@ -0,0 +1,10 @@
1
+ module Waves
2
+ class Response
3
+ module ClientError ; end
4
+ module ClientErrors
5
+ class NotFound < Packaged[404]
6
+ include ClientError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ module Waves
2
+ class Response
3
+
4
+ class Packaged < Exception
5
+ def self.[]( status )
6
+ Class.new( self ) do
7
+ define_method( :status ) { status }
8
+ end
9
+ end
10
+ def call( response )
11
+ response.status = status.to_s
12
+ end
13
+ def message
14
+ "HTTP Reponse #{status}"
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ module Waves
2
+ class Response
3
+
4
+ module Redirect ; end
5
+
6
+ # Redirects are raised by applications and rescued by the Waves
7
+ # dispatcher and used to set the response status and location.
8
+
9
+ module Redirects
10
+
11
+ class Found < Packaged[302]
12
+ include Redirect
13
+ attr_reader :location
14
+ def initialize( location )
15
+ @location = location ; super()
16
+ end
17
+ def call( response )
18
+ response.location = location
19
+ super( response )
20
+ end
21
+ end
22
+
23
+ class NotModified < Packaged[304]
24
+ include Redirect
25
+ def call ( response )
26
+ %w( Allow Content-Encoding Content-Language Content-Length Content-MD5
27
+ Content-Type Last-Modified ).each { |h| response.headers.delete( h ) }
28
+ response.cache_control = 'public'
29
+ response.body = []
30
+ super( response )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,10 +1,10 @@
1
1
  module Waves
2
-
2
+
3
3
  # Waves::Response represents an HTTP response and has methods for constructing a response.
4
4
  # These include setters for +content_type+, +content_length+, +location+, and +expires+
5
5
  # headers. You may also set the headers directly using the [] operator.
6
6
  # See Rack::Response for documentation of any method not defined here.
7
-
7
+
8
8
  class Response
9
9
 
10
10
  attr_reader :request
@@ -14,13 +14,21 @@ module Waves
14
14
  @request = request
15
15
  @response = Rack::Response.new
16
16
  end
17
-
17
+
18
18
  def rack_response; @response; end
19
19
 
20
- %w( Content-Type Content-Length Location Expires ).each do |header|
21
- define_method( header.downcase.gsub('-','_')+ '=' ) do | val |
22
- @response[header] = val
23
- end
20
+ %w( Status Content-Type Content-Length Cache-Control Location Expires ).each do |header|
21
+ name = header.downcase.tr( '-','_' )
22
+ define_method("#{name}=") {|val| @response[header] = val }
23
+ define_method("#{name}") { @response[header] }
24
+ end
25
+
26
+ def last_modified
27
+ @last_modified
28
+ end
29
+
30
+ def last_modified=( timestamp )
31
+ @last_modified = timestamp
24
32
  end
25
33
 
26
34
  # Returns the sessions associated with the request, allowing you to set values within it.
@@ -31,12 +39,22 @@ module Waves
31
39
  # attempt to further modify the response once this method is called. You don't usually
32
40
  # need to call it yourself, since it is called by the dispatcher once request processing
33
41
  # is finished.
34
- def finish ; @response.finish ; end
42
+ def finish
43
+ @response['Last-Modified'] = @last_modified.to_http_timestamp if @last_modified
44
+ @response.finish
45
+ end
35
46
 
36
47
  # Methods not explicitly defined by Waves::Response are delegated to Rack::Response.
37
- # Check the Rack documentation for more informations
38
- def method_missing(name,*args)
39
- @response.send(name,*args)
48
+ # Check the Rack documentation for more information
49
+ extend Forwardable
50
+ def method_missing( name, *args, &block )
51
+ if @response.respond_to?( name )
52
+ # avoid having to use method missing in the future
53
+ self.class.class_eval { def_delegator :@response, name }
54
+ @response.send( name, *args, &block )
55
+ else
56
+ super
57
+ end
40
58
  end
41
59
 
42
60
  end
@@ -10,7 +10,7 @@ module Waves
10
10
  # Access the response.
11
11
  def response; request.response; end
12
12
 
13
- def resource ; traits.waves.resource ; end
13
+ def resource; traits.waves.resource || ( self if self.kind_of? Waves::Resources::Mixin ) ; end
14
14
 
15
15
  def traits ; request.traits ; end
16
16
 
@@ -23,35 +23,48 @@ module Waves
23
23
 
24
24
  # Both the query and capture merged together
25
25
  def params
26
- query = captured ? request.query.merge( captured.to_h ) : request.query
27
- @params ||= Waves::Request::Query.new( query )
26
+ @params ||= Waves::Request::Query.new( captured ?
27
+ request.query.merge( captured.to_h ) : request.query )
28
28
  end
29
29
 
30
- %w( session path url domain not_found ).each do | m |
30
+ %w( session path url domain ).each do | m |
31
31
  define_method( m ) { request.send( m ) }
32
32
  end
33
33
 
34
- # Issue a redirect for the given location.
35
- def redirect(location, status = '302'); request.redirect(location, status); end
36
- # Access the Waves::Logger.
37
34
  def log; Waves::Logger; end
38
- # access stuff from an app
39
- def app_name ; self.class.rootname.snake_case.to_sym ; end
40
- def app ; eval( "::#{app_name.to_s.camel_case}" ) ; end
35
+
36
+ def app ; self.class.root ; end
37
+
38
+ def main ; Waves.main ; end
39
+
41
40
  def paths( rname = nil )
42
- ( rname.nil? ? resource.class.paths : app::Resources[ rname ].paths ).new( request )
41
+ ( rname ? app::Resources[ rname ].paths : resource.class.paths ).new
43
42
  end
44
43
 
45
- # these take strings or operate on the path by default
46
- def basename( str = nil ) ; ( str or path ).sub(/\.([^\.]+)$/,'') ; end
44
+ def http_cache( last_modified )
45
+ response.last_modified = last_modified
46
+ modified?( last_modified ) ? yield : not_modified
47
+ end
47
48
 
48
- def extension( str = nil )
49
- ( m = ( str or path ).match(/\.([^\.]+)$/) ) ? m[1] : nil
49
+ def modified?( last_modified )
50
+ request.if_modified_since.nil? ||
51
+ last_modified > request.if_modified_since
50
52
  end
51
53
 
52
- def render( path, assigns = {} )
53
- Waves::Views::Base.new( request ).render( path, assigns )
54
+ # Raise a not found exception.
55
+ def not_found
56
+ raise Waves::Response::ClientErrors::NotFound.new
54
57
  end
58
+
59
+ # Issue a redirect for the given path.
60
+ def redirect( path )
61
+ raise Waves::Response::Redirects::Found.new( path )
62
+ end
63
+
64
+ def not_modified
65
+ raise Waves::Response::Redirects::NotModified.new
66
+ end
67
+
55
68
  end
56
69
 
57
70
  end
@@ -0,0 +1,18 @@
1
+ module Waves
2
+
3
+ class Applications < Array
4
+ def []( name ) ; self.find { |app| app.name.snake_case.to_sym == name } ; end
5
+ end
6
+
7
+ def self.config; instance.config ; end
8
+
9
+ # The list of all loaded applications
10
+ def self.applications ; @applications ||= Applications.new ; end
11
+
12
+ # Access the principal Waves application.
13
+ def self.main ; applications.first ; end
14
+
15
+ # Register a module as a Waves application.
16
+ def self.<< ( app ) ; applications << app ; end
17
+
18
+ end
@@ -11,7 +11,7 @@ module Waves
11
11
 
12
12
  # Get the value of the given attribute. Typically, you wouldn't
13
13
  # use this directly.
14
- def self.[]( name ) ; send "_#{name}" ; end
14
+ def self.[]( name ) ; send "_#{name}" rescue nil ; end
15
15
 
16
16
  # Define a new attribute. After calling this, you can get and set the value
17
17
  # using the attribute name as the method
@@ -22,7 +22,7 @@ module Waves
22
22
  end
23
23
  self[ name ] = nil
24
24
  end
25
-
25
+
26
26
  def self.attributes( *names )
27
27
  names.each { |name| attribute( name ) }
28
28
  end
@@ -31,39 +31,47 @@ module Waves
31
31
 
32
32
  # The Default configuration defines sensible defaults for attributes required by Waves.
33
33
  class Default < Base
34
-
34
+
35
35
  # define where a server should listen
36
36
  # can be overridden by -p and -h options
37
37
  attributes( :host, :port, :ports )
38
-
38
+
39
39
  # which server to use, ex: Waves::Servers::Mongrel
40
40
  attribute( :server )
41
-
41
+
42
42
  # where will the logger write to? can be a IO object or a pathname
43
43
  # also can set the level here to :fatal, :debug, :warn, :info
44
44
  attribute( :log )
45
-
45
+
46
46
  # which modules are going to be reloaded on each request?
47
47
  attribute( :reloadable )
48
-
48
+
49
49
  # which resource to use as the "main" resource for this server
50
- attribute( :resource )
51
-
50
+ attribute( :resource )
51
+
52
52
  # parameters for the database connection, varies by ORM
53
53
  attribute( :database )
54
-
54
+
55
55
  # set the debug mode flag; typically done in dev / test configurations
56
56
  attribute( :debug )
57
-
57
+
58
58
  # what object to use as the main Waves cache
59
59
  attribute( :cache )
60
-
60
+
61
61
  # do you want to run a console thread (ex: LiveConsole)
62
62
  attribute( :console )
63
63
 
64
+ # what dispatcher do you want to use
65
+ attribute( :dispatcher )
66
+
64
67
  # are there any gems we need to check for on startup?
65
- attributes( :dependencies )
66
-
68
+ def self.dependencies( list )
69
+ list.each do |d|
70
+ gem d[:name], d[:version]
71
+ require d[:load] if d[:load]
72
+ end
73
+ end
74
+
67
75
  # Provides access to the Waves::MimeTypes class via the configuration. You
68
76
  # can override #mime_types to return your own MIME types repository class.
69
77
  def self.mime_types
@@ -76,25 +84,23 @@ module Waves
76
84
  if block_given?
77
85
  self['application'] = Rack::Builder.new( &block )
78
86
  else
79
- self['application']
87
+ self['application'] ||= Rack::Builder.new
80
88
  end
81
89
  end
82
90
 
91
+ def self.use( middleware, options )
92
+ application.use( middleware, options )
93
+ end
94
+
83
95
  # default options
84
- debug true
96
+ debug false
85
97
  log :level => :info, :output => $stderr
86
98
  reloadable []
87
99
  dependencies []
88
100
  server Waves::Servers::WEBrick
89
- application {
90
- use ::Rack::ShowExceptions
91
- use Rack::Session::Cookie, :key => 'rack.session',
92
- # :domain => 'foo.com',
93
- :path => '/',
94
- :expire_after => 2592000,
95
- :secret => 'Change it'
96
- run ::Waves::Dispatchers::Default.new
97
- }
101
+ application.use ::Rack::ShowExceptions
102
+ dispatcher Waves::Dispatchers::Default
103
+
98
104
  end
99
105
  end
100
106
  end
@@ -0,0 +1,24 @@
1
+ require 'waves/runtime/mocks'
2
+
3
+ module Waves
4
+
5
+ class Console
6
+
7
+ attr_accessor :options
8
+
9
+ include Waves::Runtime
10
+
11
+ def self.load( options={} )
12
+ Object.instance_eval { include Waves::Mocks }
13
+ new( options )
14
+ end
15
+
16
+
17
+ def initialize( options = {} )
18
+ @options = options
19
+ load # load the runtime
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -24,9 +24,9 @@ module Waves
24
24
  self
25
25
  end
26
26
 
27
- # Forwards logging methods to the logger.
28
- def self.method_missing(name,*args,&block)
29
- @log.send name,*args, &block if @log
27
+ class << self
28
+ extend Forwardable
29
+ def_delegators :@log, *%w( debug info warn error )
30
30
  end
31
31
 
32
32
  end
@@ -1,6 +1,6 @@
1
1
  module Waves
2
2
  module Mocks
3
-
3
+
4
4
  def dispatcher ; Waves::Dispatchers::Default ; end
5
5
  def request ; Rack::MockRequest.new( dispatcher.new ) ; end
6
6
  def env( uri, opts ) ; Rack::MockRequest.env_for( uri, opts ) ; end
@@ -9,6 +9,6 @@ module Waves
9
9
  def post( uri, opts = {} ) ; request.post( uri, opts ) ; end
10
10
  def delete( uri, opts = {} ) ; request.delete( uri, opts ) ; end
11
11
  def head( uri, opts = {} ) ; request.request( 'HEAD', uri, opts ) ; end
12
-
12
+
13
13
  end
14
14
  end
@@ -0,0 +1,37 @@
1
+ module Waves
2
+
3
+ # Runtime to use with Rackup specifically.
4
+ #
5
+ # The actual Rack application is built using `config.application`
6
+ # (see runtime/configuration.rb), not in the .ru file. Rackup
7
+ # expects to be used in the context of an already-running server.
8
+ # See the documentation for your webserver and Rack for details.
9
+ #
10
+ # Your config.ru file should minimally look something like this:
11
+ #
12
+ # require "waves"
13
+ # require "waves/runtime/rackup"
14
+ #
15
+ # run Waves::Rackup.load
16
+ #
17
+ class Rackup
18
+
19
+ attr_accessor :options
20
+
21
+ include Waves::Runtime
22
+
23
+ # Load the runtime and return an application.
24
+ def self.load(options = {})
25
+ new( options )
26
+ config.application.to_app
27
+ end
28
+
29
+ def initialize( options = {} )
30
+ @options = options
31
+ load # load runtime
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
@@ -0,0 +1,48 @@
1
+ require 'forwardable'
2
+
3
+ module Waves
4
+
5
+ module Runtime
6
+
7
+ class << self; attr_accessor :instance; end
8
+
9
+ # Create a new Waves application instance.
10
+ def load
11
+ Dir.chdir( options[:directory] ) if options[:directory]
12
+ Kernel.load( options[:startup] || 'startup.rb' )
13
+ Runtime.instance = self
14
+ options[:logger] ||= logger
15
+ end
16
+
17
+ # The 'mode' of the runtime determines which configuration it will run under.
18
+ def mode ; options[:mode]||:development ; end
19
+
20
+ # Returns true if debug was set to true in the current configuration.
21
+ def debug? ; options[:debugger] or config.debug ; end
22
+
23
+ # Returns the current configuration.
24
+ def config ; Waves.main[:configurations][ mode ] ; end
25
+
26
+ # Reload the modules specified in the current configuration.
27
+ def reload ; config.reloadable.each { |mod| mod.reload } ; end
28
+
29
+ # Start and / or access the Waves::Logger instance.
30
+ def logger ; @log ||= Waves::Logger.start ; end
31
+
32
+ # Provides access to the server mutex for thread-safe operation.
33
+ def synchronize( &block ) ; ( @mutex ||= Mutex.new ).synchronize( &block ) ; end
34
+ def synchronize? ; !options[ :turbo ] ; end
35
+
36
+ end
37
+
38
+ class << self
39
+
40
+ # Returns the most recently created instance of Waves::Runtime.
41
+ def instance ; Waves::Runtime.instance ; end
42
+
43
+ extend Forwardable
44
+ def_delegators :instance, *%w( mode debug? config reload logger synchronize synchronize? )
45
+
46
+ end
47
+
48
+ end