whirled_peas 0.7.0 → 0.10.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 (220) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +25 -0
  4. data/README.md +467 -120
  5. data/Rakefile +1 -20
  6. data/bin/easing +33 -0
  7. data/bin/reset_cursor +11 -0
  8. data/bin/screen_test +68 -0
  9. data/examples/graph.rb +54 -0
  10. data/examples/intro.rb +3 -3
  11. data/examples/scrolling.rb +5 -4
  12. data/lib/data/themes.yaml +13 -0
  13. data/lib/whirled_peas.rb +12 -6
  14. data/lib/whirled_peas/animator.rb +5 -0
  15. data/lib/whirled_peas/animator/debug_consumer.rb +17 -0
  16. data/lib/whirled_peas/animator/easing.rb +72 -0
  17. data/lib/whirled_peas/animator/frame.rb +5 -0
  18. data/lib/whirled_peas/animator/frameset.rb +33 -0
  19. data/lib/whirled_peas/animator/producer.rb +35 -0
  20. data/lib/whirled_peas/animator/renderer_consumer.rb +31 -0
  21. data/lib/whirled_peas/command.rb +5 -0
  22. data/lib/whirled_peas/command/base.rb +86 -0
  23. data/lib/whirled_peas/command/config_command.rb +43 -0
  24. data/lib/whirled_peas/command/debug.rb +21 -0
  25. data/lib/whirled_peas/command/fonts.rb +22 -0
  26. data/lib/whirled_peas/command/frame_command.rb +34 -0
  27. data/lib/whirled_peas/command/frames.rb +24 -0
  28. data/lib/whirled_peas/command/help.rb +38 -0
  29. data/lib/whirled_peas/command/play.rb +111 -0
  30. data/lib/whirled_peas/command/record.rb +57 -0
  31. data/lib/whirled_peas/command/still.rb +29 -0
  32. data/lib/whirled_peas/command/themes.rb +76 -0
  33. data/lib/whirled_peas/command_line.rb +24 -212
  34. data/lib/whirled_peas/config.rb +56 -6
  35. data/lib/whirled_peas/device.rb +5 -0
  36. data/lib/whirled_peas/device/null_device.rb +8 -0
  37. data/lib/whirled_peas/device/output_file.rb +19 -0
  38. data/lib/whirled_peas/device/screen.rb +26 -0
  39. data/lib/whirled_peas/graphics/composer.rb +23 -2
  40. data/lib/whirled_peas/graphics/container_painter.rb +91 -0
  41. data/lib/whirled_peas/graphics/content_dimensions.rb +19 -0
  42. data/lib/whirled_peas/graphics/content_painter.rb +20 -0
  43. data/lib/whirled_peas/graphics/graph_dimensions.rb +12 -0
  44. data/lib/whirled_peas/graphics/graph_painter.rb +97 -0
  45. data/lib/whirled_peas/graphics/grid_painter.rb +1 -4
  46. data/lib/whirled_peas/graphics/painter.rb +10 -0
  47. data/lib/whirled_peas/graphics/renderer.rb +8 -2
  48. data/lib/whirled_peas/graphics/text_painter.rb +7 -11
  49. data/lib/whirled_peas/settings/border.rb +25 -4
  50. data/lib/whirled_peas/settings/container_settings.rb +2 -4
  51. data/lib/whirled_peas/settings/element_settings.rb +12 -3
  52. data/lib/whirled_peas/settings/graph_settings.rb +21 -0
  53. data/lib/whirled_peas/settings/grid_settings.rb +7 -0
  54. data/lib/whirled_peas/settings/text_settings.rb +1 -0
  55. data/lib/whirled_peas/settings/theme.rb +40 -0
  56. data/lib/whirled_peas/settings/theme_library.rb +63 -0
  57. data/lib/whirled_peas/utils/ansi.rb +13 -0
  58. data/lib/whirled_peas/utils/file_handler.rb +57 -0
  59. data/lib/whirled_peas/version.rb +1 -1
  60. data/screen_test/elements/box.frame +1 -1
  61. data/screen_test/elements/box.rb +1 -1
  62. data/screen_test/elements/graph.frame +1 -0
  63. data/screen_test/elements/graph.rb +12 -0
  64. data/screen_test/elements/grid.frame +1 -1
  65. data/screen_test/elements/grid.rb +1 -1
  66. data/screen_test/elements/screen_overflow_x.frame +1 -1
  67. data/screen_test/elements/screen_overflow_x.rb +1 -1
  68. data/screen_test/elements/screen_overflow_y.frame +1 -1
  69. data/screen_test/elements/screen_overflow_y.rb +1 -1
  70. data/screen_test/elements/text.frame +1 -1
  71. data/screen_test/elements/text.rb +1 -1
  72. data/screen_test/elements/text_multiline.frame +1 -1
  73. data/screen_test/elements/text_multiline.rb +1 -1
  74. data/screen_test/elements/theme.frame +1 -0
  75. data/screen_test/elements/theme.rb +26 -0
  76. data/screen_test/settings/align/box_around.frame +1 -1
  77. data/screen_test/settings/align/box_around.rb +1 -1
  78. data/screen_test/settings/align/box_between.frame +1 -1
  79. data/screen_test/settings/align/box_between.rb +1 -1
  80. data/screen_test/settings/align/box_center.frame +1 -1
  81. data/screen_test/settings/align/box_center.rb +1 -1
  82. data/screen_test/settings/align/box_default.frame +1 -1
  83. data/screen_test/settings/align/box_default.rb +1 -1
  84. data/screen_test/settings/align/box_evenly.frame +1 -1
  85. data/screen_test/settings/align/box_evenly.rb +1 -1
  86. data/screen_test/settings/align/box_left.frame +1 -1
  87. data/screen_test/settings/align/box_left.rb +1 -1
  88. data/screen_test/settings/align/box_right.frame +1 -1
  89. data/screen_test/settings/align/box_right.rb +1 -1
  90. data/screen_test/settings/align/children_center.frame +1 -1
  91. data/screen_test/settings/align/children_center.rb +1 -1
  92. data/screen_test/settings/align/children_left.frame +1 -1
  93. data/screen_test/settings/align/children_left.rb +1 -1
  94. data/screen_test/settings/align/children_right.frame +1 -1
  95. data/screen_test/settings/align/children_right.rb +1 -1
  96. data/screen_test/settings/align/grid_center.frame +1 -1
  97. data/screen_test/settings/align/grid_center.rb +1 -1
  98. data/screen_test/settings/align/grid_default.frame +1 -1
  99. data/screen_test/settings/align/grid_default.rb +1 -1
  100. data/screen_test/settings/align/grid_left.frame +1 -1
  101. data/screen_test/settings/align/grid_left.rb +1 -1
  102. data/screen_test/settings/align/grid_right.frame +1 -1
  103. data/screen_test/settings/align/grid_right.rb +1 -1
  104. data/screen_test/settings/ansi/bold.frame +1 -1
  105. data/screen_test/settings/ansi/bold.rb +1 -1
  106. data/screen_test/settings/ansi/color.frame +1 -1
  107. data/screen_test/settings/ansi/color.rb +1 -1
  108. data/screen_test/settings/ansi/underline.frame +1 -1
  109. data/screen_test/settings/ansi/underline.rb +1 -1
  110. data/screen_test/settings/border.frame +1 -1
  111. data/screen_test/settings/border.rb +1 -1
  112. data/screen_test/settings/flow/box_b2t.frame +1 -1
  113. data/screen_test/settings/flow/box_b2t.rb +1 -1
  114. data/screen_test/settings/flow/box_l2r.frame +1 -1
  115. data/screen_test/settings/flow/box_l2r.rb +1 -1
  116. data/screen_test/settings/flow/box_r2l.frame +1 -1
  117. data/screen_test/settings/flow/box_r2l.rb +1 -1
  118. data/screen_test/settings/flow/box_t2b.frame +1 -1
  119. data/screen_test/settings/flow/box_t2b.rb +1 -1
  120. data/screen_test/settings/flow/grid_b2t.frame +1 -1
  121. data/screen_test/settings/flow/grid_b2t.rb +2 -2
  122. data/screen_test/settings/flow/grid_l2r.frame +1 -1
  123. data/screen_test/settings/flow/grid_l2r.rb +2 -2
  124. data/screen_test/settings/flow/grid_r2l.frame +1 -1
  125. data/screen_test/settings/flow/grid_r2l.rb +2 -2
  126. data/screen_test/settings/flow/grid_t2b.frame +1 -1
  127. data/screen_test/settings/flow/grid_t2b.rb +2 -2
  128. data/screen_test/settings/height/box.frame +1 -1
  129. data/screen_test/settings/height/box.rb +1 -1
  130. data/screen_test/settings/height/box_border_sizing.frame +1 -1
  131. data/screen_test/settings/height/box_border_sizing.rb +1 -1
  132. data/screen_test/settings/height/grid.frame +1 -1
  133. data/screen_test/settings/height/grid.rb +1 -1
  134. data/screen_test/settings/height/overflow_box.frame +1 -1
  135. data/screen_test/settings/height/overflow_box.rb +1 -1
  136. data/screen_test/settings/height/overflow_box_l2r.frame +1 -1
  137. data/screen_test/settings/height/overflow_box_l2r.rb +1 -1
  138. data/screen_test/settings/height/overflow_box_t2b.frame +1 -1
  139. data/screen_test/settings/height/overflow_box_t2b.rb +1 -1
  140. data/screen_test/settings/height/overflow_grid.frame +1 -1
  141. data/screen_test/settings/height/overflow_grid.rb +1 -1
  142. data/screen_test/settings/margin.frame +1 -1
  143. data/screen_test/settings/margin.rb +1 -1
  144. data/screen_test/settings/padding.frame +1 -1
  145. data/screen_test/settings/padding.rb +1 -1
  146. data/screen_test/settings/position/box_left.frame +1 -1
  147. data/screen_test/settings/position/box_left.rb +1 -1
  148. data/screen_test/settings/position/box_left_negative.frame +1 -1
  149. data/screen_test/settings/position/box_left_negative.rb +1 -1
  150. data/screen_test/settings/position/box_top.frame +1 -1
  151. data/screen_test/settings/position/box_top.rb +1 -1
  152. data/screen_test/settings/position/box_top_negative.frame +1 -1
  153. data/screen_test/settings/position/box_top_negative.rb +1 -1
  154. data/screen_test/settings/position/grid_left.frame +1 -1
  155. data/screen_test/settings/position/grid_left.rb +1 -1
  156. data/screen_test/settings/position/grid_left_negative.frame +1 -1
  157. data/screen_test/settings/position/grid_left_negative.rb +1 -1
  158. data/screen_test/settings/position/grid_top.frame +1 -1
  159. data/screen_test/settings/position/grid_top.rb +1 -1
  160. data/screen_test/settings/position/grid_top_negative.frame +1 -1
  161. data/screen_test/settings/position/grid_top_negative.rb +1 -1
  162. data/screen_test/settings/scroll/horiz_box.frame +1 -1
  163. data/screen_test/settings/scroll/horiz_box.rb +1 -1
  164. data/screen_test/settings/scroll/horiz_box_align_center.rb +1 -1
  165. data/screen_test/settings/scroll/horiz_box_align_right.rb +1 -1
  166. data/screen_test/settings/scroll/vert_box.frame +1 -1
  167. data/screen_test/settings/scroll/vert_box.rb +1 -1
  168. data/screen_test/settings/title_font.frame +1 -1
  169. data/screen_test/settings/title_font.rb +1 -1
  170. data/screen_test/settings/valign/box_around.frame +1 -1
  171. data/screen_test/settings/valign/box_around.rb +1 -1
  172. data/screen_test/settings/valign/box_between.frame +1 -1
  173. data/screen_test/settings/valign/box_between.rb +1 -1
  174. data/screen_test/settings/valign/box_bottom.frame +1 -1
  175. data/screen_test/settings/valign/box_bottom.rb +1 -1
  176. data/screen_test/settings/valign/box_default.frame +1 -1
  177. data/screen_test/settings/valign/box_default.rb +1 -1
  178. data/screen_test/settings/valign/box_evenly.frame +1 -1
  179. data/screen_test/settings/valign/box_evenly.rb +1 -1
  180. data/screen_test/settings/valign/box_middle.frame +1 -1
  181. data/screen_test/settings/valign/box_middle.rb +1 -1
  182. data/screen_test/settings/valign/box_top.frame +1 -1
  183. data/screen_test/settings/valign/box_top.rb +1 -1
  184. data/screen_test/settings/valign/grid_bottom.frame +1 -1
  185. data/screen_test/settings/valign/grid_bottom.rb +1 -1
  186. data/screen_test/settings/valign/grid_default.frame +1 -1
  187. data/screen_test/settings/valign/grid_default.rb +1 -1
  188. data/screen_test/settings/valign/grid_middle.frame +1 -1
  189. data/screen_test/settings/valign/grid_middle.rb +1 -1
  190. data/screen_test/settings/valign/grid_top.frame +1 -1
  191. data/screen_test/settings/valign/grid_top.rb +1 -1
  192. data/screen_test/settings/width/box_border_sizing.frame +1 -1
  193. data/screen_test/settings/width/box_border_sizing.rb +1 -1
  194. data/screen_test/settings/width/box_content.frame +1 -1
  195. data/screen_test/settings/width/box_content.rb +1 -1
  196. data/screen_test/settings/width/box_default.frame +1 -1
  197. data/screen_test/settings/width/box_default.rb +1 -1
  198. data/screen_test/settings/width/grid.frame +1 -1
  199. data/screen_test/settings/width/grid.rb +1 -1
  200. data/screen_test/settings/width/overflow_align_center.frame +1 -1
  201. data/screen_test/settings/width/overflow_align_center.rb +1 -1
  202. data/screen_test/settings/width/overflow_align_right.frame +1 -1
  203. data/screen_test/settings/width/overflow_align_right.rb +1 -1
  204. data/screen_test/settings/width/overflow_box.frame +1 -1
  205. data/screen_test/settings/width/overflow_box.rb +1 -1
  206. data/screen_test/settings/width/overflow_box_l2r.frame +1 -1
  207. data/screen_test/settings/width/overflow_box_l2r.rb +1 -1
  208. data/screen_test/settings/width/overflow_box_t2b.frame +1 -1
  209. data/screen_test/settings/width/overflow_box_t2b.rb +1 -1
  210. data/screen_test/settings/width/overflow_grid.frame +1 -1
  211. data/screen_test/settings/width/overflow_grid.rb +1 -1
  212. data/tools/whirled_peas/tools/screen_tester.rb +131 -65
  213. metadata +42 -9
  214. data/lib/whirled_peas/frame.rb +0 -6
  215. data/lib/whirled_peas/frame/consumer.rb +0 -30
  216. data/lib/whirled_peas/frame/debug_consumer.rb +0 -30
  217. data/lib/whirled_peas/frame/event_loop.rb +0 -90
  218. data/lib/whirled_peas/frame/producer.rb +0 -67
  219. data/lib/whirled_peas/graphics/screen.rb +0 -70
  220. data/lib/whirled_peas/graphics/text_dimensions.rb +0 -15
