<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,4 +1,11 @@
-== 0.0.7 / 2007-10-..
+== 0.1.0 / 2008-02-??
+
+* Only sort needed Elements when needed
+* Keep Element List mostly sorted
+* Show Events from Elements not shown on screen
+* Show bars representing rate behind the element texts
+
+== 0.0.7 / 2007-10-27
 
 * Make textures from BitmapCharacter font
 * Use textured quads instead of BitmapCharacter</diff>
      <filename>History.txt</filename>
    </modified>
    <modified>
      <diff>@@ -3,11 +3,9 @@ GlTail
     http://www.fudgie.org
 
 == DESCRIPTION:
-
 Real-time view of server traffic and events using OpenGL and SSH.
 
 == FEATURES:
-
 * Real-Time OpenGL view
 * Multiple logfiles on multiple servers
 * Configurable layout
@@ -20,27 +18,23 @@ Real-time view of server traffic and events using OpenGL and SSH.
 * Free!
 
 == RUNNING:
+  gl_tail --help
+  gl_tail --new gl_tail.yaml
+  gl_tail
 
-  gl_tail.rb --help
-  gl_tail.rb &lt;config.yaml|config.rb&gt;
-
-  You can also press 'f' while running to toggle the attempted frames per second. Or 'b'
+  You can press 'f' while running to toggle the attempted frames per second. Or 'b'
   to change default blob type, and space to toggle bouncing.
 
-
 == REQUIREMENTS:
-
 * rubygems    0.9.4
 * ruby-opengl 0.40.1
 * net-ssh     1.1.2
 * opengl/ruby development packages (ruby1.8-dev libgl1-mesa-dev libglu1-mesa-dev libglut3-dev)
 
 == INSTALL:
-
   * sudo gem install gl_tail
 
 == LICENSE:
-
                     GNU GENERAL PUBLIC LICENSE
                        Version 2, June 1991
 </diff>
      <filename>README.txt</filename>
    </modified>
    <modified>
      <diff>@@ -4,8 +4,8 @@ require 'rubygems'
 require 'hoe'
 require './lib/gl_tail.rb'
 
-Hoe.new('gl_tail', GlTail::VERSION) do |p|
-  p.rubyforge_name = 'gl_tail'
+Hoe.new('gltail', GlTail::VERSION) do |p|
+  p.rubyforge_name = 'gltail'
   p.author = 'Erlend Simonsen'
   p.email = 'mr@fudgie.org'
   p.summary = 'View real-time data and statistics from any logfile on any server with SSH, in an intuitive and entertaining way.'</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,7 @@ class Activity
     end
 
     @xi = (rand(100)/100.0 * 0.002) - 0.001 if type == 2
+    @yi = (rand(100)/100.0 * 0.002) - 0.001 if type == 2
 
     @color = color
     @size  = size
@@ -98,14 +99,10 @@ class Activity
 
           list = glGenLists(1)
           glNewList(list, GL_COMPILE)
-          
+
           tmp = 10 + 10 * ((@size-engine.screen.min_blob_size)/engine.screen.max_blob_size)
-          if not tmp
-            puts &quot;THIS KEEPS CRASHING FOR ME WITH tmp == NaN -- cant figure out why&quot;
-            tmp = 2
-          end
-          
           glutSolidSphere(@size, tmp, 2)
+
           glEndList()
           BlobStore.put(@size,list)
         end</diff>
      <filename>lib/gl_tail/activity.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,6 +35,9 @@ class Block
     @elements = { }
     @bottom_position = -@config.screen.top
     @max_rate = 1.0/599
+
+    @sorted = []
+    @updated = false
   end
 
   def show=(value)
@@ -74,61 +77,122 @@ class Block
   end
 
   def render(engine, num)
-    return num if @elements.size == 0
+    return num if @elements.size == 0 || @sorted.size == 0
 
     @header.wy = top - (num * line_size)
     #    @header.y = @header.wy if @header.y == -$CONFIG.top
     @header.render(engine)
     num += 1
 
-    sorted = case @show
-    when 0: @elements.values.sort { |k,v| v.rate &lt;=&gt; k.rate}[0..@size-1]
-    when 1: @elements.values.sort { |k,v| v.total &lt;=&gt; k.total}[0..@size-1]
-    when 2: @elements.values.sort { |k,v| v.average &lt;=&gt; k.average}[0..@size-1]
-    end
+    count = 0
 
