comparison nodejs/shapes.cc @ 683:7685c57e29d0

Migrate JS shapes binding to gen_v8_binding.m4
author Thinker K.F. Li <thinker@branda.to>
date Sat, 07 Aug 2010 18:27:53 +0800
parents c643af2095c5
children b346e4699e55
comparison
equal deleted inserted replaced
682:4a38e571cfce 683:7685c57e29d0
1 #include <v8.h> 1 #include <v8.h>
2 #include "mbfly_njs.h" 2 #include "mbfly_njs.h"
3
4 #include <string.h>
3 5
4 extern "C" { 6 extern "C" {
5 #include <mb.h> 7 #include <mb.h>
6 } 8 }
7 9
9 #define ASSERT(x) 11 #define ASSERT(x)
10 #endif 12 #endif
11 13
12 using namespace v8; 14 using namespace v8;
13 15
14 /*! \defgroup shape_temp Templates for shape and derivations. 16 /*! \defgroup xnjsmb_shapes Implement binding of shapes.
17 * \ingroup xnjsmb
15 * 18 *
16 * @{ 19 * @{
17 */ 20 */
18 static Persistent<FunctionTemplate> xnjsmb_shape_temp; 21 static void
19 22 xnjsmb_sh_stext_set_style(shape_t *sh, Handle<Value> blks, const char **err) {
20 static Handle<Value> 23 Array *blksobj;
21 xnjsmb_shape_show(const Arguments &args) { 24 Array *blkobj;
22 shape_t *sh; 25 mb_style_blk_t *mb_blks;
23 Handle<Object> self; 26 int nblks;
24 27 int r;
25 self = args.This(); 28 int i;
26 sh = (shape_t *)UNWRAP(self);
27 sh_show(sh);
28 29
29 return Null(); 30 blksobj = Array::Cast(*blks);
31 nblks = blksobj->Length();
32 mb_blks = new mb_style_blk_t[nblks];
33 for(i = 0; i < nblks; i++) {
34 blkobj = Array::Cast(*blksobj->Get(i));
35 mb_blks[i].n_chars = blkobj->Get(0)->ToInt32()->Value();
36 mb_blks[i].face = (mb_font_face_t *)UNWRAP(blkobj->Get(1)->ToObject());
37 mb_blks[i].font_sz = blkobj->Get(2)->ToNumber()->Value();
38 }
39
40 r = sh_stext_set_style(sh, mb_blks, nblks);
41 if(r != 0) {
42 *err = "Unknown error";
43 return;
44 }
45
46 delete mb_blks;
30 } 47 }
31 48
32 static Handle<Value> 49 static Handle<Value>
33 xnjsmb_shape_hide(const Arguments &args) { 50 xnjsmb_shape_stroke_width_get(Handle<Object> self, shape_t *sh,
34 shape_t *sh; 51 const char **err) {
35 Handle<Object> self; 52 float stroke_width;
36 53
37 self = args.This(); 54 stroke_width = sh_get_stroke_width(sh);
38 sh = (shape_t *)UNWRAP(self); 55 return Number::New(stroke_width);
39 sh_hide(sh);
40
41 return Null();
42 } 56 }
43 57
44 /*! \brief Get stroke width of a shape. 58 static void
45 */ 59 xnjsmb_shape_stroke_width_set(Handle<Object> self, shape_t *sh,
46 static Handle<Value> 60 Handle<Value> value, const char **err) {
47 xnjsmb_shape_stroke_width_getter(Local<String> property, 61 float stroke_width;
48 const AccessorInfo &info) { 62 Handle<Object> rt;
49 Handle<Object> self = info.This(); 63 redraw_man_t *rdman;
50 shape_t *sh;
51 float w;
52 Handle<Value> w_val;
53 64
54 sh = (shape_t *)UNWRAP(self); 65 stroke_width = value->Int32Value();
55 w = sh_get_stroke_width(sh); 66 sh_set_stroke_width(sh, stroke_width);
56 w_val = Number::New(w);
57 67
58 return w_val;
59 }
60
61 /*! \brief Set stroke width of a shape.
62 */
63 static void
64 xnjsmb_shape_stroke_width_setter(Local<String> property,
65 Local<Value> value,
66 const AccessorInfo &info) {
67 Handle<Object> self = info.This();
68 Handle<Object> rt;
69 shape_t *sh;
70 redraw_man_t *rdman;
71 float w;
72 Handle<Number> w_num;
73
74 sh = (shape_t *)UNWRAP(self);
75 w_num = value->ToNumber();
76 w = w_num->Value();
77
78 sh_set_stroke_width(sh, w);
79
80 /* 68 /*
81 * Mark changed. 69 * Mark changed.
82 */ 70 */
83 rt = GET(self, "mbrt")->ToObject(); 71 rt = GET(self, "mbrt")->ToObject();
84 ASSERT(rt != NULL); 72 ASSERT(rt != NULL);
86 74
87 if(sh_get_coord(sh)) 75 if(sh_get_coord(sh))
88 rdman_shape_changed(rdman, sh); 76 rdman_shape_changed(rdman, sh);
89 } 77 }
90 78
91 static void 79 /* @} */
92 xnjsmb_init_shape_temp(void) {
93 Handle<FunctionTemplate> temp;
94 Handle<ObjectTemplate> proto_temp;
95 Handle<FunctionTemplate> method_temp;
96 80
97 temp = FunctionTemplate::New(); 81 #include "shapes-inc.h"
98 temp->SetClassName(String::New("shape"));
99 xnjsmb_shape_temp = Persistent<FunctionTemplate>::New(temp);
100 proto_temp = temp->PrototypeTemplate();
101
102 method_temp = FunctionTemplate::New(xnjsmb_shape_show);
103 SET(proto_temp, "show", method_temp);
104 method_temp = FunctionTemplate::New(xnjsmb_shape_hide);
105 SET(proto_temp, "hide", method_temp);
106 82
107 proto_temp->SetAccessor(String::New("stroke_width"), 83 /*! \defgroup xnjsmb_shapes_export Export functions of creating objects.
108 xnjsmb_shape_stroke_width_getter, 84 * \ingroup xnjsmb_shapes
109 xnjsmb_shape_stroke_width_setter); 85 *
86 * @{
87 */
88 Handle<Value>
89 export_xnjsmb_auto_path_new(shape_t *sh) {
90 return xnjsmb_auto_path_new(sh);
91 }
92
93 Handle<Value>
94 export_xnjsmb_auto_stext_new(shape_t *sh) {
95 return xnjsmb_auto_stext_new(sh);
96 }
97
98 Handle<Value>
99 export_xnjsmb_auto_image_new(shape_t *sh) {
100 return xnjsmb_auto_image_new(sh);
110 } 101 }
111 102
112 /* @} */ 103 /* @} */
113 104
114 /*! \defgroup path_temp Templates for path objects. 105 /*! \defgroup xnjsmb_shapes_wraps Wrap functions for shape objects.
106 * \ingroup xnjsmb_shapes
107 *
108 * These functions are used by methods of mb_rt to wrap shape objects
109 * as Javascript objects.
115 * 110 *
116 * @{ 111 * @{
117 */ 112 */
118 static Persistent<FunctionTemplate> xnjsmb_path_temp; 113 shape_t *
119 114 xnjsmb_path_new(njs_runtime_t *rt, const char *d) {
120 /*! \brief Callback of constructor of path objects for Javascript. 115 redraw_man_t *rdman;
121 */
122 static Handle<Value>
123 xnjsmb_shape_path(const Arguments &args) {
124 shape_t *sh; 116 shape_t *sh;
125 redraw_man_t *rdman; 117
126 Handle<Object> self = args.This(); // path object 118 rdman = X_njs_MB_rdman(rt);
127 Handle<Object> rt; 119 sh = rdman_shape_path_new(rdman, d);
128 Persistent<Object> *self_hdl; 120
129 char *dstr; 121 return sh;
130 int argc;
131
132 argc = args.Length();
133 if(argc != 2)
134 THROW("Invalid number of arugments (!= 1)");
135 if(!args[0]->IsString())
136 THROW("Invalid argument type (should be a string)");
137 if(!args[1]->IsObject())
138 THROW("Invalid argument type (should be an object)");
139
140 String::Utf8Value dutf8(args[0]->ToString());
141 dstr = *dutf8;
142
143 rt = args[1]->ToObject();
144 rdman = xnjsmb_rt_rdman(rt);
145 sh = rdman_shape_path_new(rdman, dstr);
146
147 WRAP(self, sh);
148 SET(self, "mbrt", rt);
149 /* Keep associated js object in property store for retrieving,
150 * later, without create new js object.
151 */
152 self_hdl = new Persistent<Object>(self);
153 mb_prop_set(&sh->obj.props, PROP_JSOBJ, self_hdl);
154
155 return Null();
156 } 122 }
157 123
158 /*! \brief Initial function template for constructor of path objects. 124 shape_t *
159 */ 125 xnjsmb_stext_new(njs_runtime_t *rt, const char *txt, float x, float y) {
160 static void 126 redraw_man_t *rdman;
161 xnjsmb_init_path_temp(void) { 127 shape_t *sh;
162 Handle<FunctionTemplate> temp;
163 Handle<ObjectTemplate> inst_temp;
164 128
165 temp = FunctionTemplate::New(xnjsmb_shape_path); 129 rdman = X_njs_MB_rdman(rt);
166 temp->Inherit(xnjsmb_shape_temp); 130 sh = rdman_shape_stext_new(rdman, txt, x, y);
167 temp->SetClassName(String::New("path"));
168 131
169 inst_temp = temp->InstanceTemplate(); 132 return sh;
170 inst_temp->SetInternalFieldCount(1);
171
172 xnjsmb_path_temp = Persistent<FunctionTemplate>::New(temp);
173 } 133 }
174 134
175 /*! \brief Callback function of mb_rt.path_new(). 135 shape_t *
176 */ 136 xnjsmb_image_new(njs_runtime_t *rt, float x, float y, float w, float h) {
177 static Handle<Value> 137 redraw_man_t *rdman;
178 xnjsmb_shape_path_new(const Arguments &args) { 138 shape_t *sh;
179 HandleScope scope;
180 Handle<Object> self = args.This(); // runtime object
181 Handle<Object> path_obj;
182 Handle<Value> path_args[2];
183 int argc;
184 139
185 argc = args.Length(); 140 rdman = X_njs_MB_rdman(rt);
186 if(argc != 1) 141 sh = rdman_shape_image_new(rdman, x, y, w, h);
187 THROW("Invalid number of arugments (!= 1)");
188 if(!args[0]->IsString())
189 THROW("Invalid argument type (shoud be a string)");
190 142
191 path_args[0] = args[0]; 143 return sh;
192 path_args[1] = self;
193
194 path_obj = xnjsmb_path_temp->GetFunction()->NewInstance(2, path_args);
195
196 scope.Close(path_obj);
197 return path_obj;
198 }
199
200 /* @} */
201
202 /*! \defgroup stext_path Template for stext objects.
203 *
204 * @{
205 */
206
207 /*! \brief Constructor for stext objects.
208 *
209 * 4 arguments
210 * \param rt is a runtime object.
211 * \param data is a text to be showed.
212 * \param x is postion in x-axis.
213 * \param y is position in y-axis.
214 */
215 static Handle<Value>
216 xnjsmb_shape_stext(const Arguments &args) {
217 int argc = args.Length();
218 Handle<Object> self = args.This();
219 Handle<Object> rt;
220 Persistent<Object> *self_hdl;
221 float x, y;
222 char *data;
223 redraw_man_t *rdman;
224 shape_t *stext;
225
226 if(argc != 4)
227 THROW("Invalid number of arguments (!= 4)");
228 if(!args[0]->IsObject() || !args[1]->IsString() ||
229 !args[2]->IsNumber() || !args[3]->IsNumber())
230 THROW("Invalid argument type");
231
232 rt = args[0]->ToObject();
233 String::Utf8Value data_utf8(args[1]);
234 data = *data_utf8;
235 x = args[2]->ToNumber()->Value();
236 y = args[3]->ToNumber()->Value();
237
238 rdman = xnjsmb_rt_rdman(rt);
239 ASSERT(rdman != NULL);
240
241 stext = rdman_shape_stext_new(rdman, data, x, y);
242
243 WRAP(self, stext);
244 SET(self, "mbrt", rt);
245 /* Keep associated js object in property store for retrieving,
246 * later, without create new js object.
247 */
248 self_hdl = new Persistent<Object>(self);
249 mb_prop_set(&stext->obj.props, PROP_JSOBJ, self_hdl);
250
251 return Null();
252 }
253
254 static Persistent<FunctionTemplate> xnjsmb_shape_stext_temp;
255
256 /*! \brief Create a stext and return it.
257 */
258 static Handle<Value>
259 xnjsmb_shape_stext_new(const Arguments &args) {
260 HandleScope scope;
261 int argc = args.Length();
262 Handle<Object> self = args.This();
263 Handle<Value> stext_args[4];
264 Handle<Object> stext_obj;
265 Handle<Function> func;
266
267 if(argc != 3)
268 THROW("Invalid number of arguments (!= 3)");
269
270 stext_args[0] = self;
271 stext_args[1] = args[0];
272 stext_args[2] = args[1];
273 stext_args[3] = args[2];
274
275 func = xnjsmb_shape_stext_temp->GetFunction();
276 stext_obj = func->NewInstance(4, stext_args);
277 ASSERT(stext_obj != NULL);
278
279 scope.Close(stext_obj);
280 return stext_obj;
281 }
282
283 /*! \brief Setup style blocks for a stext.
284 *
285 * It defines font style and size for blocks of text message.
286 *
287 * \param blks is a list (n_char, face, font size) tuples.
288 */
289 static Handle<Value>
290 xnjsmb_shape_stext_set_style(const Arguments &args) {
291 HandleScope scope;
292 int argc = args.Length();
293 Handle<Object> self = args.This();
294 shape_t *sh;
295 Array *blksobj;
296 Array *blkobj;
297 mb_style_blk_t *blks;
298 int nblks;
299 int i;
300 int r;
301
302 if(argc != 1)
303 THROW("Invalid number of arguments (!= 1)");
304 if(!args[0]->IsArray())
305 THROW("Invalid type of the argument");
306
307 blksobj = Array::Cast(*args[0]);
308 nblks = blksobj->Length();
309 blks = new mb_style_blk_t[nblks];
310 for(i = 0; i < nblks; i++) {
311 blkobj = Array::Cast(*blksobj->Get(i));
312 blks[i].n_chars = blkobj->Get(0)->ToInt32()->Value();
313 blks[i].face = (mb_font_face_t *)UNWRAP(blkobj->Get(1)->ToObject());
314 blks[i].font_sz = blkobj->Get(2)->ToNumber()->Value();
315 }
316
317 sh = (shape_t *)UNWRAP(self);
318 r = sh_stext_set_style(sh, blks, nblks);
319 if(r != 0)
320 THROW("Unknown error");
321
322 delete blks;
323
324 return Null();
325 }
326
327 /*! \brief Initialize function template for stext objects.
328 */
329 static void
330 xnjsmb_init_stext_temp(void) {
331 Handle<FunctionTemplate> func_temp;
332 Handle<FunctionTemplate> meth_temp;
333 Handle<ObjectTemplate> inst_temp;
334 Handle<ObjectTemplate> proto_temp;
335
336 func_temp = FunctionTemplate::New(xnjsmb_shape_stext);
337 func_temp->Inherit(xnjsmb_shape_temp);
338 func_temp->SetClassName(String::New("stext"));
339
340 inst_temp = func_temp->InstanceTemplate();
341 inst_temp->SetInternalFieldCount(1);
342
343 proto_temp = func_temp->PrototypeTemplate();
344 meth_temp = FunctionTemplate::New(xnjsmb_shape_stext_set_style);
345 SET(proto_temp, "set_style", meth_temp);
346
347 xnjsmb_shape_stext_temp = Persistent<FunctionTemplate>::New(func_temp);
348 }
349
350 /* @} */
351
352 /*! \defgroup image_temp Templates for image objects.
353 *
354 * @{
355 */
356
357 static Handle<Value>
358 xnjsmb_shape_image(const Arguments &args) {
359 int argc = args.Length();
360 Handle<Object> self = args.This();
361 Handle<Object> rt;
362 Persistent<Object> *self_hdl;
363 float x, y;
364 float w, h;
365 redraw_man_t *rdman;
366 shape_t *img;
367
368 if(argc != 5)
369 THROW("Invalid number of arguments (!= 5)");
370 if(!args[0]->IsObject() ||
371 !args[1]->IsNumber() || !args[2]->IsNumber() ||
372 !args[3]->IsNumber() || !args[4]->IsNumber())
373 THROW("Invalid argument type");
374
375 rt = args[0]->ToObject();
376 x = args[1]->ToNumber()->Value();
377 y = args[2]->ToNumber()->Value();
378 w = args[3]->ToNumber()->Value();
379 h = args[4]->ToNumber()->Value();
380
381 rdman = xnjsmb_rt_rdman(rt);
382 img = rdman_shape_image_new(rdman, x, y, w, h);
383
384 WRAP(self, img);
385 SET(self, "mbrt", rt);
386 /* Keep associated js object in property store for retrieving,
387 * later, without create new js object.
388 */
389 self_hdl = new Persistent<Object>(self);
390 mb_prop_set(&img->obj.props, PROP_JSOBJ, self_hdl);
391
392 return Null();
393 }
394
395 static Persistent<FunctionTemplate> xnjsmb_shape_image_temp;
396
397 static Handle<Value>
398 xnjsmb_shape_image_new(const Arguments &args) {
399 HandleScope scope;
400 int argc = args.Length();
401 Handle<Object> self = args.This();
402 Handle<Value> img_args[5];
403 Handle<Object> img_obj;
404 Handle<Function> func;
405
406 if(argc != 4)
407 THROW("Invalid number of arguments (!= 3)");
408
409 img_args[0] = self;
410 img_args[1] = args[0];
411 img_args[2] = args[1];
412 img_args[3] = args[2];
413 img_args[4] = args[3];
414
415 func = xnjsmb_shape_image_temp->GetFunction();
416 img_obj = func->NewInstance(5, img_args);
417 ASSERT(img_obj != NULL);
418
419 scope.Close(img_obj);
420 return img_obj;
421 }
422
423 static void
424 xnjsmb_init_image_temp() {
425 Handle<FunctionTemplate> func_temp;
426 Handle<FunctionTemplate> meth_temp;
427 Handle<ObjectTemplate> inst_temp;
428 Handle<ObjectTemplate> proto_temp;
429
430 func_temp = FunctionTemplate::New(xnjsmb_shape_image);
431 func_temp->Inherit(xnjsmb_shape_temp);
432 func_temp->SetClassName(String::New("image"));
433
434 inst_temp = func_temp->InstanceTemplate();
435 inst_temp->SetInternalFieldCount(1);
436
437 xnjsmb_shape_image_temp = Persistent<FunctionTemplate>::New(func_temp);
438 } 144 }
439 145
440 /* @} */ 146 /* @} */
441 147
442 /*! \brief Set properties of template of mb_rt. 148 /*! \brief Set properties of template of mb_rt.
149 * \ingroup xnjsmb_shapes
443 */ 150 */
444 void 151 void
445 xnjsmb_shapes_init_mb_rt_temp(Handle<FunctionTemplate> rt_temp) { 152 xnjsmb_shapes_init_mb_rt_temp(Handle<FunctionTemplate> rt_temp) {
446 HandleScope scope; 153 HandleScope scope;
447 Handle<FunctionTemplate> path_new_temp, stext_new_temp; 154 Handle<FunctionTemplate> path_new_temp, stext_new_temp;
448 Handle<FunctionTemplate> image_new_temp; 155 Handle<FunctionTemplate> image_new_temp;
449 Handle<ObjectTemplate> rt_proto_temp; 156 Handle<ObjectTemplate> rt_proto_temp;
450 static int temp_init_flag = 0; 157 static int temp_init_flag = 0;
451 158
452 if(temp_init_flag == 0) { 159 if(temp_init_flag == 0) {
453 xnjsmb_init_shape_temp(); 160 xnjsmb_auto_shape_init();
454 xnjsmb_init_path_temp(); 161 xnjsmb_auto_path_init();
455 xnjsmb_init_stext_temp(); 162 xnjsmb_auto_stext_init();
456 xnjsmb_init_image_temp(); 163 xnjsmb_auto_image_init();
457 temp_init_flag = 1; 164 temp_init_flag = 1;
458 } 165 }
459 166 return;
460 rt_proto_temp = rt_temp->PrototypeTemplate();
461
462 path_new_temp = FunctionTemplate::New(xnjsmb_shape_path_new);
463 SET(rt_proto_temp, "path_new", path_new_temp);
464
465 stext_new_temp = FunctionTemplate::New(xnjsmb_shape_stext_new);
466 SET(rt_proto_temp, "stext_new", stext_new_temp);
467
468 image_new_temp = FunctionTemplate::New(xnjsmb_shape_image_new);
469 SET(rt_proto_temp, "image_new", image_new_temp);
470 } 167 }