lib/overlayer.rb in sensible-cinema-0.7.0 vs lib/overlayer.rb in sensible-cinema-0.7.1
- old
+ new
@@ -42,22 +42,25 @@
def unblank!
@am_blanked = false
Blanker.unblank_full_screen! unless $DEBUG
end
- def reload_yaml!
- if @file_mtime != (new_time = File.stat(@filename).mtime)
- @all_sequences = OverLayer.translate_yaml(File.read(@filename))
- # LTODO... @all_sequences = @all_sequences.map{|k, v| v.sort!} etc.
- puts '(re) loaded mute sequences as', pretty_sequences.pretty_inspect, "" unless $DEBUG # I hate these during unit tests...
- pps 'because old time', @file_mtime.to_f, '!= new time', new_time.to_f if $VERBOSE
- @file_mtime = new_time # save 0.0002!
- else
- p 'matching time:', new_time if $VERBOSE
+ def check_reload_yaml
+ current_mtime = File.stat(@filename).mtime # save 0.0002!
+ if @file_mtime != current_mtime
+ reload_yaml!
+ @file_mtime = current_mtime
end
end
+ def reload_yaml!
+ @all_sequences = OverLayer.translate_yaml(File.read(@filename))
+ # LTODO... @all_sequences = @all_sequences.map{|k, v| v.sort!} etc. and validate...
+ puts '(re) loaded mute sequences from ' + File.basename(@filename) + ' as', pretty_sequences.pretty_inspect, "" unless $DEBUG && !$VERBOSE # I hate these during unit tests...
+ signal_change
+ end
+
def pretty_sequences
new_sequences = {}
@all_sequences.each{|type, values|
if values.is_a? Array
new_sequences[type] = values.map{|s, f|
@@ -88,19 +91,32 @@
self.set_seconds self.class.translate_string_to_seconds(minutes)
end
end
def self.translate_yaml raw_yaml
- all = YAML.load(raw_yaml)
+ begin
+ all = YAML.load(raw_yaml) || {}
+
+ rescue NoMethodError
+ p 'appears your file has a syntax error in it--perhaps missing quotation marks'
+ return
+ end
# now it's like {:mutes => {"1:02.0" => "1:3.0"}}
# translate to floats like 62.0 => 63.0
for type in [:mutes, :blank_outs]
maps = all[type] || all[type.to_s] || {}
new = {}
- maps.each{|s,e|
+ maps.each{|start,endy|
# both are like 1:02.0
- new[translate_string_to_seconds(s)] = translate_string_to_seconds(e)
+ start = translate_string_to_seconds(start)
+ endy = translate_string_to_seconds(endy)
+ if start == 0 || endy == 0
+ p 'warning--possible error in the scene list someline not parsed! (NB if you want one to start at time 0 please use 0.0001)', start, endy unless $DEBUG
+ # drop it in bitbucket...
+ else
+ new[start] = endy
+ end
}
all.delete(type.to_s)
all[type] = new.sort
end
all
@@ -118,30 +134,19 @@
seconds = seconds - minutes * 60
out << ":"
out << "%04.1f" % seconds
end
- # make it optional...for now muhaha [lodo take out if never useful]
- def timestamp_changed to_this_exact_string, delta
- if to_this_exact_string
- set_seconds OverLayer.translate_string_to_seconds(to_this_exact_string) + delta
- else
- round_current_time_to_nearest_second
- end
+ def timestamp_changed to_this_exact_string_might_be_nil, delta
+ set_seconds OverLayer.translate_string_to_seconds(to_this_exact_string_might_be_nil) + delta if to_this_exact_string_might_be_nil
end
- def round_current_time_to_nearest_second
- current_time = cur_time
- better_time = current_time.round
- set_seconds better_time
- puts 'screen snapshot diff with time we thought it was was:' + (current_time - better_time).to_s if $VERBOSE
- end
-
def self.translate_string_to_seconds s
- # might actually already be a float...
- if s.is_a? Float
- return s
+ # might actually already be a float, or int, depending on the yaml
+ # int for 8 => 9 and also for 1:09 => 1:10
+ if s.is_a? Numeric
+ return s.to_f
end
# s is like 1:01:02.0
total = 0.0
seconds = s.split(":")[-1]
@@ -153,24 +158,32 @@
total
end
# returns seconds it's at currently...
def cur_time
- return Time.now_f - @start_time
+ Time.now_f - @start_time
end
+ def cur_english_time
+ translate_time_to_human_readable(cur_time)
+ end
+
def status
- time = "Current time: " + translate_time_to_human_readable(cur_time)
+ time = "Current time: " + cur_english_time
begin
mute, blank, next_sig = get_current_state
if next_sig == :done
state = " no more actions after this point..."
else
- state = " next action at #{translate_time_to_human_readable next_sig}s (#{mute ? "muted" : '' } #{blank ? "blanked" : '' })"
+ state = " next action will be at #{translate_time_to_human_readable next_sig}s "
end
+ if blank? or muted?
+ state += "(" + [muted? ? "muted" : nil, blank? ? "blanked" : nil ].compact.join(' ') + ") "
+ end
end
- time + state + " (HhMmSsTtdvq): "
+ check_reload_yaml
+ time + state + "(r,d,v,q to quit): "
end
def keyboard_input char
delta = case char
when 'h' then 60*60
@@ -190,14 +203,17 @@
p 'set debug to', $DEBUG
return
when ' ' then
puts cur_time
return
+ when 'r' then
+ reload_yaml!
+ puts
+ return
else nil
end
if delta
- reload_yaml!
set_seconds(cur_time + delta)
else
puts 'invalid char: [' + char + ']'
end
end
@@ -205,11 +221,18 @@
# sets it to a new set of seconds...
def set_seconds seconds
seconds = [seconds, 0].max
@mutex.synchronize {
@start_time = Time.now_f - seconds
- # tell the driver thread to continue onward. Cheery-o. We're not super thread friendly but good enough for having two contact each other...
+ }
+ signal_change
+ end
+
+ def signal_change
+ @mutex.synchronize {
+ # tell the driver thread to wake up and re-check state.
+ # We're not super thread friendly but good enough for having two contact each other...
@cv.signal
}
end
# we have a single scheduler thread, that is notified when the time may have changed
@@ -218,13 +241,17 @@
# @current_time = xxx
# broadcast # things have changed
# end
def start_thread continue_forever = false
- Thread.new { continue_until_past_all continue_forever }
+ @thread = Thread.new { continue_until_past_all continue_forever }
end
+ def kill_thread!
+ @thread.kill
+ end
+
# returns [start, end, active|:done]
def discover_state type, cur_time
for start, endy in @all_sequences[type]
if cur_time < endy
# first one that we haven't passed the *end* of yet
@@ -271,71 +298,63 @@
output
end
def continue_until_past_all continue_forever
if RUBY_VERSION < '1.9.2'
- raise 'need 1.9.2+ for MRI' unless RUBY_PLATFORM =~ /java/
+ raise 'need 1.9.2+ for MRI for the mutex stuff' unless RUBY_PLATFORM =~ /java/
end
@mutex.synchronize {
loop {
muted, blanked, next_point = get_current_state
if next_point == :done
- unless continue_forever
- return # done!
- else
+ if continue_forever
time_till_next_mute_starts = 1_000_000
+ else
+ #set_states! # for the unit tests' sake
+ return
end
else
time_till_next_mute_starts = next_point - cur_time
end
pps 'sleeping until next action (%s) begins in %fs (%f) %f' % [next_point, time_till_next_mute_starts, Time.now_f, cur_time] if $VERBOSE
@cv.wait(@mutex, time_till_next_mute_starts) if time_till_next_mute_starts > 0
pps 'just woke up from pre-mute wait at', Time.now_f if $VERBOSE
- something_has_possibly_changed
+ set_states!
}
}
end
+ def display_change change
+ puts ''
+ puts change + ' at ' + cur_english_time if $VERBOSE unless $DEBUG # too chatty for unit tests
+ end
+
def set_states!
should_be_muted, should_be_blank, next_point = get_current_state
if should_be_muted && !muted?
mute!
+ puts ''
+ display_change 'muted'
end
if !should_be_muted && muted?
- unmute!
+ unmute!
+ display_change 'unmuted'
end
if should_be_blank && !blank?
blank!
+ display_change 'blanked'
end
if !should_be_blank && blank?
unblank!
+ display_change 'unblanked'
end
- end
-
- def something_has_possibly_changed
- current = cur_time
- muted, blanked, next_point = get_current_state
- @muted = muted
- @blanked = blanked
- @endy = next_point
- return if next_point == :done
- if(current < next_point)
- set_states!
- duration_left = @endy - current
- pps 'just muted it at', Time.now_f, current, 'for interval:', 'which is', duration_left, 'more s' if $VERBOSE
- if duration_left > 0
- @cv.wait(@mutex, duration_left) if duration_left > 0
- end
- pps 'done sleeping', duration_left, 'was muted unmuting now', Time.now_f if $VERBOSE
- set_states!
- end
end
end