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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +25 -0
- data/README.md +467 -120
- data/Rakefile +1 -20
- data/bin/easing +33 -0
- data/bin/reset_cursor +11 -0
- data/bin/screen_test +68 -0
- data/examples/graph.rb +54 -0
- data/examples/intro.rb +3 -3
- data/examples/scrolling.rb +5 -4
- data/lib/data/themes.yaml +13 -0
- data/lib/whirled_peas.rb +12 -6
- data/lib/whirled_peas/animator.rb +5 -0
- data/lib/whirled_peas/animator/debug_consumer.rb +17 -0
- data/lib/whirled_peas/animator/easing.rb +72 -0
- data/lib/whirled_peas/animator/frame.rb +5 -0
- data/lib/whirled_peas/animator/frameset.rb +33 -0
- data/lib/whirled_peas/animator/producer.rb +35 -0
- data/lib/whirled_peas/animator/renderer_consumer.rb +31 -0
- data/lib/whirled_peas/command.rb +5 -0
- data/lib/whirled_peas/command/base.rb +86 -0
- data/lib/whirled_peas/command/config_command.rb +43 -0
- data/lib/whirled_peas/command/debug.rb +21 -0
- data/lib/whirled_peas/command/fonts.rb +22 -0
- data/lib/whirled_peas/command/frame_command.rb +34 -0
- data/lib/whirled_peas/command/frames.rb +24 -0
- data/lib/whirled_peas/command/help.rb +38 -0
- data/lib/whirled_peas/command/play.rb +111 -0
- data/lib/whirled_peas/command/record.rb +57 -0
- data/lib/whirled_peas/command/still.rb +29 -0
- data/lib/whirled_peas/command/themes.rb +76 -0
- data/lib/whirled_peas/command_line.rb +24 -212
- data/lib/whirled_peas/config.rb +56 -6
- data/lib/whirled_peas/device.rb +5 -0
- data/lib/whirled_peas/device/null_device.rb +8 -0
- data/lib/whirled_peas/device/output_file.rb +19 -0
- data/lib/whirled_peas/device/screen.rb +26 -0
- data/lib/whirled_peas/graphics/composer.rb +23 -2
- data/lib/whirled_peas/graphics/container_painter.rb +91 -0
- data/lib/whirled_peas/graphics/content_dimensions.rb +19 -0
- data/lib/whirled_peas/graphics/content_painter.rb +20 -0
- data/lib/whirled_peas/graphics/graph_dimensions.rb +12 -0
- data/lib/whirled_peas/graphics/graph_painter.rb +97 -0
- data/lib/whirled_peas/graphics/grid_painter.rb +1 -4
- data/lib/whirled_peas/graphics/painter.rb +10 -0
- data/lib/whirled_peas/graphics/renderer.rb +8 -2
- data/lib/whirled_peas/graphics/text_painter.rb +7 -11
- data/lib/whirled_peas/settings/border.rb +25 -4
- data/lib/whirled_peas/settings/container_settings.rb +2 -4
- data/lib/whirled_peas/settings/element_settings.rb +12 -3
- data/lib/whirled_peas/settings/graph_settings.rb +21 -0
- data/lib/whirled_peas/settings/grid_settings.rb +7 -0
- data/lib/whirled_peas/settings/text_settings.rb +1 -0
- data/lib/whirled_peas/settings/theme.rb +40 -0
- data/lib/whirled_peas/settings/theme_library.rb +63 -0
- data/lib/whirled_peas/utils/ansi.rb +13 -0
- data/lib/whirled_peas/utils/file_handler.rb +57 -0
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/elements/box.frame +1 -1
- data/screen_test/elements/box.rb +1 -1
- data/screen_test/elements/graph.frame +1 -0
- data/screen_test/elements/graph.rb +12 -0
- data/screen_test/elements/grid.frame +1 -1
- data/screen_test/elements/grid.rb +1 -1
- data/screen_test/elements/screen_overflow_x.frame +1 -1
- data/screen_test/elements/screen_overflow_x.rb +1 -1
- data/screen_test/elements/screen_overflow_y.frame +1 -1
- data/screen_test/elements/screen_overflow_y.rb +1 -1
- data/screen_test/elements/text.frame +1 -1
- data/screen_test/elements/text.rb +1 -1
- data/screen_test/elements/text_multiline.frame +1 -1
- data/screen_test/elements/text_multiline.rb +1 -1
- data/screen_test/elements/theme.frame +1 -0
- data/screen_test/elements/theme.rb +26 -0
- data/screen_test/settings/align/box_around.frame +1 -1
- data/screen_test/settings/align/box_around.rb +1 -1
- data/screen_test/settings/align/box_between.frame +1 -1
- data/screen_test/settings/align/box_between.rb +1 -1
- data/screen_test/settings/align/box_center.frame +1 -1
- data/screen_test/settings/align/box_center.rb +1 -1
- data/screen_test/settings/align/box_default.frame +1 -1
- data/screen_test/settings/align/box_default.rb +1 -1
- data/screen_test/settings/align/box_evenly.frame +1 -1
- data/screen_test/settings/align/box_evenly.rb +1 -1
- data/screen_test/settings/align/box_left.frame +1 -1
- data/screen_test/settings/align/box_left.rb +1 -1
- data/screen_test/settings/align/box_right.frame +1 -1
- data/screen_test/settings/align/box_right.rb +1 -1
- data/screen_test/settings/align/children_center.frame +1 -1
- data/screen_test/settings/align/children_center.rb +1 -1
- data/screen_test/settings/align/children_left.frame +1 -1
- data/screen_test/settings/align/children_left.rb +1 -1
- data/screen_test/settings/align/children_right.frame +1 -1
- data/screen_test/settings/align/children_right.rb +1 -1
- data/screen_test/settings/align/grid_center.frame +1 -1
- data/screen_test/settings/align/grid_center.rb +1 -1
- data/screen_test/settings/align/grid_default.frame +1 -1
- data/screen_test/settings/align/grid_default.rb +1 -1
- data/screen_test/settings/align/grid_left.frame +1 -1
- data/screen_test/settings/align/grid_left.rb +1 -1
- data/screen_test/settings/align/grid_right.frame +1 -1
- data/screen_test/settings/align/grid_right.rb +1 -1
- data/screen_test/settings/ansi/bold.frame +1 -1
- data/screen_test/settings/ansi/bold.rb +1 -1
- data/screen_test/settings/ansi/color.frame +1 -1
- data/screen_test/settings/ansi/color.rb +1 -1
- data/screen_test/settings/ansi/underline.frame +1 -1
- data/screen_test/settings/ansi/underline.rb +1 -1
- data/screen_test/settings/border.frame +1 -1
- data/screen_test/settings/border.rb +1 -1
- data/screen_test/settings/flow/box_b2t.frame +1 -1
- data/screen_test/settings/flow/box_b2t.rb +1 -1
- data/screen_test/settings/flow/box_l2r.frame +1 -1
- data/screen_test/settings/flow/box_l2r.rb +1 -1
- data/screen_test/settings/flow/box_r2l.frame +1 -1
- data/screen_test/settings/flow/box_r2l.rb +1 -1
- data/screen_test/settings/flow/box_t2b.frame +1 -1
- data/screen_test/settings/flow/box_t2b.rb +1 -1
- data/screen_test/settings/flow/grid_b2t.frame +1 -1
- data/screen_test/settings/flow/grid_b2t.rb +2 -2
- data/screen_test/settings/flow/grid_l2r.frame +1 -1
- data/screen_test/settings/flow/grid_l2r.rb +2 -2
- data/screen_test/settings/flow/grid_r2l.frame +1 -1
- data/screen_test/settings/flow/grid_r2l.rb +2 -2
- data/screen_test/settings/flow/grid_t2b.frame +1 -1
- data/screen_test/settings/flow/grid_t2b.rb +2 -2
- data/screen_test/settings/height/box.frame +1 -1
- data/screen_test/settings/height/box.rb +1 -1
- data/screen_test/settings/height/box_border_sizing.frame +1 -1
- data/screen_test/settings/height/box_border_sizing.rb +1 -1
- data/screen_test/settings/height/grid.frame +1 -1
- data/screen_test/settings/height/grid.rb +1 -1
- data/screen_test/settings/height/overflow_box.frame +1 -1
- data/screen_test/settings/height/overflow_box.rb +1 -1
- data/screen_test/settings/height/overflow_box_l2r.frame +1 -1
- data/screen_test/settings/height/overflow_box_l2r.rb +1 -1
- data/screen_test/settings/height/overflow_box_t2b.frame +1 -1
- data/screen_test/settings/height/overflow_box_t2b.rb +1 -1
- data/screen_test/settings/height/overflow_grid.frame +1 -1
- data/screen_test/settings/height/overflow_grid.rb +1 -1
- data/screen_test/settings/margin.frame +1 -1
- data/screen_test/settings/margin.rb +1 -1
- data/screen_test/settings/padding.frame +1 -1
- data/screen_test/settings/padding.rb +1 -1
- data/screen_test/settings/position/box_left.frame +1 -1
- data/screen_test/settings/position/box_left.rb +1 -1
- data/screen_test/settings/position/box_left_negative.frame +1 -1
- data/screen_test/settings/position/box_left_negative.rb +1 -1
- data/screen_test/settings/position/box_top.frame +1 -1
- data/screen_test/settings/position/box_top.rb +1 -1
- data/screen_test/settings/position/box_top_negative.frame +1 -1
- data/screen_test/settings/position/box_top_negative.rb +1 -1
- data/screen_test/settings/position/grid_left.frame +1 -1
- data/screen_test/settings/position/grid_left.rb +1 -1
- data/screen_test/settings/position/grid_left_negative.frame +1 -1
- data/screen_test/settings/position/grid_left_negative.rb +1 -1
- data/screen_test/settings/position/grid_top.frame +1 -1
- data/screen_test/settings/position/grid_top.rb +1 -1
- data/screen_test/settings/position/grid_top_negative.frame +1 -1
- data/screen_test/settings/position/grid_top_negative.rb +1 -1
- data/screen_test/settings/scroll/horiz_box.frame +1 -1
- data/screen_test/settings/scroll/horiz_box.rb +1 -1
- data/screen_test/settings/scroll/horiz_box_align_center.rb +1 -1
- data/screen_test/settings/scroll/horiz_box_align_right.rb +1 -1
- data/screen_test/settings/scroll/vert_box.frame +1 -1
- data/screen_test/settings/scroll/vert_box.rb +1 -1
- data/screen_test/settings/title_font.frame +1 -1
- data/screen_test/settings/title_font.rb +1 -1
- data/screen_test/settings/valign/box_around.frame +1 -1
- data/screen_test/settings/valign/box_around.rb +1 -1
- data/screen_test/settings/valign/box_between.frame +1 -1
- data/screen_test/settings/valign/box_between.rb +1 -1
- data/screen_test/settings/valign/box_bottom.frame +1 -1
- data/screen_test/settings/valign/box_bottom.rb +1 -1
- data/screen_test/settings/valign/box_default.frame +1 -1
- data/screen_test/settings/valign/box_default.rb +1 -1
- data/screen_test/settings/valign/box_evenly.frame +1 -1
- data/screen_test/settings/valign/box_evenly.rb +1 -1
- data/screen_test/settings/valign/box_middle.frame +1 -1
- data/screen_test/settings/valign/box_middle.rb +1 -1
- data/screen_test/settings/valign/box_top.frame +1 -1
- data/screen_test/settings/valign/box_top.rb +1 -1
- data/screen_test/settings/valign/grid_bottom.frame +1 -1
- data/screen_test/settings/valign/grid_bottom.rb +1 -1
- data/screen_test/settings/valign/grid_default.frame +1 -1
- data/screen_test/settings/valign/grid_default.rb +1 -1
- data/screen_test/settings/valign/grid_middle.frame +1 -1
- data/screen_test/settings/valign/grid_middle.rb +1 -1
- data/screen_test/settings/valign/grid_top.frame +1 -1
- data/screen_test/settings/valign/grid_top.rb +1 -1
- data/screen_test/settings/width/box_border_sizing.frame +1 -1
- data/screen_test/settings/width/box_border_sizing.rb +1 -1
- data/screen_test/settings/width/box_content.frame +1 -1
- data/screen_test/settings/width/box_content.rb +1 -1
- data/screen_test/settings/width/box_default.frame +1 -1
- data/screen_test/settings/width/box_default.rb +1 -1
- data/screen_test/settings/width/grid.frame +1 -1
- data/screen_test/settings/width/grid.rb +1 -1
- data/screen_test/settings/width/overflow_align_center.frame +1 -1
- data/screen_test/settings/width/overflow_align_center.rb +1 -1
- data/screen_test/settings/width/overflow_align_right.frame +1 -1
- data/screen_test/settings/width/overflow_align_right.rb +1 -1
- data/screen_test/settings/width/overflow_box.frame +1 -1
- data/screen_test/settings/width/overflow_box.rb +1 -1
- data/screen_test/settings/width/overflow_box_l2r.frame +1 -1
- data/screen_test/settings/width/overflow_box_l2r.rb +1 -1
- data/screen_test/settings/width/overflow_box_t2b.frame +1 -1
- data/screen_test/settings/width/overflow_box_t2b.rb +1 -1
- data/screen_test/settings/width/overflow_grid.frame +1 -1
- data/screen_test/settings/width/overflow_grid.rb +1 -1
- data/tools/whirled_peas/tools/screen_tester.rb +131 -65
- metadata +42 -9
- data/lib/whirled_peas/frame.rb +0 -6
- data/lib/whirled_peas/frame/consumer.rb +0 -30
- data/lib/whirled_peas/frame/debug_consumer.rb +0 -30
- data/lib/whirled_peas/frame/event_loop.rb +0 -90
- data/lib/whirled_peas/frame/producer.rb +0 -67
- data/lib/whirled_peas/graphics/screen.rb +0 -70
- 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 '
|
2
|
-
|
3
|
-
require 'whirled_peas/
|
4
|
-
require 'whirled_peas/
|
5
|
-
require 'whirled_peas/
|
6
|
-
require 'whirled_peas/
|
7
|
-
require 'whirled_peas/
|
8
|
-
require 'whirled_peas/
|
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
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
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
|
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
|
data/lib/whirled_peas/config.rb
CHANGED
@@ -1,13 +1,47 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
1
3
|
module WhirledPeas
|
2
4
|
class Config
|
3
|
-
|
4
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
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
|