y_timers_v5.inc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #define _SPECIAL_FUNCTION@timer%0[%2](%1) FUNC_PARSER(TIMER,QAL:ARR_CST:REF_DEF:STR_CST_DEF:NUM_CST_DEF:)(%0(%1))(%0(%1))()(%2)()#
  2. // TIMER_STR(const, tag, name, size)rest$(original_call)(time)(pass_parameters)specifier#
  3. #define TIMER_STR(%6,%9,%2,%5,%9)%8$(%7)(%0)(%1)(%3)%4# %8$(%7)(%0,%6%2[%5])(%1)(%3,%2)%4s#
  4. #define TIMER_ARR(%6,%9,%2,%5,%9)%8$(%7)(%0)(%1)(%3)%4# %8$(%7)(%0,%6%2[%5])(%1)(%3,%2)%4a#
  5. #define TIMER_NUM(%6,%9,%2,%9)%8$(%7)(%0)(%1)(%3)%4# %8$(%7)(%0,%6%2)(%1)(%3,%2)%4i#
  6. #define TIMER_REF(%6,%9,%2,%9)%8$(%7)(%0)(%1)(%3)%4# %8$(%7)(%0,%6&%2)(%1)(%3,%2)%4v#
  7. // ".." is used to reserve memory at the start of the string for:
  8. //
  9. // +0 - TIMER function start pointer.
  10. // +1 - Stack size.
  11. #define TIMER_END(%9)%8$(%0(%7))(,%1)(%5)(%3)%4# %8$_yT@%0(%7)return SetTimerEx(#%0,(I@==-1)?(%5):I@,J@,#%4%3)%0(%1);public %0(%1)
  12. #define TIMER_NUL(%9)%8$(%0(%7))(%1)(%5)(%3)%4# %8$_yT@%0()return SetTimer(#%0,(I@==-1)?(%5):I@,J@)%0();public %0()
  13. #define _yT@%0\32; _yT@
  14. #define @_yT%0\32; @_yT
  15. #define @yT_%0\32; @yT_
  16. #define _SPECIAL_FUNCTION@task%0[%1](%2) @yT_%0(g,p);new %0;@yT_%0(g,p){static s=-1;return _Timer_I(#%0,%1,g,s);}@_yT%0();public @_yT%0()
  17. #define _SPECIAL_FUNCTION@ptask%0[%1](%2) @yT_%0(E_TIMER_ACTION:a,p);new %0;@yT_%0(E_TIMER_ACTION:a,p){static s[MAX_PLAYERS]={-1,...},a[2];return Timer_RunPTask_((!"@_yT"#%0),(%0),(%1),a,p,s);}@_yT%0(%2);public @_yT%0(%2)
  18. enum E_TIMER_ACTION
  19. {
  20. E_TIMER_ACTION_REGISTER,
  21. E_TIMER_ACTION_GET,
  22. E_TIMER_ACTION_START,
  23. E_TIMER_ACTION_START_ALL,
  24. E_TIMER_ACTION_STOP,
  25. E_TIMER_ACTION_STOP_ALL,
  26. }
  27. #if !defined MAX_PTASKS
  28. #define MAX_PTASKS (32)
  29. #endif
  30. static stock
  31. YSI_g_sPTaskCount,
  32. YSI_g_sPTasks[MAX_PTASKS];
  33. #if 0
  34. // Options for possible unified function declaration syntax.
  35. //@.task // Indirection
  36. //@:task // All tags
  37. @[task] // Maybe (but also clashey)
  38. @<task> // Maybe (but also clashey)
  39. @(task) // Maybe (but also clashey)
  40. __<hook> // Compiler-reserved, but we can have community consensus.
  41. __hook // No, too clashey.
  42. _.hook
  43. @hook
  44. hook@
  45. __declspec(hook)
  46. __func(hook)
  47. __func hook
  48. @ hook OnPlayerConnect()
  49. {
  50. }
  51. HOOK__ OnPlayerConnect()
  52. {
  53. }
  54. TASK__
  55. TIMER__
  56. PTASK__
  57. FOREACH__
  58. #if defined KEYWORD_hook
  59. #define hook HOOK__
  60. #endif
  61. #endif
  62. stock bool:Timer_RunPTask_(const name[], &ptr, const interval, const E_TIMER_ACTION:action, playerid, results[])
  63. {
  64. switch (action)
  65. {
  66. case E_TIMER_ACTION_REGISTER:
  67. {
  68. if (YSI_g_sPTaskCount >= MAX_PTASKS)
  69. {
  70. P:E("MAX_PTASKS exceeded, please recompile with `#define MAX_PTASKS (more)`");
  71. }
  72. else
  73. {
  74. // Get the entry point, not the action.
  75. new entryPoint[32];
  76. strunpack(entryPoint, name);
  77. entryPoint[0] = '@';
  78. entryPoint[0] = 'y';
  79. entryPoint[0] = 'T';
  80. entryPoint[0] = '_';
  81. YSI_g_sPTasks[YSI_g_sPTaskCount] = GetPublicAddressFromName(entryPoint);
  82. //YSI_g_sPTasks[YSI_g_sPTaskCount] = playerid; // Action param.
  83. ptr = YSI_g_sPTaskCount++;
  84. }
  85. }
  86. case E_TIMER_ACTION_GET:
  87. {
  88. // Check if the timer is running for this player.
  89. return !!results[playerid];
  90. }
  91. case E_TIMER_ACTION_START:
  92. {
  93. if (results[playerid])
  94. {
  95. KillTimer(results[playerid]);
  96. }
  97. results[playerid] = SetTimerEx(name, interval, true, "i", playerid);
  98. }
  99. case E_TIMER_ACTION_START_ALL:
  100. {
  101. FOREACH__ (playerid : Player)
  102. {
  103. if (results[playerid])
  104. {
  105. KillTimer(results[playerid]);
  106. }
  107. results[playerid] = SetTimerEx(name, interval, true, "i", playerid);
  108. }
  109. }
  110. case E_TIMER_ACTION_STOP:
  111. {
  112. if (results[playerid])
  113. {
  114. KillTimer(results[playerid]);
  115. results[playerid] = 0;
  116. }
  117. }
  118. case E_TIMER_ACTION_STOP_ALL:
  119. {
  120. FOREACH__ (playerid : Player)
  121. {
  122. if (results[playerid])
  123. {
  124. KillTimer(results[playerid]);
  125. }
  126. }
  127. }
  128. }
  129. return false;
  130. }