home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / v / vista / Examples / !Threads / c / threads
Encoding:
Text File  |  1996-02-01  |  8.4 KB  |  297 lines

  1. // **************************************************************************
  2. //                     Copyright 1996 David Allison
  3. //
  4. //             VV    VV    IIIIII     SSSSS     TTTTTT       AA
  5. //             VV    VV      II      SS           TT       AA  AA
  6. //             VV    VV      II        SSSS       TT      AA    AA
  7. //              VV  VV       II           SS      TT      AAAAAAAA
  8. //                VV       IIIIII     SSSS        TT      AA    AA
  9. //
  10. //                    MULTI-THREADED C++ WIMP CLASS LIBRARY
  11. //                                for RISC OS
  12. // **************************************************************************
  13. //
  14. //             P U B L I C    D O M A I N    L I C E N C E
  15. //             -------------------------------------------
  16. //
  17. //     This library is copyright. You may not sell the library for
  18. //     profit, but you may sell products which use it providing
  19. //     those products are presented as executable code and are not
  20. //     libraries themselves.  The library is supplied without any
  21. //     warranty and the copyright owner cannot be held responsible for
  22. //     damage resulting from failure of any part of this library.
  23. //
  24. //          See the User Manual for details of the licence.
  25. //
  26. // *************************************************************************
  27.  
  28. //
  29. // Example of a DialogueBox
  30. //
  31.  
  32. #include "threads.h"
  33. #include <kernel.h>
  34. #include <swis.h>
  35. #include <string.h>
  36. #include <math.h>
  37.  
  38. //
  39. // define the main program variable
  40. //
  41.  
  42. Threads *threads ;
  43.  
  44. // -------------------------
  45. // Tracker class constructor
  46. // -------------------------
  47.  
  48.  
  49. Tracker::Tracker (Task *task)
  50.    : Window (task, "main"),
  51.    Thread ("tracker")
  52.    {
  53.    _kernel_swi_regs r ;
  54.    int block[5] ;
  55.    coords_display = new Icon (this, POSITION) ;
  56.    time_display = new Icon (this, TIME) ;
  57.    select_button = new Icon (this, SELECT) ;
  58.    menu_button = new Icon (this, MENU) ;
  59.    adjust_button = new Icon (this, ADJUST) ;
  60.    select_display = new Icon (this, SELSTAT) ;
  61.    menu_display = new Icon (this, MENSTAT) ;
  62.    adjust_display = new Icon (this, ADJSTAT) ;
  63.    speed_display = new Icon (this, SPEED) ;
  64.    dist_display = new Icon (this, DIST) ;
  65.    window_display = new Icon (this, WINDOW) ;
  66.    icon_display = new Icon (this, ICON) ;
  67.    speedometer = new Meter (this, SPEEDOMETER_BACKGROUND, SPEEDOMETER_VALUE, 5000) ;
  68.    r.r[1] = (int)block ;
  69.    _kernel_swi (Wimp_GetPointerInfo, &r, &r) ;
  70.    prev_x = block[0] ;
  71.    prev_y = block[1] ;
  72.    _kernel_swi (OS_ReadMonotonicTime, &r, &r) ;
  73.    prev_time = r.r[0] ;
  74.    running = false ;
  75.    }
  76.  
  77. //
  78. // Tracker destructor
  79. //
  80.  
  81. Tracker::~Tracker()
  82.    {
  83.    delete coords_display ;
  84.    delete time_display ;
  85.    delete select_button ;
  86.    delete menu_button ;
  87.    delete adjust_button ;
  88.    delete select_display ;
  89.    delete menu_display ;
  90.    delete adjust_display ;
  91.    delete speed_display ;
  92.    delete dist_display ;
  93.    delete window_display ;
  94.    delete icon_display ;
  95.    }
  96.  
  97.  
  98. //
  99. // This is called when the user clicks in the window outside all Icons.
  100. //
  101. // Note that we have not created an Icon object for the ShowBox button
  102. // but just deal with the click on it here.  We could have created
  103. // an Icon object for it, but it makes the thing more complicated.
  104. //
  105.  
  106. void Tracker::click(int x, int y, int button, int icon)
  107.    {
  108.    if (button & 4 && icon == STOP)           // select on Stop icon
  109.       running = false ;
  110.    }
  111.  
  112. //
  113. // thread run function.  This function enters a loop until the thread is stopped
  114. // by setting the variable 'running' to false.  Vista takes care of
  115. // switching between threads and polling the OS.  There can be any number
  116. // of these threads running.  Click the iconbar icon a few times to
  117. // see it.
  118. //
  119. // The 'yield()' function is called on each iteration because it is unlikley that
  120. // the mouse has moved much in the time it takes to read its position again, so
  121. // we might as well give another thread a chance to run.  This improves
  122. // performance because it stops threads hogging the processor when there is
  123. // nothing for them to do.
  124. //
  125.  
  126. void Tracker::run()
  127.    {
  128.    _kernel_swi_regs r ;
  129.    int block[5] ;
  130.    int x, y ;
  131.    int buttons ;
  132.    int window ;
  133.    int icon ;
  134.    int xdist,ydist, dist ;
  135.    int time_diff ;
  136.    int speed ;
  137.    int prev_buttons = 0 ;
  138.    int distance = 0 ;
  139.    int select = 0 ;
  140.    int menu = 0 ;
  141.    int adjust = 0 ;
  142.    int time = 0 ;
  143.    int prev_time_display = 0 ;
  144.    running = true ;
  145.    do_open() ;                    // open the window
  146.    while (running)
  147.       {
  148.       r.r[1] =(int)block ;
  149.       _kernel_swi (Wimp_GetPointerInfo, &r, &r) ;        // read pointer position
  150.       x = block[0] ;
  151.       y = block[1] ;
  152.       buttons = block[2] ;
  153.       window = block[3] ;
  154.       icon = block[4] ;
  155.       _kernel_swi (OS_ReadMonotonicTime, &r, &r) ;        // read current time
  156.       xdist = x - prev_x ;
  157.       ydist = y - prev_y ;
  158.       time_diff = r.r[0] - prev_time ;                          // calculate time taken
  159.       time += time_diff ;
  160.       if (buttons == prev_buttons && xdist == 0 && ydist == 0)           // has mouse changed?
  161.          {
  162.          if (speed != 0)
  163.             speed_display->write (0) ;           // no, so don't change anything
  164.          speed = 0 ;
  165.          }
  166.       else
  167.          {
  168.          dist = sqrt ((xdist * xdist) + (ydist * ydist)) ;         // calculate distance moved
  169.          distance += dist ;
  170.          if (time_diff == 0)
  171.            speed = 0 ;
  172.          else
  173.             speed = (dist * 100) / time_diff ;                     // OS units per second
  174.          coords_display->print ("(%d,%d)",x,y) ;                   // display mouse position
  175.          if (buttons & 4)
  176.             {
  177.             select++ ;
  178.             select_button->select() ;
  179.             }
  180.          else
  181.             select_button->unselect() ;
  182.          if (buttons & 2)
  183.             {
  184.             menu++ ;
  185.             menu_button->select() ;
  186.             }
  187.          else
  188.             menu_button->unselect() ;
  189.          if (buttons & 1)
  190.             {
  191.             adjust++ ;
  192.             adjust_button->select() ;
  193.             }
  194.          else
  195.             adjust_button->unselect() ;
  196.          select_display->write (select) ;
  197.          menu_display->write (menu) ;
  198.          adjust_display->write (adjust) ;
  199.          speed_display->write (speed) ;
  200.          dist_display->write (distance) ;
  201.          speedometer->write (speed) ;
  202.          window_display->print ("%x",window) ;
  203.          icon_display->write (icon) ;
  204.          }
  205.       if ((time / 100) > prev_time_display)
  206.          {
  207.          int secs = time / 100 ;
  208.          int mins = secs / 60 ;
  209.          time_display->print ("%d:%02d", mins, secs % 60) ;       // display time in mins and secs
  210.          }
  211.       prev_time_display = time / 100 ;
  212.       prev_buttons = buttons ;              // store current state
  213.       prev_time = r.r[0] ;
  214.       prev_x = x ;
  215.       prev_y = y ;
  216.       yield() ;                             // give another thread a chance - improves performance
  217.       }
  218.    }
  219.  
  220.  
  221. // ************************************************************************
  222. // The main task class itself
  223. // ************************************************************************
  224.  
  225.  
  226. Threads::Threads()
  227.    : Task ("Threads Example", "Threads", "!Threads", "iconbar")
  228.    {
  229.    }
  230.  
  231. //
  232. // icon bar click on our icon
  233. //
  234.  
  235. void Threads::click (int x, int y, int button, int icon)
  236.     {
  237.     Tracker tracker(this) ;        // create a tracker
  238.     tracker.start() ;              // start it running
  239.     sleep (&tracker) ;             // sleep until thread terminates
  240.     }
  241.  
  242. //
  243. // menu hit on the iconbar menu
  244. //
  245.  
  246.  
  247. void Threads::menu(MenuItem items[])
  248.    {
  249.    switch (items[0])
  250.       {
  251.       case INFO:
  252.          {                          // need these braces
  253.          ProgramInfo proginfo (this, 4, "1.0 (9 Jan 1996)") ;
  254.          proginfo.show() ;
  255.          sleep (&proginfo) ;
  256.          break ;
  257.          }
  258.       case QUIT:
  259.          exit() ;             // exit task (Task::exit())
  260.          break ;
  261.       }
  262.    }
  263.  
  264.  
  265. main()
  266.    {
  267. #ifdef __EASY_C
  268.    try
  269. #endif
  270.       {
  271.       threads = new Threads() ;           // create the task
  272.       threads->run() ;                   // run it
  273.       }
  274. #ifdef __EASY_C
  275.    catch (_kernel_oserror *e)
  276.       {
  277.       _kernel_swi_regs r ;
  278.       r.r[0] = (int)e ;
  279.       r.r[1] = 0 ;
  280.       r.r[2] = (int)"DBox" ;
  281.       _kernel_swi (Wimp_ReportError, &r, &r) ;
  282.       }
  283.  
  284.    catch (char *s)
  285.       {
  286.       _kernel_oserror err ;
  287.       _kernel_swi_regs r ;
  288.       err.errnum = 0 ;
  289.       strcpy (err.errmess, s) ;
  290.       r.r[0] = (int)&err ;
  291.       r.r[1] = 0 ;
  292.       r.r[2] = (int)"DBox" ;
  293.       _kernel_swi (Wimp_ReportError, &r, &r) ;
  294.       }
  295. #endif
  296.    }
  297.