]> git.cworth.org Git - sup/blobdiff - lib/sup/buffer.rb
warning fix
[sup] / lib / sup / buffer.rb
index 4000004524d6f07da76b5de5eaee87d81d5254a3..0e2b85bce1bad619e41dd84144b901d41db57fad 100644 (file)
@@ -14,7 +14,7 @@ module Ncurses
   end
 
   def mutex; @mutex ||= Mutex.new; end
-  def sync &b; mutex.synchronize &b; end
+  def sync &b; mutex.synchronize(&b); end
 
   ## aaahhh, user input. who would have though that such a simple
   ## idea would be SO FUCKING COMPLICATED?! because apparently
@@ -136,9 +136,10 @@ class BufferManager
     @focus_buf = nil
     @dirty = true
     @minibuf_stack = []
+    @minibuf_mutex = Mutex.new
     @textfields = {}
     @flash = nil
-    @shelled = false
+    @shelled = @asking = false
 
     self.class.i_am_the_instance self
   end
@@ -216,7 +217,6 @@ class BufferManager
     if true
       buf = @buffers.last
       buf.resize Ncurses.rows - minibuf_lines, Ncurses.cols
-      File.open("asdf.txt", "a") { |f| f.puts "dirty #@dirty, (re)drawing #{buf.mode.name}" }
       @dirty ? buf.draw : buf.redraw
     end
 
@@ -232,7 +232,6 @@ class BufferManager
   ## the mode is expensive, as it often is.
   def spawn_unless_exists title, opts={}
     if @name_map.member? title
-      Redwood::log "buffer '#{title}' already exists, raising to front"
       raise_to_front @name_map[title] unless opts[:hidden]
     else
       mode = yield
@@ -291,7 +290,10 @@ class BufferManager
     end
   end
 
+  ## not really thread safe.
   def ask domain, question, default=nil
+    raise "impossible!" if @asking
+
     @textfields[domain] ||= TextField.new Ncurses.stdscr, Ncurses.rows - 1, 0, Ncurses.cols
     tf = @textfields[domain]
 
@@ -309,7 +311,10 @@ class BufferManager
     ret = nil
     tf.position_cursor
     Ncurses.sync { Ncurses.refresh }
+
+    @asking = true
     while tf.handle_input(Ncurses.nonblocking_getch); end
+    @asking = false
 
     ret = tf.value
     Ncurses.sync { tf.deactivate }
@@ -345,10 +350,10 @@ class BufferManager
     @shelled = false
 
     Ncurses.sync do
-      SafeNcurses.curs_set 0
+      Ncurses.curs_set 0
       erase_flash
       draw_screen :sync => false
-      SafeNcurses.curs_set 0
+      Ncurses.curs_set 0
     end
 
     ret
@@ -366,26 +371,40 @@ class BufferManager
     end
   end
 
-  def minibuf_lines; [(@flash ? 1 : 0) + @minibuf_stack.compact.size, 1].max; end
+  def minibuf_lines
+    @minibuf_mutex.synchronize do
+      [(@flash ? 1 : 0) + 
+       (@asking ? 1 : 0) +
+       @minibuf_stack.compact.size, 1].max
+    end
+  end
   
   def draw_minibuf opts={}
-    m = @minibuf_stack.compact
-    m << @flash if @flash
-    m << "" if m.empty?
+    m = nil
+    @minibuf_mutex.synchronize do
+      m = @minibuf_stack.compact
+      m << @flash if @flash
+      m << "" if m.empty?
+    end
 
     Ncurses.mutex.lock unless opts[:sync] == false
     Ncurses.attrset Colormap.color_for(:none)
+    adj = @asking ? 2 : 1
     m.each_with_index do |s, i|
-      Ncurses.mvaddstr Ncurses.rows - i - 1, 0, s + (" " * [Ncurses.cols - s.length, 0].max)
+      Ncurses.mvaddstr Ncurses.rows - i - adj, 0, s + (" " * [Ncurses.cols - s.length, 0].max)
     end
     Ncurses.refresh if opts[:refresh]
     Ncurses.mutex.unlock unless opts[:sync] == false
   end
 
   def say s, id=nil
-    new_id = id.nil?
-    id ||= @minibuf_stack.length
-    @minibuf_stack[id] = s
+    new_id = nil
+    @minibuf_mutex.synchronize do
+      new_id = id.nil?
+      id ||= @minibuf_stack.length
+      @minibuf_stack[id] = s
+    end
+
     if new_id
       draw_screen :refresh => true
     else
@@ -394,7 +413,7 @@ class BufferManager
 
     if block_given?
       begin
-        yield
+        yield id
       ensure
         clear id
       end
@@ -412,11 +431,13 @@ class BufferManager
   ## a little tricky because we can't just delete_at id because ids
   ## are relative (they're positions into the array).
   def clear id
-    @minibuf_stack[id] = nil
-    if id == @minibuf_stack.length - 1
-      id.downto(0) do |i|
-        break if @minibuf_stack[i]
-        @minibuf_stack.delete_at i
+    @minibuf_mutex.synchronize do
+      @minibuf_stack[id] = nil
+      if id == @minibuf_stack.length - 1
+        id.downto(0) do |i|
+          break if @minibuf_stack[i]
+          @minibuf_stack.delete_at i
+        end
       end
     end