|
11 | 11 | info.GetReturnValue().Set(Nan::New(wrapper->{{ field.name }})); |
12 | 12 |
|
13 | 13 | {% elsif field.isCallbackFunction %} |
14 | | - if (wrapper->{{field.name}} != NULL) { |
15 | | - info.GetReturnValue().Set(wrapper->{{ field.name }}->GetFunction()); |
| 14 | + if (wrapper->{{field.name}}.HasCallback()) { |
| 15 | + info.GetReturnValue().Set(wrapper->{{ field.name }}.GetCallback()->GetFunction()); |
16 | 16 | } else { |
17 | 17 | info.GetReturnValue().SetUndefined(); |
18 | 18 | } |
|
31 | 31 | } |
32 | 32 |
|
33 | 33 | NAN_SETTER({{ cppClassName }}::Set{{ field.cppFunctionName }}) { |
34 | | - |
35 | 34 | {{ cppClassName }} *wrapper = Nan::ObjectWrap::Unwrap<{{ cppClassName }}>(info.This()); |
36 | 35 |
|
37 | 36 | {% if field.isEnum %} |
|
47 | 46 | wrapper->raw->{{ field.name }} = {% if not field.cType | isPointer %}*{% endif %}{% if field.cppClassName == 'GitStrarray' %}StrArrayConverter::Convert({{ field.name }}->ToObject()){% else %}Nan::ObjectWrap::Unwrap<{{ field.cppClassName }}>({{ field.name }}->ToObject())->GetValue(){% endif %}; |
48 | 47 |
|
49 | 48 | {% elsif field.isCallbackFunction %} |
50 | | - if (wrapper->{{ field.name }} != NULL) { |
51 | | - delete wrapper->{{ field.name }}; |
52 | | - } |
| 49 | + Nan::Callback *callback = NULL; |
| 50 | + int throttle = {%if field.return.throttle %}{{ field.return.throttle }}{%else%}0{%endif%}; |
53 | 51 |
|
54 | 52 | if (value->IsFunction()) { |
| 53 | + callback = new Nan::Callback(value.As<Function>()); |
| 54 | + } else if (value->IsObject()) { |
| 55 | + Local<Object> object = value.As<Object>(); |
| 56 | + Local<String> callbackKey; |
| 57 | + Nan::MaybeLocal<Value> maybeObjectCallback = Nan::Get(object, Nan::New("callback").ToLocalChecked()); |
| 58 | + if (!maybeObjectCallback.IsEmpty()) { |
| 59 | + Local<Value> objectCallback = maybeObjectCallback.ToLocalChecked(); |
| 60 | + if (objectCallback->IsFunction()) { |
| 61 | + callback = new Nan::Callback(objectCallback.As<Function>()); |
| 62 | + Nan::MaybeLocal<Value> maybeObjectThrottle = Nan::Get(object, Nan::New("throttle").ToLocalChecked()); |
| 63 | + if(!maybeObjectThrottle.IsEmpty()) { |
| 64 | + Local<Value> objectThrottle = maybeObjectThrottle.ToLocalChecked(); |
| 65 | + if (objectThrottle->IsNumber()) { |
| 66 | + throttle = (int)objectThrottle.As<Number>()->Value(); |
| 67 | + } |
| 68 | + } |
| 69 | + } |
| 70 | + } |
| 71 | + } |
| 72 | + if (callback) { |
55 | 73 | if (!wrapper->raw->{{ field.name }}) { |
56 | 74 | wrapper->raw->{{ field.name }} = ({{ field.cType }}){{ field.name }}_cppCallback; |
57 | 75 | } |
58 | 76 |
|
59 | | - wrapper->{{ field.name }} = new Nan::Callback(value.As<Function>()); |
| 77 | + wrapper->{{ field.name }}.SetCallback(callback, throttle); |
60 | 78 | } |
61 | 79 |
|
62 | 80 | {% elsif field.payloadFor %} |
|
82 | 100 | } |
83 | 101 |
|
84 | 102 | {% if field.isCallbackFunction %} |
| 103 | + {{ cppClassName }}* {{ cppClassName }}::{{ field.name }}_getInstanceFromBaton({{ field.name|titleCase }}Baton* baton) { |
| 104 | + return static_cast<{{ cppClassName }}*>(baton->{% each field.args|argsInfo as arg %} |
| 105 | + {% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %} |
| 106 | + {% endeach %}); |
| 107 | + } |
| 108 | + |
85 | 109 | {{ field.return.type }} {{ cppClassName }}::{{ field.name }}_cppCallback ( |
86 | 110 | {% each field.args|argsInfo as arg %} |
87 | 111 | {{ arg.cType }} {{ arg.name}}{% if not arg.lastArg %},{% endif %} |
88 | 112 | {% endeach %} |
89 | 113 | ) { |
90 | | - {{ field.name|titleCase }}Baton* baton = new {{ field.name|titleCase }}Baton(); |
| 114 | + {{ field.name|titleCase }}Baton* baton = |
| 115 | + new {{ field.name|titleCase }}Baton({{ field.return.noResults }}); |
91 | 116 |
|
92 | 117 | {% each field.args|argsInfo as arg %} |
93 | 118 | baton->{{ arg.name }} = {{ arg.name }}; |
94 | 119 | {% endeach %} |
95 | 120 |
|
96 | | - baton->result = 0; |
97 | | - baton->req.data = baton; |
98 | | - baton->done = false; |
99 | | - |
100 | | - uv_async_init(uv_default_loop(), &baton->req, (uv_async_cb) {{ field.name }}_async); |
101 | | - { |
102 | | - LockMaster::TemporaryUnlock temporaryUnlock; |
103 | | - |
104 | | - uv_async_send(&baton->req); |
| 121 | + {{ cppClassName }}* instance = {{ field.name }}_getInstanceFromBaton(baton); |
105 | 122 |
|
106 | | - while(!baton->done) { |
107 | | - sleep_for_ms(1); |
108 | | - } |
| 123 | + if (instance->{{ field.name }}.WillBeThrottled()) { |
| 124 | + return baton->defaultResult; |
109 | 125 | } |
110 | 126 |
|
111 | | - return baton->result; |
| 127 | + return baton->ExecuteAsync((uv_async_cb) {{ field.name }}_async); |
112 | 128 | } |
113 | 129 |
|
114 | 130 | void {{ cppClassName }}::{{ field.name }}_async(uv_async_t* req, int status) { |
115 | 131 | Nan::HandleScope scope; |
116 | 132 |
|
117 | 133 | {{ field.name|titleCase }}Baton* baton = static_cast<{{ field.name|titleCase }}Baton*>(req->data); |
118 | | - {{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>(baton->{% each field.args|argsInfo as arg %} |
119 | | - {% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %} |
120 | | - {% endeach %}); |
| 134 | + {{ cppClassName }}* instance = {{ field.name }}_getInstanceFromBaton(baton); |
121 | 135 |
|
122 | | - if (instance->{{ field.name }}->IsEmpty()) { |
| 136 | + if (instance->{{ field.name }}.GetCallback()->IsEmpty()) { |
123 | 137 | {% if field.return.type == "int" %} |
124 | | - baton->result = {{ field.return.noResults }}; // no results acquired |
| 138 | + baton->result = baton->defaultResult; // no results acquired |
125 | 139 | {% endif %} |
126 | 140 |
|
127 | 141 | baton->done = true; |
|
163 | 177 | }; |
164 | 178 |
|
165 | 179 | Nan::TryCatch tryCatch; |
166 | | - Local<v8::Value> result = instance->{{ field.name }}->Call({{ field.args|jsArgsCount }}, argv); |
| 180 | + Local<v8::Value> result = instance->{{ field.name }}.GetCallback()->Call({{ field.args|jsArgsCount }}, argv); |
167 | 181 |
|
168 | 182 | uv_close((uv_handle_t*) &baton->req, NULL); |
169 | 183 |
|
|
187 | 201 | baton->result = (int)result->ToNumber()->Value(); |
188 | 202 | } |
189 | 203 | else { |
190 | | - baton->result = {{ field.return.noResults }}; |
| 204 | + baton->result = baton->defaultResult; |
191 | 205 | } |
192 | 206 | {% endif %} |
193 | 207 | } |
194 | 208 | else { |
195 | | - baton->result = {{ field.return.noResults }}; |
| 209 | + baton->result = baton->defaultResult; |
196 | 210 | } |
197 | 211 | {% endeach %} |
198 | 212 | baton->done = true; |
|
220 | 234 | baton->result = (int)result->ToNumber()->Value(); |
221 | 235 | } |
222 | 236 | else{ |
223 | | - baton->result = {{ field.return.noResults }}; |
| 237 | + baton->result = baton->defaultResult; |
224 | 238 | } |
225 | 239 | {% endif %} |
226 | 240 | } |
227 | 241 | else { |
228 | | - baton->result = {{ field.return.noResults }}; |
| 242 | + baton->result = baton->defaultResult; |
229 | 243 | } |
230 | 244 | {% endeach %} |
231 | 245 | } |
|
0 commit comments