-    sorted.each do |e|
-      e.wy = top - (num * line_size)
-      e.render(engine)
+    @sorted.each do |e|
       engine.stats[0] += 1
-      if e.rate &lt;= 0.0001 &amp;&amp; e.active &amp;&amp; e.updates &gt; 59 &amp;&amp; @auto_clean
-        @elements.delete(e.name)
+      if count &lt; @size
+        e.wy = top - (num * line_size)
+        e.render(engine)
+        num += 1
+        @max_rate = e.rate if e.rate &gt; @max_rate
+      else
+        e.render_events(engine)
       end
-      num += 1
-      @max_rate = e.rate if e.rate &gt; @max_rate
-    end
 
-    (@elements.values - sorted).each do |e|
-      engine.stats[0] += 1
-      e.activities.each do |a|
-        a.render(engine)
-        if a.x &gt; 1.0 || a.x &lt; -1.0 || a.y &gt; @config.screen.aspect
-          e.activities.delete a
-        end
-      end
-      if e.activities.size == 0 &amp;&amp; @auto_clean &amp;&amp; e.updates &gt; 59
+      if e.activities.size == 0 &amp;&amp; (e.rate &lt;= 0.001 || count &gt; 100) &amp;&amp; @auto_clean
         @elements.delete(e.name)
+        @sorted.delete(e)
       end
+      count += 1
     end
-    @elements.delete_if { |k,v| (!sorted.include? v) &amp;&amp; v.active &amp;&amp; v.activities.size == 0 &amp;&amp; v.updates &gt; 29} if @auto_clean
-    @bottom_position = top - ((sorted.size &gt; 0 ? (num-1) : num) * line_size)
+
+    @bottom_position = top - ((@sorted.size &gt; 0 ? (num-1) : num) * line_size)
     num + 1
   end
 
   def add_activity(options = { })
-    x = @elements[options[:name]] ||= Element.new(self, options[:name], @color || options[:color] )
+    return unless options[:name]
+    x = nil
+    unless @elements[options[:name]]
+      x = Element.new(self, options[:name], @color || options[:color] )
+      @elements[options[:name]] = x
+      if @sorted.size &gt; @size
+        @sorted.insert(@size,x)
+      else
+        @sorted &lt;&lt; x
+      end
+    else
+      x = @elements[options[:name]]
+    end
     x.add_activity(options[:message], @color || options[:color], options[:size] || 0.01, options[:type] || 0 )
+    @updated = true
   end
 
   def add_event(options = { })
-    x = @elements[options[:name]] ||= Element.new(self, options[:name], @color || options[:color] )
+    return unless options[:name]
+    x = nil
+    unless @elements[options[:name]]
+      x = Element.new(self, options[:name], @color || options[:color] )
+      @elements[options[:name]] = x
+      if @sorted.size &gt; @size
+        @sorted.insert(@size,x)
+      else
+        @sorted &lt;&lt; x
+      end
+    else
+      x = @elements[options[:name]]
+    end
+
     x.add_event(options[:message], options[:color] || @color, options[:update_stats] || false)
+    @updated = true
   end
 
   def update
-    @max_rate = @max_rate * 0.9995
-    @elements.each_value do |e|
-      e.update
+    return if @sorted.size == 0
+
+    @max_rate = @max_rate * 0.9999
+
+    startTime = Time.now
+
+    i = 1
+    @ordered = [@sorted[0]]
+    min = @sorted[0].update
+    size = @sorted.size
+
+    while i &lt; size
+      rate = @sorted[i].update
+      if rate &gt; min
+        j = i - 1
+        while @ordered[j-1].rate &lt; rate &amp;&amp; j &gt; 0
+          j -= 1
+        end
+        @ordered.insert(j, @sorted[i])
+      else
+        @ordered &lt;&lt; @sorted[i]
+        min = rate if i &lt; @size
+      end
+      i += 1
     end
