/src/scripts/ns_timer.c

https://bitbucket.org/portix/dwb · C · 158 lines · 77 code · 18 blank · 63 comment · 17 complexity · 576f91d9d2b84e7b06b033cb4d5771c7 MD5 · raw file

  1. /*
  2. * Copyright (c) 2010-2014 Stefan Bolte <portix@gmx.net>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. #include "private.h"
  19. /**
  20. * @callback timer~startCallback
  21. * @returns {Boolean}
  22. * Return true to stop the timer
  23. * */
  24. static gboolean
  25. timeout_callback(JSObjectRef obj)
  26. {
  27. gboolean ret = false;
  28. JSContextRef ctx = scripts_get_global_context();
  29. if (ctx == NULL)
  30. return false;
  31. JSValueRef val = scripts_call_as_function(ctx, obj, obj, 0, NULL);
  32. if (val == NULL)
  33. ret = false;
  34. else
  35. ret = !JSValueIsBoolean(ctx, val) || JSValueToBoolean(ctx, val);
  36. scripts_release_global_context();
  37. return ret;
  38. }
  39. /**
  40. * For internal usage only
  41. *
  42. * @name _stop
  43. * @memberOf timer
  44. * @function
  45. * @private
  46. * */
  47. /**
  48. * Stops a timer started by {@link timerStart}
  49. * @name stop
  50. * @memberOf timer
  51. * @function
  52. *
  53. * @param {Number} id
  54. * A timer handle retrieved from {@link timer.start|start}
  55. *
  56. * @returns {Boolean}
  57. * true if the timer was stopped
  58. * */
  59. static JSValueRef
  60. timer_stop(JSContextRef ctx, JSObjectRef f, JSObjectRef self, size_t argc, const JSValueRef argv[], JSValueRef* exc)
  61. {
  62. if (argc < 1)
  63. {
  64. js_make_exception(ctx, exc, EXCEPTION("timerStop: missing argument."));
  65. return JSValueMakeBoolean(ctx, false);
  66. }
  67. gdouble sigid = JSValueToNumber(ctx, argv[0], exc);
  68. if (!isnan(sigid))
  69. {
  70. ScriptContext *sctx = scripts_get_context();
  71. if (sctx == NULL)
  72. return JSValueMakeBoolean(ctx, false);
  73. gboolean ret = g_source_remove((int)sigid);
  74. GSList *source = g_slist_find(sctx->timers, GINT_TO_POINTER(sigid));
  75. if (source)
  76. sctx->timers = g_slist_delete_link(sctx->timers, source);
  77. scripts_release_context();
  78. return JSValueMakeBoolean(ctx, ret);
  79. }
  80. return JSValueMakeBoolean(ctx, false);
  81. }
  82. /**
  83. * For internal usage only
  84. *
  85. * @name _start
  86. * @memberOf timer
  87. * @function
  88. * @private
  89. * */
  90. /* global_timer_start {{{*/
  91. static JSValueRef
  92. timer_start(JSContextRef ctx, JSObjectRef f, JSObjectRef self, size_t argc, const JSValueRef argv[], JSValueRef* exc)
  93. {
  94. if (argc < 2)
  95. {
  96. js_make_exception(ctx, exc, EXCEPTION("timerStart: missing argument."));
  97. return JSValueMakeNumber(ctx, -1);
  98. }
  99. double msec = JSValueToNumber(ctx, argv[0], exc);
  100. int ret = -1;
  101. if (isnan(msec))
  102. return JSValueMakeNumber(ctx, -1);
  103. JSObjectRef func = js_value_to_function(ctx, argv[1], exc);
  104. if (func == NULL)
  105. return JSValueMakeNumber(ctx, -1);
  106. JSValueProtect(ctx, func);
  107. ScriptContext *sctx = scripts_get_context();
  108. if (sctx != NULL) {
  109. ret = g_timeout_add_full(G_PRIORITY_DEFAULT, (int)msec, (GSourceFunc)timeout_callback, func, (GDestroyNotify)scripts_unprotect);
  110. sctx->timers = g_slist_prepend(sctx->timers, GINT_TO_POINTER(ret));
  111. scripts_release_context();
  112. }
  113. return JSValueMakeNumber(ctx, ret);
  114. }
  115. JSObjectRef
  116. timer_initialize(JSContextRef ctx) {
  117. /**
  118. * Static object for timed execution
  119. * @namespace
  120. * Static object for timed execution
  121. * @name timer
  122. * @static
  123. * @example
  124. * //!javascript
  125. *
  126. * var timer = namespace("timer");
  127. * */
  128. JSObjectRef global_object = JSContextGetGlobalObject(ctx);
  129. JSObjectRef ret;
  130. JSStaticFunction timer_functions[] = {
  131. { "_start", timer_start, kJSDefaultAttributes },
  132. // FIXME: wrapper isn't really necessary
  133. { "_stop", timer_stop, kJSDefaultAttributes },
  134. { 0, 0, 0 },
  135. };
  136. JSClassRef klass = scripts_create_class("timer", timer_functions, NULL, NULL);
  137. ret = scripts_create_object(ctx, klass, global_object, kJSDefaultAttributes, "timer", NULL);
  138. JSClassRelease(klass);
  139. return ret;
  140. }