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