+
+    @sorted = @ordered
+
+#    puts &quot;#{@name} [#{@sorted.size}]: [#{Time.now - startTime}]&quot; if @name == &quot;urls&quot;
+
+    return
+
+    return unless @updated
+
+    sortTime = Time.now
+#    iSort( @sorted )
+
+#    @sorted = case @show
+#              when 0: @sorted.insertionSort
+#              when 1: @sorted.sort! { |k,v| &quot;#{sprintf('%05d',v.total)} #{v.rate}&quot; &lt;=&gt; &quot;#{sprintf('%05d',k.total)} #{k.rate}&quot; }
+#              when 2: @sorted.sort! { |k,v| &quot;#{v.average} #{v.name}&quot; &lt;=&gt; &quot;#{k.average} #{k.name}&quot; }
+#              end
+
+    puts &quot;#{@name} [#{@sorted.size}]: [#{sortTime - startTime}] [#{Time.now - sortTime}]&quot;
+
+    @updated = false
+
   end
+
 end</diff>
      <filename>lib/gl_tail/block.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,16 +35,21 @@ class Element
     @step = 0, @updates = 0
     @active = false
     @color = color
-    @color ||= [1.0, 1.0, 1.0, 1.0]
     @type = (@block.activity_type == &quot;blobs&quot; ? :blobs : :bars)
+    @bar_color ||= @color.dup
+
   end
 
   def add_activity(message, color, size,  type)
+    @bar_color[0] = @bar_color[0] + (@color[0] - @bar_color[0]) / 5
+    @bar_color[1] = @bar_color[1] + (@color[1] - @bar_color[1]) / 5
+    @bar_color[2] = @bar_color[2] + (@color[2] - @bar_color[2]) / 5
+
     @pending.push Item.new(message, size, color, type) if(type != 3)
     @messages += 1
     @total += 1
     @sum += size
-#    @color = color
+    @color = color
 
     if @rate == 0
       @rate = 1.0 / 60
@@ -66,17 +71,16 @@ class Element
 
 
   def update
-    @active = true if @total &gt; 0
+    @rate = (@rate * 299.0 + @messages) / 300.0
     @updates += 1
-    @rate = (@rate.to_f * 299 + @messages) / 300
     @messages = 0
-    if @pending.size + @queue.size &gt; 0
-#      @total += @pending.size
+    size = @pending.size
+    if size &gt; 0
       @average = @sum / @total
 
-      @step = 1.0 / (@queue.size + @pending.size) * 1000.0
-      @queue = @queue + @pending
-      if @queue.size == 1
+      @step = 1.0 / size * 1000.0
+      @queue = @pending
+      if size == 1
         @step = rand(1000) * 1.0
       end
       @pending = []
@@ -85,8 +89,36 @@ class Element
     end
     @last_time = glutGet(GLUT_ELAPSED_TIME)
     @last_time += @step if @queue.size == 1
-#    @last_time -= @step if @queue.size != 1
+    @rate
+  end
 
+  def render_events(engine)
+    @color ||= [1.0, 1.0, 1.0, 1.0]
+
+    t = glutGet(GLUT_ELAPSED_TIME)
+    while( (@queue.size &gt; 0) &amp;&amp; (@last_time &lt; t ) )
+
+      @last_time += @step
+      item = @queue.pop
+      url = item.message
+      color = item.color
+      size = item.size
+      type = item.type
+
+      if type == 2
+        @activities.push Activity.new(url, 0.0 - (0.008 * url.length), engine.screen.top, 0.0, color, size, type)
+      end
+    end
+
+    @activities.each do |a|
+      if a.x &gt; 1.0 || a.x &lt; -1.0 || a.y &lt; -(engine.screen.aspect*1.5)
+        @activities.delete a
+      else
+        a.wy = @wy + 0.005 if(a.type == 5 &amp;&amp; @wy != a.wy)
+        a.render(engine)
+        engine.stats[1] += 1
+      end
+    end
 
   end
 
@@ -127,7 +159,6 @@ class Element
     glPushMatrix()
     glTranslate(@x, @y, @z)
 
-    @bar_color ||= @color.dup
 
     if( rate &gt; 0.0 )
       glBegin(GL_QUADS)
@@ -187,7 +218,7 @@ class Element
 
 #    glTranslate(@x, @y, @z)
 
