Update Iot.js
[platform/upstream/iotjs.git] / tools / src / module / iotjs_module_timer.c
1 /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include "iotjs_def.h"
17 #include "iotjs_module_timer.h"
18
19
20 static void iotjs_timerwrap_destroy(iotjs_timerwrap_t* timerwrap);
21 static void iotjs_timerwrap_on_timeout(iotjs_timerwrap_t* timerwrap);
22
23
24 iotjs_timerwrap_t* iotjs_timerwrap_create(const iotjs_jval_t* jtimer) {
25   iotjs_timerwrap_t* timerwrap = IOTJS_ALLOC(iotjs_timerwrap_t);
26   IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_timerwrap_t, timerwrap);
27
28   iotjs_handlewrap_initialize(&_this->handlewrap, jtimer,
29                               (uv_handle_t*)(&_this->handle),
30                               (JFreeHandlerType)iotjs_timerwrap_destroy);
31
32   // Initialize timer handler.
33   const iotjs_environment_t* env = iotjs_environment_get();
34   uv_timer_init(iotjs_environment_loop(env), &_this->handle);
35
36   return timerwrap;
37 }
38
39
40 static void iotjs_timerwrap_destroy(iotjs_timerwrap_t* timerwrap) {
41   IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_timerwrap_t, timerwrap);
42   iotjs_handlewrap_destroy(&_this->handlewrap);
43
44   IOTJS_RELEASE(timerwrap);
45 }
46
47
48 // This function is called from uv when timeout expires.
49 static void TimeoutHandler(uv_timer_t* handle) {
50   // Find timer wrap from handle.
51   iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_handle(handle);
52
53   // Call the timeout handler.
54   iotjs_timerwrap_on_timeout(timer_wrap);
55 }
56
57
58 int iotjs_timerwrap_start(iotjs_timerwrap_t* timerwrap, int64_t timeout,
59                           int64_t repeat) {
60   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
61
62   // Start uv timer.
63   return uv_timer_start(&_this->handle, TimeoutHandler, timeout, repeat);
64 }
65
66
67 int iotjs_timerwrap_stop(iotjs_timerwrap_t* timerwrap) {
68   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
69
70   if (!uv_is_closing(iotjs_handlewrap_get_uv_handle(&_this->handlewrap))) {
71     iotjs_handlewrap_close(&_this->handlewrap, NULL);
72   }
73
74   return 0;
75 }
76
77
78 static void iotjs_timerwrap_on_timeout(iotjs_timerwrap_t* timerwrap) {
79   IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_timerwrap_t, timerwrap);
80
81   // Call javascript timeout handler function.
82   const iotjs_jval_t* jobject = iotjs_timerwrap_jobject(timerwrap);
83   iotjs_jval_t jcallback =
84       iotjs_jval_get_property(jobject, IOTJS_MAGIC_STRING_HANDLETIMEOUT);
85   iotjs_make_callback(&jcallback, jobject, iotjs_jargs_get_empty());
86   iotjs_jval_destroy(&jcallback);
87 }
88
89
90 uv_timer_t* iotjs_timerwrap_handle(iotjs_timerwrap_t* timerwrap) {
91   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
92   return &_this->handle;
93 }
94
95
96 iotjs_jval_t* iotjs_timerwrap_jobject(iotjs_timerwrap_t* timerwrap) {
97   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
98   iotjs_jval_t* jobject = iotjs_handlewrap_jobject(&_this->handlewrap);
99   IOTJS_ASSERT(iotjs_jval_is_object(jobject));
100   return jobject;
101 }
102
103
104 iotjs_timerwrap_t* iotjs_timerwrap_from_handle(uv_timer_t* timer_handle) {
105   uv_handle_t* handle = (uv_handle_t*)(timer_handle);
106   iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle);
107   iotjs_timerwrap_t* timerwrap = (iotjs_timerwrap_t*)handlewrap;
108   IOTJS_ASSERT(iotjs_timerwrap_handle(timerwrap) == timer_handle);
109   return timerwrap;
110 }
111
112
113 iotjs_timerwrap_t* iotjs_timerwrap_from_jobject(const iotjs_jval_t* jtimer) {
114   iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_jobject(jtimer);
115   return (iotjs_timerwrap_t*)handlewrap;
116 }
117
118
119 JHANDLER_FUNCTION(Start) {
120   // Check parameters.
121   JHANDLER_CHECK_THIS(object);
122   JHANDLER_CHECK_ARGS(2, number, number);
123
124   const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
125
126   // Take timer wrap.
127   iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(jtimer);
128
129   // parameters.
130   int64_t timeout = JHANDLER_GET_ARG(0, number);
131   int64_t repeat = JHANDLER_GET_ARG(1, number);
132
133   // Start timer.
134   int res = iotjs_timerwrap_start(timer_wrap, timeout, repeat);
135
136   iotjs_jhandler_return_number(jhandler, res);
137 }
138
139
140 JHANDLER_FUNCTION(Stop) {
141   JHANDLER_CHECK_THIS(object);
142
143   const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
144
145   iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(jtimer);
146
147   // Stop timer.
148   int res = iotjs_timerwrap_stop(timer_wrap);
149
150   iotjs_jhandler_return_number(jhandler, res);
151 }
152
153
154 JHANDLER_FUNCTION(Timer) {
155   JHANDLER_CHECK_THIS(object);
156
157   const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
158
159   iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_create(jtimer);
160   IOTJS_ASSERT(iotjs_jval_is_object(iotjs_timerwrap_jobject(timer_wrap)));
161   IOTJS_ASSERT(iotjs_jval_get_object_native_handle(jtimer) != 0);
162 }
163
164
165 iotjs_jval_t InitTimer() {
166   iotjs_jval_t timer = iotjs_jval_create_function_with_dispatch(Timer);
167
168   iotjs_jval_t prototype = iotjs_jval_create_object();
169   iotjs_jval_set_property_jval(&timer, IOTJS_MAGIC_STRING_PROTOTYPE,
170                                &prototype);
171
172   iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_START, Start);
173   iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_STOP, Stop);
174
175   iotjs_jval_destroy(&prototype);
176
177   return timer;
178 }