@@ -0,0 +1,29 @@
1
+ require_relative 'frame_command'
2
+
3
+ module WhirledPeas
4
+ module Command
5
+ # Display a still frame with the specified arguments.
6
+ class Still < FrameCommand
7
+ def self.description
8
+ 'Show the specified still frame'
9
+ end
10
+
11
+ def start
12
+ super
13
+
14
+ require 'whirled_peas/device/screen'
15
+ require 'whirled_peas/graphics/renderer'
16
+ require 'whirled_peas/utils/ansi'
17
+
18
+ Utils::Ansi.with_screen do |width, height|
19
+ rendered = Graphics::Renderer.new(
20
+ WhirledPeas.config.template_factory.build(frame, frame_args),
21
+ width,
22
+ height
23
+ ).paint
24
+ Device::Screen.new(10000).handle_renders([rendered])
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,76 @@
1
+ require 'whirled_peas/device/screen'
2
+ require 'whirled_peas/graphics/renderer'
3
+ require 'whirled_peas/settings/theme_library'
4
+
5
+ require_relative 'base'
6
+
7
+ module WhirledPeas
8
+ module Command
9
+ # Display a still frame with the specified arguments.
10
+ class Themes < Base
11
+ def self.description
12
+ 'List all themes with sample template rendered in the theme'
13
+ end
14
+
15
+ def start
16
+ super
17
+
18
+ require config_file unless config_file.nil?
19
+
20
+ theme_names = Settings::ThemeLibrary.theme_names
21
+ theme_names.each.with_index do |name, index|
22
+ template = WhirledPeas.template(name) do |composer, settings|
23
+ settings.full_border
24
+ settings.flow = :t2b
25
+ composer.add_text do |_, settings|
26
+ settings.title_font = :theme
27
+ name
28
+ end
29
+ composer.add_text do
30
+ name == Settings::ThemeLibrary.default_name ? ' (default)' : ''
31
+ end
32
+ composer.add_graph do |_, settings|
33
+ settings.height = 12
34
+ 20.times.map { |i| Math.sqrt(i) }
35
+ end
36
+ end
37
+ Utils::Ansi.with_screen do |width, height|
38
+ rendered = Graphics::Renderer.new(
39
+ template,
40
+ 80,
41
+ 30
42
+ ).paint
43
+ Device::Screen.new(10000).handle_renders([rendered])
44
+ end
45
+
46
+ if index < theme_names.length - 1
47
+ print 'See next theme? [Y/q] '
48
+ STDOUT.flush
49
+ break if gets.chomp == 'q'
50
+ end
51
+ end
52
+ rescue LoadError
53
+ puts "Error loading #{config_file}"
54
+ exit(1)
55
+ end
56
+
57
+ private
58
+
59
+ attr_reader :config_file
60
+
61
+ def validate!
62
+ super
63
+ config_file = args.shift
64
+ @error_text = 'hi'
65
+ unless config_file.nil?
66
+ # We think we have a valid ruby config file, set the absolute path to @config
67
+ @config_file = config_file[0] == '/' ? config_file : File.join(Dir.pwd, config_file)
68
+ end
69
+ end
70
+
71
+ def options_usage
72
+ '[config file]'
73
+ end
74
+ end
75
+ end
76
+ end
@@ -1,217 +1,23 @@
1
- require 'json'
2
-
3
- require 'whirled_peas/graphics/debugger'
4
- require 'whirled_peas/graphics/renderer'
5
- require 'whirled_peas/graphics/screen'
6
- require 'whirled_peas/frame/debug_consumer'
7
- require 'whirled_peas/frame/event_loop'
8
- require 'whirled_peas/frame/producer'
1
+ require 'whirled_peas/command/debug'
2
+ require 'whirled_peas/command/fonts'
3
+ require 'whirled_peas/command/frames'
4
+ require 'whirled_peas/command/help'
5
+ require 'whirled_peas/command/play'
6
+ require 'whirled_peas/command/record'
7
+ require 'whirled_peas/command/still'
8
+ require 'whirled_peas/command/themes'
9
9
 
