PageRenderTime 62ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/build45/harbour/contrib/libnf/ontick.c

#
C | 139 lines | 57 code | 23 blank | 59 comment | 10 complexity | 82eac70d606d421f7d32eb9b46c51a36 MD5 | raw file
Possible License(s): AGPL-1.0, BSD-3-Clause, CC-BY-SA-3.0, LGPL-3.0, GPL-2.0, LGPL-2.0, LGPL-2.1
  1. /*
  2. * File......: ONTICK.C
  3. * Author....: Ted Means
  4. * CIS ID....: 73067,3332
  5. *
  6. * This function is an original work by Ted Means and is placed in the
  7. * public domain.
  8. *
  9. * Modification history:
  10. * ---------------------
  11. *
  12. * Rev 1.0 01 Jan 1995 03:01:00 TED
  13. * Initial release
  14. */
  15. /* $DOC$
  16. * $FUNCNAME$
  17. * FT_OnTick()
  18. * $CATEGORY$
  19. * Event
  20. * $ONELINER$
  21. * Evaluate a designated code block at a designated interval.
  22. * $SYNTAX$
  23. * FT_OnTick( bCode, nInterval )
  24. * $ARGUMENTS$
  25. * <bCode> is the code block to evaluate.
  26. * <nInterval> is the number of clock ticks to wait between
  27. * evaluations of the code block.
  28. * $RETURNS$
  29. * NIL
  30. * $DESCRIPTION$
  31. * This function effectively allows you to run tasks in the background
  32. * by transparently and periodically calling a designated routine.
  33. *
  34. * To halt the execution of the background function, call FT_OnTick()
  35. * with no arguments.
  36. *
  37. * This function makes heavy use of several undocumented internal
  38. * routines. If this fact makes you uncomfortable then don't use
  39. * this function, you quivering sack of cowardly slime.
  40. * $EXAMPLES$
  41. *
  42. * // Set up a self-updating on-screen clock
  43. *
  44. * FT_OnTick( "CLOCK", 9 )
  45. *
  46. * procedure Clock
  47. *
  48. * local nRow := Row()
  49. * local nCol := Col()
  50. *
  51. * @ 0, 0 say Time()
  52. *
  53. * SetPos( nRow, nCol )
  54. *
  55. * return
  56. *
  57. * $SEEALSO$
  58. * $END$
  59. */
  60. #include <extend.api>
  61. #include <item.api>
  62. #include <cpmi.h>
  63. typedef union
  64. {
  65. long far * Address;
  66. struct
  67. {
  68. unsigned int Offset;
  69. unsigned int Segment;
  70. } Pointer;
  71. } LONGPTR;
  72. void cdecl _evLow( unsigned int, void *, unsigned int );
  73. void cdecl _bcopy( void *, void *, unsigned int );
  74. static long far Ticks = 0;
  75. static long far Interval = 1;
  76. static ITEM far codeBlock;
  77. static char inProgress = 0;
  78. static void cdecl TickTock( void )
  79. {
  80. auto unsigned int ProtMode = cpmiIsProtected();
  81. auto LONGPTR Timer;
  82. auto EVALINFO eval;
  83. if ( inProgress ) return;
  84. inProgress = 1;
  85. if ( ProtMode )
  86. {
  87. Timer.Pointer.Segment = cpmiProtectedPtr( ( long * ) ( 0x0000046C ), sizeof( long ) );
  88. Timer.Pointer.Offset = 0;
  89. if ( Timer.Pointer.Segment == 0 ) goto Exit;
  90. }
  91. else
  92. Timer.Address = ( long * ) ( 0x0000046C );
  93. if ( *Timer.Address >= ( Ticks + Interval ) ||
  94. ( *Timer.Address < Ticks ) )
  95. {
  96. Ticks = *Timer.Address;
  97. _evalNew( &eval, codeBlock );
  98. _itemRelease( _evalLaunch( &eval ) );
  99. }
  100. if ( ProtMode ) cpmiFreeSelector( Timer.Pointer.Segment );
  101. Exit: inProgress = 0;
  102. return;
  103. }
  104. CLIPPER FT_OnTick( void )
  105. {
  106. if ( _itemType( codeBlock ) == BLOCK ) _itemRelease( codeBlock );
  107. codeBlock = _itemParam( 1 );
  108. if ( _itemType( codeBlock ) == BLOCK )
  109. {
  110. Interval = _parnl( 2 );
  111. _evLow( 5, TickTock, TRUE );
  112. }
  113. else
  114. _evLow( 5, TickTock, FALSE );
  115. return;
  116. }