waves 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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