-    glColor( (@queue.size &gt; 0 ? (engine.screen.highlight_color || [1.0, 0.0, 0.0, 1.0]) : @color) )
+    glColor( (@queue.size &gt; 0 ? (engine.screen.highlight_color || [1.0, 0.0, 0.0, 1.0]) : @color ) )
 
     case @block.show
     when 0
@@ -212,7 +243,7 @@ class Element
       raise &quot;unknown block type #{self.inspect}&quot;
     end
 
-   if @x &lt; 0
+    if @x &lt; 0
      str = sprintf(&quot;%#{@block.width}s %s&quot;, @name.length &gt; @block.width ? @name[-@block.width..-1] : @name, txt)
     else
      str = sprintf(&quot;%s%s&quot;, txt, @name[0..@block.width-1])
@@ -225,10 +256,6 @@ class Element
     t = glutGet(GLUT_ELAPSED_TIME)
     while( (@queue.size &gt; 0) &amp;&amp; (@last_time &lt; t ) )
 
-      @bar_color[0] = @bar_color[0] + (@color[0] - @bar_color[0]) / 5
-      @bar_color[1] = @bar_color[1] + (@color[1] - @bar_color[1]) / 5
-      @bar_color[2] = @bar_color[2] + (@color[2] - @bar_color[2]) / 5
-
       @last_time += @step
       item = @queue.pop
       url = item.message
@@ -267,4 +294,25 @@ class Element
     @bar_color[2] = @bar_color[2] + (0.15 - @bar_color[2]) / 100
 
   end
+
+  def &lt;=&gt;(b)
+    b.rate &lt;=&gt; self.rate
+  end
+
+  def &gt; (b)
+    b.rate &gt; self.rate
+  end
+
+  def &lt; (b)
+    b.rate &lt; self.rate
+  end
+
+  def &lt;= (b)
+    b.rate &lt;= self.rate
+  end
+
+  def &gt;= (b)
+    b.rate &gt;= self.rate
+  end
+
 end</diff>
      <filename>lib/gl_tail/element.rb</filename>
    </modified>
    <modified>
      <diff>@@ -76,7 +76,7 @@ module GlTail
 
       @frames += 1
       t = glutGet(GLUT_ELAPSED_TIME)
-      if t - @t0 &gt;= 5000
+      if t - @t0 &gt;= 10000
         seconds = (t - @t0) / 1000.0
         $FPS = @frames / seconds
         printf(&quot;%d frames in %6.3f seconds = %6.3f FPS\n&quot;,
@@ -226,14 +226,19 @@ module GlTail
 
       glLightfv(GL_LIGHT0, GL_POSITION, [5.0, 5.0, 0.0, 0.0])
       glLightfv(GL_LIGHT0, GL_AMBIENT, [0,0,0,1])
+
+      glLightModel(GL_LIGHT_MODEL_AMBIENT, [0.1,0.1,0.1,1]);
+#      glLightModel(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
+#      glLightModel(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+
       glDisable(GL_CULL_FACE)
       glEnable(GL_LIGHTING)
       glEnable(GL_LIGHT0)
       glEnable(GL_TEXTURE_2D)
-      #    glShadeModel(GL_FLAT)
+#      glShadeModel(GL_FLAT)
       glDisable(GL_DEPTH_TEST)
-      glDisable(GL_NORMALIZE)
-      #    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)
+#      glDisable(GL_NORMALIZE)
+#      glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)
       glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST )
 
       glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)</diff>
      <filename>lib/gl_tail/engine.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>LICENSE</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>6288d977eebe1133d5edcacb3f2f7de9934544fa</id>
    </parent>
  </parents>
  <author>
    <name>erlends</name>
    <email>erlends</email>
  </author>
  <url>http://github.com/Fudge/gltail/commit/3078bc9590aa4f29238641c5546e77355821a079</url>
  <id>3078bc9590aa4f29238641c5546e77355821a079</id>
  <committed-date>2008-02-16T11:17:24-08:00</committed-date>
  <authored-date>2008-02-16T11:17:24-08:00</authored-date>
  <message>* Only sort Elements when needed
* Only sort needed elements
* Keep Element List mostly sorted
* Show Events from Elements not shown on screen</message>
  <tree>f5fce01e24deda748e7ed0757ae3b0de75c8f825</tree>
  <committer>
    <name>erlends</name>
    <email>erlends</email>
  </committer>
</commit>
