home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / Palettes / TTools / TToolsPalette / Utilities.subproj / SortedList.m < prev    next >
Encoding:
Text File  |  1993-11-09  |  3.4 KB  |  156 lines

  1. /* SortedList.m
  2.  * Written By:  Thomas Burkholder
  3.  *
  4.  * You may freely copy, distribute, and reuse the code in this example.
  5.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  6.  * fitness for any particular use.
  7.  */
  8.  
  9. #import "SortedList.h"
  10.  
  11. @implementation SortedList:List
  12.  
  13. - initCount:(unsigned)numSlots
  14. {
  15.     [super initCount:numSlots];
  16.     agent = nil;
  17.     return self;
  18. }
  19.  
  20. - setAgent:anObject
  21. {
  22.     agent = anObject;
  23.     return self;
  24. }
  25.  
  26. - agent
  27. {
  28.     return agent;
  29. }
  30.  
  31. - (id)subdirectoryForObjectAt:(int)at
  32. {
  33.     if (agent && [agent respondsTo:@selector(subdirectoryFor:sender:)])
  34.         return [agent subdirectoryFor:[self objectAt:at] sender:self];
  35.     return nil;  // default is no entries.
  36. }
  37.  
  38. - (BOOL)isLeafAt:(int)at
  39. {
  40.     if (agent && [agent respondsTo:@selector(isLeaf:sender:)])
  41.         return [agent isLeaf:[self objectAt:at] sender:self];
  42.     return YES;  // default is YES.
  43. }
  44.  
  45. - (const char *)displayStringForObjectAt:(int)at
  46. {
  47.     if (agent && [agent respondsTo:@selector(displayStringFor:sender:)])
  48.         return [agent displayStringFor:[self objectAt:at] sender:self];
  49.     return NULL;  // default is YES.
  50. }
  51.  
  52. - (int)compareObjectAt:(int)at with:object
  53. {
  54.     if (agent && [agent respondsTo:@selector(compare:with:sender:)])
  55.         return [agent compare:[self objectAt:at] with:object sender:self];
  56.     return 1;  //By default, it's smaller, so it get's appended.
  57. }
  58.  
  59. - (int)browser:sender fillMatrix:matrix inColumn:(int)column
  60. {
  61.     id c;
  62.     int i,n;
  63.     id candidate = self;
  64.  
  65.     if (column != 0) {
  66.         for(i=0;(i<column);i++) {
  67.             candidate = [candidate subdirectoryForObjectAt:[[sender matrixInColumn:i] selectedRow]];
  68.             if ((!candidate) || (![candidate isKindOf:[SortedList class]])) return 0;
  69.         }
  70.     }
  71.  
  72.     for(i=0,n=[candidate count];i<n;i++) {
  73.         [matrix addRow];
  74.         c = [matrix cellAt:i :0];
  75.         [c setLeaf:[candidate isLeafAt:i]];
  76.         [c setLoaded:YES];
  77.         [c setStringValue:[candidate displayStringForObjectAt:i]];
  78.     }
  79.     return i;
  80. }
  81.  
  82. - (const char *)browser:sender titleOfColumn:(int)column
  83. {
  84.     return [agent titleOfColumn:column];
  85. }
  86.  
  87. - binaryInsert:anObject between:(int)lower and:(int)upper
  88. {
  89.     int r,c = lower + (1+upper-lower)/2;
  90.  
  91.     if (lower == upper) {  
  92.         if ([self compareObjectAt:lower with:anObject]>0) // insert before
  93.             return [super insertObject:anObject at:lower];
  94.         else  // insert after
  95.             return [super insertObject:anObject at:lower+1];
  96.     }
  97.  
  98.     r = [self compareObjectAt:c with:anObject];
  99.     if (r>0)  // Recursion is Good.
  100.         return [self binaryInsert:anObject between:lower and:c-1];
  101.     else if (r<0)  // In fact, Recursion is Holy.
  102.         return [self binaryInsert:anObject between:c and:upper];
  103.     else  // if equal insert right now.
  104.         return [super insertObject:anObject at:c];
  105. }
  106.  
  107. - addObject:anObject  // Assumes sorted list
  108. {
  109.     // Binary insertion...
  110.     if (![self count])
  111.         return [super addObject:anObject];
  112.     [self binaryInsert:anObject between:0 and:[self count]-1];
  113.     return self;
  114. }
  115.  
  116. - sort:sender
  117. {
  118.     id l = [[List alloc] init];
  119.     int i, n;
  120.  
  121.     // move our elements into plain old list.
  122.     for(i=0,n=[self count];(i<n);i++)
  123.         [l addObject:[self objectAt:i]];
  124.     [self empty];
  125.  
  126.  
  127.     // re-insert everything.
  128.     for(i=0,n=[l count];(i<n);i++)
  129.         [self addObject:[l objectAt:i]];
  130.     [l empty];
  131.     [l free];
  132.     return self;
  133. }
  134.  
  135. - read:(NXTypedStream *)stream
  136. {
  137.     [super read:stream];
  138.     agent = NXReadObject(stream);
  139.     return self;
  140. }
  141.  
  142. - awakeFromNib
  143. {
  144.     // This won't be called in Test Interface mode.
  145.     [self sort:self];
  146.     return self;
  147. }
  148.  
  149. - write:(NXTypedStream *)stream
  150. {
  151.     [super write:stream];
  152.     NXWriteObject(stream,agent);
  153.     return self;
  154. }
  155.  
  156. @end