home *** CD-ROM | disk | FTP | other *** search
/ Peanuts NeXT Software Archives / Peanuts-Update.iso / Rhapsody / developer / examples / LocalizationExample.5.0.m.I.bs.tz / LocalizationExample.5.0.m.I.bs / LocalizationExample.5.0.I.bs / Source / Animator.m < prev    next >
Encoding:
Text File  |  1997-10-22  |  4.9 KB  |  232 lines

  1. //  Animator.m
  2. //  Object for general timing, animation, and dynamics.
  3. //  Author: R. E. Crandall, Educational Technology Center
  4. //  10-Apr-88
  5. //  Revised by Bluce Blumberg for 0.8, 29-Sep-88
  6. //  Revised for 1.0 by Ali Ozer, 13-Jun-89
  7. //  Revised for 2.0 by Jayson Adams, 14-Oct-90
  8. //
  9. // You may freely copy, distribute and reuse the code in this example.
  10. // NeXT disclaims any warranty of any kind, expressed or implied, as to its
  11. // fitness for any particular use.
  12.  
  13. /*
  14.  *  An 'Animator' controls the timing for your action method of choice.
  15.  *  The object may function as a general timer object; i.e.
  16.  *  graphics are neither expected nor required by the class.
  17.  *  When you create an Animator with +newChronon, you specify
  18.  *  the time interval between calls, the adaptation time constant (see below),
  19.  *  the target to which the method belongs, the action name, whether to 
  20.  *  automatically start up the timing upon creation, and an event mask (if you     
  21.  *  plan to break conditionally out of loops within the action method).
  22.  *
  23.  *  The Animator has adaptive means for adjusting to harsh operating
  24.  *  environments.  An adaptation constant d > 0. will invoke dynamical 
  25.  *  correction of entry times, on-the-fly, so that the desired chronon
  26.  *  will be realized in a real-time sense.
  27.  *
  28.  *  Functionality and applications are discussed in Report ETC-0008.
  29.  */
  30.  
  31. #import "Animator.h"
  32.  
  33. #import <sys/time.h>
  34. #import <objc/objc-runtime.h>
  35.  
  36. @interface Animator(private_methods)
  37.  
  38. - (void)_timerFunction:(NSTimer *)theTimer;
  39.  
  40. @end
  41.  
  42. @implementation Animator
  43.  
  44. - (void)_timerFunction:(NSTimer *)theTimer
  45. {
  46.     gettimeofday(&entrytime, NULL);
  47.     if (howOften > 0.0) {
  48.         [self adapt];
  49.     }
  50.  
  51.     [target performSelector:action withObject:self];
  52. }
  53.  
  54. - initChronon:(double)dt    /* The time increment desired. */
  55.   adaptation:(double)howoft    /* Adaptive time constant (0.deactivates).*/
  56.   target:(id)targ        /* Target to whom proc belongs. */
  57.   action:(SEL)act        /* The action. */
  58.   autoStart:(int)start        /* Automatic start of timed entry? */
  59.   eventMask:(int)eMask        /* Mask for optional check in "shouldBreak". */
  60. {
  61.     [super init];
  62.     ticking = NO;
  63.     desireddt = dt;
  64.     [self setIncrement:dt];
  65.     [self setAdaptation:howoft];
  66.     [self setTarget:targ];
  67.     [self setAction:act];
  68.     
  69.     if (start) {
  70.     [self startEntry];
  71.     }
  72.     
  73.     mask = eMask;
  74.     [self resetRealTime];
  75.     
  76.     return self;
  77. }
  78.  
  79. - resetRealTime
  80. /* After this call, getDoubleRealTime is the real time that ensues. */
  81.     struct timeval    realtime;
  82.     
  83.     gettimeofday(&realtime, NULL);
  84.     synctime = realtime.tv_sec + realtime.tv_usec / 1000000.0;
  85.     passcounter = 0;
  86.     t0 = 0.0;
  87.     
  88.     return self;
  89. }
  90.  
  91. - (double)getSyncTime
  92. {
  93.     return synctime;
  94. }
  95.  
  96. - (double)getDoubleEntryTime
  97. /* Returns real time since "resetrealTime". */
  98. {
  99.     return (- synctime + entrytime.tv_sec + entrytime.tv_usec / 1000000.0);
  100. }
  101.  
  102. - (double)getDoubleRealTime
  103. /* Returns real time since "resetrealTime". */
  104. {
  105.     struct timeval    realtime;
  106.     struct timezone    tzone;
  107.     
  108.     gettimeofday(&realtime, &tzone);
  109.     return (- synctime + realtime.tv_sec + realtime.tv_usec / 1000000.0);
  110. }
  111.  
  112. - (double)getDouble
  113. {
  114.     return [self getDoubleRealTime];
  115. }
  116.  
  117. - adapt
  118. /* Adaptive time-step algorithm. */
  119. {
  120.     double t;
  121.     
  122.     if (!ticking) {
  123.     return self;
  124.     }
  125.     
  126.     ++passcounter;
  127.     t = [self getDoubleEntryTime];
  128.     
  129.     if (t - t0 >= howOften) {      
  130.     adapteddt *= desireddt * passcounter / (t - t0);
  131.     [self setIncrement:adapteddt];
  132.     [self startEntry];
  133.     passcounter = 0;
  134.     t0 = t;
  135.     }
  136.     return self;
  137. }
  138.   
  139. - setBreakMask:(int)eventMask
  140. {
  141.     mask = eventMask;
  142.     return self;
  143. }
  144.  
  145. - (int)getBreakMask
  146. {
  147.     return mask;
  148. }
  149.  
  150. - (int)isTicking
  151. {
  152.     return ticking;
  153. }
  154.    
  155. - (int)shouldBreak
  156. /* Call this to see if you want to exit a loop in your action method. */
  157. {
  158.     NSEvent *e, *event;
  159.     
  160.     e = (event = [NSApp nextEventMatchingMask:mask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.0] inMode:NSEventTrackingRunLoopMode dequeue:NO]);
  161.            
  162.     return (e ? 1: 0);
  163. }
  164.  
  165. - setIncrement:(double)dt
  166. {
  167.     adapteddt = dt;
  168.     interval = dt;
  169.   
  170.     return self;
  171. }
  172.  
  173. - (double)getIncrement
  174. {
  175.     return adapteddt;
  176. }
  177.  
  178. - setAdaptation:(double)oft
  179. {
  180.     howOften = oft;
  181.     return self;
  182. }
  183.  
  184. - (void)setTarget:(id)targ
  185. {
  186.     target = targ;
  187. }
  188.  
  189. - (void)setAction:(SEL)aSelector
  190. {
  191.     action = aSelector;
  192. }
  193.  
  194. - startEntry
  195.     [self stopEntry];    
  196.     teNum = [[NSTimer timerWithTimeInterval:interval target:self selector:@selector(_timerFunction:) userInfo:nil repeats:YES] retain];
  197.     [[NSRunLoop currentRunLoop] addTimer:teNum forMode:NSDefaultRunLoopMode];
  198.     [[NSRunLoop currentRunLoop] addTimer:teNum forMode:NSModalPanelRunLoopMode];
  199.     [[NSRunLoop currentRunLoop] addTimer:teNum forMode:NSEventTrackingRunLoopMode];
  200.     ticking = YES;
  201.     
  202.     return self;
  203. }
  204.  
  205. - stopEntry
  206. {
  207.     if (ticking) {
  208.         [teNum invalidate];
  209.         [teNum release];
  210.         teNum = nil;
  211.     }
  212.     ticking = NO;
  213.     
  214.     return self;
  215. }
  216.  
  217. - (void)dealloc
  218. {
  219.     if (ticking) {
  220.         [teNum invalidate];
  221.         [teNum release];
  222.         teNum = nil;
  223.     }
  224.     
  225.     [super dealloc];
  226.     return;
  227. }
  228.  
  229. @end    
  230.