10
10
  module WhirledPeas
11
- class Command
12
- DEFAULT_LOG_LEVEL = Logger::INFO
13
- DEFAULT_FORMATTER = proc do |severity, datetime, progname, msg|
14
- if msg.is_a?(Exception)
15
- msg = %Q(#{msg.class}: #{msg.to_s}\n #{msg.backtrace.join("\n ")})
16
- end
17
- "[#{severity}] #{datetime.strftime('%Y-%m-%dT%H:%M:%S.%L')} (#{progname}) - #{msg}\n"
18
- end
19
-
20
- def self.command_name
21
- self.name.split('::').last.sub(/Command$/, '').gsub(/([a-z])([A-Z])/, '\1_\2').downcase
22
- end
23
-
24
- def self.build_logger(output, level=DEFAULT_LOG_LEVEL, formatter=DEFAULT_FORMATTER)
25
- logger = Logger.new(output)
26
- logger.level = level
27
- logger.formatter = formatter
28
- logger
29
- end
30
-
31
- attr_reader :args
32
-
33
- def initialize(args)
34
- @args = args
35
- end
36
-
37
- def valid?
38
- @error_text = nil
39
- validate!
40
- @error_text.nil?
41
- end
42
-
43
- def print_error
44
- puts @error_text if @error_text
45
- print_usage
46
- end
47
-
48
- def start
49
- end
50
-
51
- private
52
-
53
- def print_usage
54
- puts "Usage: #{$0} #{self.class.command_name}"
55
- end
56
-
57
- def validate!
58
- # Set @error_text if the options are not valid
59
- end
60
- end
61
-
62
- class TitleFontsCommand < Command
63
- def start
64
- require 'whirled_peas/utils/title_font'
65
-
66
- Utils::TitleFont.fonts.keys.each do |key|
67
- puts Utils::TitleFont.to_s(key.to_s, key)
68
- puts key.inspect
69
- puts
70
- end
71
- end
72
- end
73
-
74
- class ConfigCommand < Command
75
- def start
76
- require config
77
- end
78
-
79
- private
80
-
81
- attr_reader :config
82
-
83
- def validate!
84
- if args.length == 0
85
- @error_text = "#{self.class.command_name} requires a config file"
86
- elsif !File.exist?(args[0])
87
- @error_text = "File not found: #{args[0]}"
88
- elsif args[0][-3..-1] != '.rb'
89
- @error_text = 'Config file should be a .rb file'
90
- else
91
- @config = args[0][0] == '/' ? args[0] : File.join(Dir.pwd, args[0])
92
- end
93
- end
94
-
95
- def print_usage
96
- puts "Usage: #{$0} #{self.class.command_name} <config file>"
97
- end
98
- end
99
-
100
- class StartCommand < ConfigCommand
101
- LOGGER_ID = 'MAIN'
102
-
103
- def start
104
- super
105
-
106
- logger = self.class.build_logger(File.open('whirled_peas.log', 'a'))
107
-
108
- consumer = Frame::EventLoop.new(
109
- WhirledPeas.config.template_factory,
110
- WhirledPeas.config.loading_template_factory,
111
- logger: logger
112
- )
113
- Frame::Producer.produce(consumer, logger) do |producer|
114
- begin
115
- WhirledPeas.config.driver.start(producer)
116
- rescue => e
117
- logger.warn(LOGGER_ID) { 'Driver exited with error, terminating producer...' }
118
- logger.error(LOGGER_ID) { e }
119
- raise
120
- end
121
- end
122
- end
123
- end
124
-
125
- class ListFramesCommand < ConfigCommand
126
- def start
127
- super
128
-
129
- Frame::Producer.produce(Frame::DebugConsumer.new) do |producer|
130
- WhirledPeas.config.driver.start(producer)
131
- end
132
- end
133
- end
134
-
135
- class PlayFrameCommand < ConfigCommand
136
- def start
137
- super
138
-
139
- if args.last == '--template'
140
- template = WhirledPeas.config.template_factory.build(frame, frame_args)
141
- puts Graphics::Debugger.new(template).debug
142
- else
143
- logger = self.class.build_logger(File.open('whirled_peas.log', 'a'))
144
- consumer = Frame::EventLoop.new(
145
- WhirledPeas.config.template_factory,
146
- logger: logger
147
- )
148
- Frame::Producer.produce(consumer, logger) do |producer|
149
- producer.send_frame(frame, args: frame_args)
150
- end
151
- end
152
- end
153
-
154
- private
155
-
156
- attr_reader :frame, :frame_args
157
-
158
- def validate!
159
- super
160
- if !@error_text.nil?
161
- return
162
- elsif args.length < 2
163
- @error_text = "#{self.class.command_name} requires a frame name"
164
- else
165
- @frame = args[1]
166
- @frame_args = {}
167
- return if args.length < 3 || args[2][0..1] == '--'
168
- JSON.parse(args[2] || '{}').each do |key, value|
169
- @frame_args[key.to_sym] = value
170
- end
171
- end
172
- end
173
-
174
- def print_usage
175
- puts "Usage: #{$0} #{self.class.command_name} <config file> <frame> [args as a JSON string] [--template]"
176
- end
177
- end
178
-
179
- class LoadingCommand < ConfigCommand
180
- def start
181
- super
182
- unless WhirledPeas.config.loading_template_factory
183
- puts 'No loading screen configured'
184
- exit(1)
185
- end
186
-
187
- if args.last == '--template'
188
- template = WhirledPeas.config.loading_template_factory.build
189
- puts Graphics::Debugger.new(template).debug
190
- else
191
- logger = self.class.build_logger(File.open('whirled_peas.log', 'a'))
192
- consumer = Frame::EventLoop.new(
193
- WhirledPeas.config.template_factory,
194
- WhirledPeas.config.loading_template_factory,
195
- logger: logger
196
- )
197
- Frame::Producer.produce(consumer, logger) { sleep(5) }
198
- end
199
- end
200
-
201
- private
202
-
203
- def print_usage
204
- puts "Usage: #{$0} #{self.class.command_name} [--template]"
205
- end
206
- end
207
-
208
11
  class CommandLine
209
12
  COMMANDS = [
210
- StartCommand,
211
- ListFramesCommand,
212
- PlayFrameCommand,
213
- LoadingCommand,
214
- TitleFontsCommand
13
+ Command::Debug,
14
+ Command::Fonts,
15
+ Command::Frames,
16
+ Command::Help,
17
+ Command::Play,
18
+ Command::Record,
19
+ Command::Still,
20
+ Command::Themes
215
21
  ].map.with_object({}) { |c, h| h[c.command_name] = c }
216
22
 
217
23
  def initialize(args)
@@ -232,7 +38,7 @@ module WhirledPeas
232
38
  exit(1)
233
39
  end
234
40
 
235
- cmd = COMMANDS[command].new(args)
41
+ cmd = COMMANDS[command].new(args, WhirledPeas.config)
236
42
 
237
43
  unless cmd.valid?
238
44
  cmd.print_error
@@ -249,7 +55,13 @@ module WhirledPeas
249
55
  def print_usage
250
56
  puts "Usage: #{$0} <command> [command options]"
251
57
  puts
252
- puts "Available commands: #{COMMANDS.keys.join(', ')}"
58
+ puts 'Available commands:'
59
+ puts
60
+ max_name_length = 0
61
+ COMMANDS.keys.each { |c| max_name_length = c.length if c.length > max_name_length }
62
+ COMMANDS.each do |name, klass|
63
+ puts " #{name.ljust(max_name_length, ' ')} #{klass.description}"
64
+ end
253
65
  end
254
66
  end
255
67
  end
@@ -1,13 +1,47 @@
1
+ require 'logger'
2
+
1
3
  module WhirledPeas
2
4
  class Config
3
- attr_writer :driver, :template_factory
4
- attr_accessor :loading_template_factory
5
+ # Refreshed rate measured in frames per second
6
+ DEFAULT_REFRESH_RATE = 30
7
+
8
+ DEFAULT_LOG_LEVEL = Logger::INFO
9
+ DEFAULT_LOG_FILE = 'whirled_peas.log'
5
10
 
6
- def driver
7
- unless @driver
8
- raise ConfigurationError, 'driver must be configured'
11
+ # This formatter expects a loggers to send `progname` in each log call. This value
12
+ # should be an all uppercase version of the module or class that is invoking the
13
+ # logger. Ruby's logger supports setting this value on a per-log statement basis
14
+ # when the log message is passed in through a block:
15
+ #
16
+ # logger.<level>(progname, &block)
17
+ #
18
+ # E.g.
19
+ #
20
+ # class Foo
21
+ # def bar
22
+ # logger.warn('FOO') { 'Something fishy happened in #bar' }
23
+ # end
24
+ # end
25
+ #
26
+ # The block format also has the advantage that the evaluation of the block only
27
+ # occurs if the message gets logged. So expensive to calculate debug statements
28
+ # will not impact the performance of the application if the log level is INFO or
29
+ # higher.
30
+ DEFAULT_FORMATTER = proc do |severity, datetime, progname, msg|
31
+ # Convert an instance of an exception into a nicely formatted message string
32
+ if msg.is_a?(Exception)
33
+ msg = %Q(#{msg.class}: #{msg.to_s}\n #{msg.backtrace.join("\n ")})
9
34
  end
10
- @driver
35
+ "[#{severity}] #{datetime.strftime('%Y-%m-%dT%H:%M:%S.%L')} (#{progname}) - #{msg}\n"
36
+ end
37
+
38
+ attr_writer :application, :template_factory, :refresh_rate, :log_level, :log_formatter, :log_file
39
+
40
+ def application
41
+ unless @application
42
+ raise ConfigurationError, 'application must be configured'
43
+ end
44
+ @application
11
45
  end
12
46
 
13
47
  def template_factory
@@ -16,6 +50,22 @@ module WhirledPeas
16
50
  end
17
51
  @template_factory
18
52
  end
53
+
54
+ def refresh_rate
55
+ @refresh_rate || DEFAULT_REFRESH_RATE
56
+ end
57
+
58
+ def log_level
59
+ @log_level || DEFAULT_LOG_LEVEL
60
+ end
61
+
62
+ def log_formatter
63
+ @log_formatter || DEFAULT_FORMATTER
64
+ end
65
+
66
+ def log_file
67
+ @log_file || DEFAULT_LOG_FILE
68
+ end
19
69
  end
20
70
  private_constant :Config
21
71
  end
@@ -0,0 +1,5 @@
1
+ module WhirledPeas
2
+ module Device
3
+ end
4
+ private_constant :Device
5
+ end
@@ -0,0 +1,8 @@
1
+ module WhirledPeas
2
+ module Device
3
+ class NullDevice
4
+ def handle_renders(*)
5
+ end
6
+ end
7
+ end
8
+ end