qml 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +57 -4
  3. data/changes.md +8 -0
  4. data/examples/fizzbuzz/fizzbuzz.rb +1 -1
  5. data/examples/imageprovider/imageprovider.rb +1 -1
  6. data/examples/todo_array/todo_array.rb +1 -1
  7. data/examples/todo_sequel/todo_sequel.rb +1 -1
  8. data/examples/twitter/twitter.rb +1 -1
  9. data/ext/qml/accessclass.cpp +5 -9
  10. data/ext/qml/conversionerror.h +14 -0
  11. data/ext/qml/ext_metaobject.cpp +30 -41
  12. data/ext/qml/init.cpp +5 -7
  13. data/ext/qml/rubyclass.cpp +6 -18
  14. data/ext/qml/rubyclass.h +22 -26
  15. data/ext/qml/rubyvalue.cpp +155 -221
  16. data/ext/qml/rubyvalue.h +30 -63
  17. data/ext/qml/signalforwarder.cpp +1 -3
  18. data/ext/qml/util.cpp +2 -25
  19. data/ext/qml/util.h +1 -21
  20. data/ext/qml/weakvaluereference.cpp +4 -5
  21. data/lib/qml/access.rb +9 -17
  22. data/lib/qml/application.rb +18 -21
  23. data/lib/qml/context.rb +1 -1
  24. data/lib/qml/dispatcher.rb +0 -1
  25. data/lib/qml/error_converter.rb +1 -0
  26. data/lib/qml/meta_object.rb +3 -3
  27. data/lib/qml/qt_object_base.rb +130 -5
  28. data/lib/qml/reactive/object.rb +34 -25
  29. data/lib/qml/reactive/signal.rb +6 -10
  30. data/lib/qml/reactive/unbound_property.rb +1 -1
  31. data/lib/qml/reactive/unbound_signal.rb +2 -2
  32. data/lib/qml/version.rb +1 -1
  33. data/spec/qml/reactive/object_spec.rb +14 -38
  34. data/spec/qml/reactive/signal_spec.rb +1 -1
  35. data/spec/qml/reactive/unbound_property_spec.rb +40 -0
  36. data/spec/qml/reactive/unbound_signal_spec.rb +70 -0
  37. data/spec/{shared_examples → shared}/qml/data/list_model.rb +0 -0
  38. data/spec/shared/qml/reactive/object.rb +39 -0
  39. data/spec/spec_helper.rb +1 -1
  40. metadata +12 -6
  41. data/lib/qml/class_builder.rb +0 -129
@@ -1,4 +1,5 @@
1
1
  #include "rubyvalue.h"
2
+ #include "conversionerror.h"
2
3
  #include "util.h"
3
4
  #include "ext_pointer.h"
4
5
  #include "ext_metaobject.h"
@@ -22,12 +23,10 @@ namespace {
22
23
 
23
24
  RubyValue convertToString(RubyValue x)
24
25
  {
25
- return protect([&] {
26
- if (rb_type(x) == T_SYMBOL) {
27
- x = rb_sym_to_s(x);
28
- }
29
- return rb_convert_type(x, T_STRING, "String", "to_str");
30
- });
26
+ if (rb_type(x) == T_SYMBOL) {
27
+ x = rb_sym_to_s(x);
28
+ }
29
+ return rb_convert_type(x, T_STRING, "String", "to_str");
31
30
  }
32
31
 
33
32
  struct ConverterHash
@@ -116,9 +115,7 @@ Q_GLOBAL_STATIC(ConverterHash, converterHash)
116
115
 
117
116
  RubyValue Conversion<const char *>::to(const char *str)
118
117
  {
119
- return protect([&] {
120
- return rb_enc_str_new(str, strlen(str), rb_utf8_encoding());
121
- });
118
+ return rb_enc_str_new(str, strlen(str), rb_utf8_encoding());
122
119
  }
123
120
 
124
121
  template <> QByteArray Conversion<QByteArray>::from(RubyValue x)
@@ -145,172 +142,128 @@ template <> RubyValue Conversion<QString>::to(const QString &str)
145
142
 
146
143
  template <> QDateTime Conversion<QDateTime>::from(RubyValue time)
147
144
  {
148
- timeval at;
149
145
  int offset;
150
- protect([&] {
151
- if (rb_obj_is_kind_of(time, rb_cTime)) {
152
- offset = NUM2INT(rb_funcall(time, RUBYQML_INTERN("gmt_offset"), 0));
153
- } else { // DateTime
154
- auto dayOffset = rb_funcall(time, RUBYQML_INTERN("offset"), 0);
155
- offset = NUM2INT(RRATIONAL(dayOffset)->num) * 24 * 60 * 60 / NUM2INT(RRATIONAL(dayOffset)->den);
156
- time = rb_funcall(time, RUBYQML_INTERN("to_time"), 0);
157
- }
158
- at = rb_time_timeval(time);
159
- });
146
+
147
+ if (time.isKindOf(rb_cTime)) {
148
+ offset = time.send(RUBYQML_INTERN("gmt_offset")).to<int>();
149
+ } else { // DateTime
150
+ VALUE dayOffset = time.send(RUBYQML_INTERN("offset"));
151
+ offset = RubyValue(RRATIONAL(dayOffset)->num).to<int>() * 24 * 60 * 60 / RubyValue(RRATIONAL(dayOffset)->den).to<int>();
152
+ time = time.send(RUBYQML_INTERN("to_time"));
153
+ }
154
+ timeval at = rb_time_timeval(time);
155
+
160
156
  QDateTime dateTime;
161
157
  dateTime.setOffsetFromUtc(offset);
162
158
  dateTime.setMSecsSinceEpoch(at.tv_sec * 1000 + at.tv_usec / 1000);
163
159
  return dateTime;
164
160
  }
165
161
 
166
- template <> RubyValue Conversion<QDateTime>::to(const QDateTime &dateTime) {
167
- RubyValue ret;
168
- protect([&] {
169
- auto sec = rb_rational_new(LL2NUM(dateTime.toMSecsSinceEpoch()), INT2NUM(1000));
170
- auto time = rb_time_num_new(sec, INT2NUM(dateTime.offsetFromUtc()));
171
- ret = rb_funcall(time, RUBYQML_INTERN("to_datetime"), 0);
172
- });
173
- return ret;
162
+ template <> RubyValue Conversion<QDateTime>::to(const QDateTime &dateTime)
163
+ {
164
+ RubyValue sec = rb_rational_new(RubyValue::from(dateTime.toMSecsSinceEpoch()), RubyValue::from(1000));
165
+ RubyValue time = rb_time_num_new(sec, RubyValue::from(dateTime.offsetFromUtc()));
166
+ return time.send(RUBYQML_INTERN("to_datetime"));
174
167
  }
175
168
 
176
169
  template <> QDate Conversion<QDate>::from(RubyValue x)
177
170
  {
178
- int y, m, d;
179
- protect([&] {
180
- y = NUM2INT(rb_funcall(x, RUBYQML_INTERN("year"), 0));
181
- m = NUM2INT(rb_funcall(x, RUBYQML_INTERN("month"), 0));
182
- d = NUM2INT(rb_funcall(x, RUBYQML_INTERN("day"), 0));
183
- });
171
+ int y = x.send(RUBYQML_INTERN("year")).to<int>();
172
+ int m = x.send(RUBYQML_INTERN("month")).to<int>();
173
+ int d = x.send(RUBYQML_INTERN("day")).to<int>();
184
174
  return QDate(y, m, d);
185
175
  }
186
176
 
187
177
  template <> RubyValue Conversion<QDate>::to(const QDate &date)
188
178
  {
189
179
  static auto klass = RubyClass::fromPath("Date");
190
- return protect([&] {
191
- return rb_funcall(klass, RUBYQML_INTERN("new"), 3,
192
- INT2NUM(date.year()), INT2NUM(date.month()), INT2NUM(date.day()));
193
- });
180
+ return klass.toValue().send(RUBYQML_INTERN("new"), RubyValue::from(date.year()), RubyValue::from(date.month()), RubyValue::from(date.day()));
194
181
  }
195
182
 
196
183
  template <> QPoint Conversion<QPoint>::from(RubyValue value)
197
184
  {
198
- int x, y;
199
- protect([&] {
200
- x = NUM2INT(rb_funcall(value, RUBYQML_INTERN("x"), 0));
201
- y = NUM2INT(rb_funcall(value, RUBYQML_INTERN("y"), 0));
202
- });
185
+ auto x = value.send(RUBYQML_INTERN("x")).to<int>();
186
+ auto y = value.send(RUBYQML_INTERN("y")).to<int>();
203
187
  return QPoint(x, y);
204
188
  }
205
189
 
206
190
  template <> RubyValue Conversion<QPoint>::to(const QPoint &point)
207
191
  {
208
192
  static auto klass = RubyClass::fromPath("QML::Geometry::Point");
209
- return protect([&] {
210
- return rb_funcall(klass, RUBYQML_INTERN("new"), 2,
211
- INT2NUM(point.x()), INT2NUM(point.y()));
212
- });
193
+ return klass.toValue().send(RUBYQML_INTERN("new"), RubyValue::from(point.x()), RubyValue::from(point.y()));
213
194
  }
214
195
 
215
196
  template <> QPointF Conversion<QPointF>::from(RubyValue value)
216
197
  {
217
- double x, y;
218
- protect([&] {
219
- x = rb_num2dbl(rb_funcall(value, RUBYQML_INTERN("x"), 0));
220
- y = rb_num2dbl(rb_funcall(value, RUBYQML_INTERN("y"), 0));
221
- });
198
+ auto x = value.send(RUBYQML_INTERN("x")).to<double>();
199
+ auto y = value.send(RUBYQML_INTERN("y")).to<double>();
222
200
  return QPointF(x, y);
223
201
  }
224
202
 
225
203
  template <> RubyValue Conversion<QPointF>::to(const QPointF &point)
226
204
  {
227
205
  static auto klass = RubyClass::fromPath("QML::Geometry::Point");
228
- return protect([&] {
229
- return rb_funcall(klass, RUBYQML_INTERN("new"), 2,
230
- rb_float_new(point.x()), rb_float_new(point.y()));
231
- });
206
+ return klass.toValue().send(RUBYQML_INTERN("new"), RubyValue::from(point.x()), RubyValue::from(point.y()));
232
207
  }
233
208
 
234
209
  template <> QSize Conversion<QSize>::from(RubyValue value)
235
210
  {
236
- int w, h;
237
- protect([&] {
238
- w = NUM2INT(rb_funcall(value, RUBYQML_INTERN("width"), 0));
239
- h = NUM2INT(rb_funcall(value, RUBYQML_INTERN("height"), 0));
240
- });
241
- return QSize(w, h);
211
+ auto width = value.send(RUBYQML_INTERN("width")).to<int>();
212
+ auto height= value.send(RUBYQML_INTERN("height")).to<int>();
213
+ return QSize(width, height);
242
214
  }
243
215
 
244
216
  template <> RubyValue Conversion<QSize>::to(const QSize &size)
245
217
  {
246
218
  static auto klass = RubyClass::fromPath("QML::Geometry::Size");
247
- return protect([&] {
248
- return rb_funcall(klass, RUBYQML_INTERN("new"), 2,
249
- INT2NUM(size.width()), INT2NUM(size.height()));
250
- });
219
+ return klass.toValue().send(RUBYQML_INTERN("new"), RubyValue::from(size.width()), RubyValue::from(size.height()));
251
220
  }
252
221
 
253
222
  template <> QSizeF Conversion<QSizeF>::from(RubyValue value)
254
223
  {
255
- double w, h;
256
- protect([&] {
257
- w = rb_num2dbl(rb_funcall(value, RUBYQML_INTERN("width"), 0));
258
- h = rb_num2dbl(rb_funcall(value, RUBYQML_INTERN("height"), 0));
259
- });
260
- return QSizeF(w, h);
224
+ auto width = value.send(RUBYQML_INTERN("width")).to<double>();
225
+ auto height = value.send(RUBYQML_INTERN("height")).to<double>();
226
+ return QSizeF(width, height);
261
227
  }
262
228
 
263
229
  template <> RubyValue Conversion<QSizeF>::to(const QSizeF &size)
264
230
  {
265
231
  static auto klass = RubyClass::fromPath("QML::Geometry::Size");
266
- return protect([&] {
267
- return rb_funcall(klass, RUBYQML_INTERN("new"), 2,
268
- rb_float_new(size.width()), rb_float_new(size.height()));
269
- });
232
+ return klass.toValue().send(RUBYQML_INTERN("new"), RubyValue::from(size.width()), RubyValue::from(size.height()));
270
233
  }
271
234
 
272
235
  template <> QRect Conversion<QRect>::from(RubyValue value)
273
236
  {
274
- int x, y, w, h;
275
- protect([&] {
276
- x = NUM2INT(rb_funcall(value, RUBYQML_INTERN("x"), 0));
277
- y = NUM2INT(rb_funcall(value, RUBYQML_INTERN("y"), 0));
278
- w = NUM2INT(rb_funcall(value, RUBYQML_INTERN("width"), 0));
279
- h = NUM2INT(rb_funcall(value, RUBYQML_INTERN("height"), 0));
280
- });
237
+ auto x = value.send(RUBYQML_INTERN("x")).to<int>();
238
+ auto y = value.send(RUBYQML_INTERN("y")).to<int>();
239
+ auto w = value.send(RUBYQML_INTERN("width")).to<int>();
240
+ auto h = value.send(RUBYQML_INTERN("height")).to<int>();
281
241
  return QRect(QPoint(x, y), QSize(w, h));
282
242
  }
283
243
 
284
244
  template <> RubyValue Conversion<QRect>::to(const QRect &rect)
285
245
  {
286
246
  static auto klass = RubyClass::fromPath("QML::Geometry::Rectangle");
287
- return protect([&] {
288
- return rb_funcall(klass, RUBYQML_INTERN("new"), 4,
289
- INT2NUM(rect.x()), INT2NUM(rect.y()),
290
- INT2NUM(rect.width()), INT2NUM(rect.height()));
291
- });
247
+ return klass.toValue().send(RUBYQML_INTERN("new"),
248
+ RubyValue::from(rect.x()), RubyValue::from(rect.y()),
249
+ RubyValue::from(rect.width()), RubyValue::from(rect.height()));
292
250
  }
293
251
 
294
252
  template <> QRectF Conversion<QRectF>::from(RubyValue value)
295
253
  {
296
- double x, y, w, h;
297
- protect([&] {
298
- x = rb_num2dbl(rb_funcall(value, RUBYQML_INTERN("x"), 0));
299
- y = rb_num2dbl(rb_funcall(value, RUBYQML_INTERN("y"), 0));
300
- w = rb_num2dbl(rb_funcall(value, RUBYQML_INTERN("width"), 0));
301
- h = rb_num2dbl(rb_funcall(value, RUBYQML_INTERN("height"), 0));
302
- });
303
- return QRectF(QPoint(x, y), QSize(w, h));
254
+ auto x = value.send(RUBYQML_INTERN("x")).to<double>();
255
+ auto y = value.send(RUBYQML_INTERN("y")).to<double>();
256
+ auto w = value.send(RUBYQML_INTERN("width")).to<double>();
257
+ auto h = value.send(RUBYQML_INTERN("height")).to<double>();
258
+ return QRectF(QPointF(x, y), QSizeF(w, h));
304
259
  }
305
260
 
306
261
  template <> RubyValue Conversion<QRectF>::to(const QRectF &rect)
307
262
  {
308
263
  static auto klass = RubyClass::fromPath("QML::Geometry::Rectangle");
309
- return protect([&] {
310
- return rb_funcall(klass, RUBYQML_INTERN("new"), 4,
311
- rb_float_new(rect.x()), rb_float_new(rect.y()),
312
- rb_float_new(rect.width()), rb_float_new(rect.height()));
313
- });
264
+ return klass.toValue().send(RUBYQML_INTERN("new"),
265
+ RubyValue::from(rect.x()), RubyValue::from(rect.y()),
266
+ RubyValue::from(rect.width()), RubyValue::from(rect.height()));
314
267
  }
315
268
 
316
269
  template <> QVariant Conversion<QVariant>::from(RubyValue x)
@@ -343,13 +296,6 @@ template <> RubyValue Conversion<const QMetaObject *>::to(const QMetaObject *met
343
296
 
344
297
  Q_GLOBAL_STATIC(QSet<int>, enumeratorMetaTypes)
345
298
 
346
- bool RubyValue::isKindOf(const RubyModule &module) const
347
- {
348
- return protect([&] {
349
- return rb_obj_is_kind_of(mValue, module);
350
- });
351
- }
352
-
353
299
  bool RubyValue::isConvertibleTo(int metaType) const
354
300
  {
355
301
  auto x = *this;
@@ -424,58 +370,56 @@ bool RubyValue::isConvertibleTo(int metaType) const
424
370
  break;
425
371
  }
426
372
 
427
- return protect([&] {
428
- if (rb_obj_is_kind_of(x, rb_cTime)) {
429
- return metaType == QMetaType::QDateTime;
430
- }
431
- static auto dateTimeClass = RubyClass::fromPath("DateTime");
432
- if (rb_obj_is_kind_of(x, dateTimeClass)) {
433
- return metaType == QMetaType::QDateTime;
434
- }
435
- static auto dateClass = RubyClass::fromPath("Date");
436
- if (rb_obj_is_kind_of(x, dateClass)) {
437
- return metaType == QMetaType::QDate || metaType == QMetaType::QDateTime;
373
+ if (rb_obj_is_kind_of(x, rb_cTime)) {
374
+ return metaType == QMetaType::QDateTime;
375
+ }
376
+ static auto dateTimeClass = RubyClass::fromPath("DateTime");
377
+ if (rb_obj_is_kind_of(x, dateTimeClass)) {
378
+ return metaType == QMetaType::QDateTime;
379
+ }
380
+ static auto dateClass = RubyClass::fromPath("Date");
381
+ if (rb_obj_is_kind_of(x, dateClass)) {
382
+ return metaType == QMetaType::QDate || metaType == QMetaType::QDateTime;
383
+ }
384
+ static auto objectBaseClass = RubyClass::fromPath("QML::QtObjectBase");
385
+ if (rb_obj_is_kind_of(x, objectBaseClass)) {
386
+ if (metaType == QMetaType::QObjectStar) {
387
+ return true;
438
388
  }
439
- static auto objectBaseClass = RubyClass::fromPath("QML::QtObjectBase");
440
- if (rb_obj_is_kind_of(x, objectBaseClass)) {
441
- if (metaType == QMetaType::QObjectStar) {
389
+ if (QMetaType::metaObjectForType(metaType)) {
390
+ auto metaObj = QMetaType::metaObjectForType(metaType);
391
+ if (x.to<QObject *>()->inherits(metaObj->className())) {
442
392
  return true;
443
393
  }
444
- if (QMetaType::metaObjectForType(metaType)) {
445
- auto metaObj = QMetaType::metaObjectForType(metaType);
446
- if (x.to<QObject *>()->inherits(metaObj->className())) {
447
- return true;
448
- }
449
- }
450
- return false;
451
- }
452
- if (rb_obj_is_kind_of(x, wrapperRubyClass<Ext_MetaObject>())) {
453
- return metaType == QMetaType::type("const QMetaObject*");
454
- }
455
- auto accessModule = RubyModule::fromPath("QML::Access");
456
- if (rb_obj_is_kind_of(x, accessModule)) {
457
- return metaType == QMetaType::QObjectStar;
458
394
  }
395
+ return false;
396
+ }
397
+ if (rb_obj_is_kind_of(x, wrapperRubyClass<Ext_MetaObject>())) {
398
+ return metaType == QMetaType::type("const QMetaObject*");
399
+ }
400
+ auto accessModule = RubyModule::fromPath("QML::Access");
401
+ if (rb_obj_is_kind_of(x, accessModule)) {
402
+ return metaType == QMetaType::QObjectStar;
403
+ }
459
404
 
460
- static auto pointClass = RubyModule::fromPath("QML::Geometry::Point");
461
- if (rb_obj_is_kind_of(x, pointClass)) {
462
- return metaType == QMetaType::QPoint || metaType == QMetaType::QPointF;
463
- }
464
- static auto sizeClass = RubyModule::fromPath("QML::Geometry::Size");
465
- if (rb_obj_is_kind_of(x, sizeClass)) {
466
- return metaType == QMetaType::QSize || metaType == QMetaType::QSizeF;
467
- }
468
- static auto rectClass = RubyModule::fromPath("QML::Geometry::Rectangle");
469
- if (rb_obj_is_kind_of(x, rectClass)) {
470
- return metaType == QMetaType::QRect || metaType == QMetaType::QRectF;
471
- }
472
- static auto listModelClass = RubyModule::fromPath("QML::Data::ListModel");
405
+ static auto pointClass = RubyModule::fromPath("QML::Geometry::Point");
406
+ if (rb_obj_is_kind_of(x, pointClass)) {
407
+ return metaType == QMetaType::QPoint || metaType == QMetaType::QPointF;
408
+ }
409
+ static auto sizeClass = RubyModule::fromPath("QML::Geometry::Size");
410
+ if (rb_obj_is_kind_of(x, sizeClass)) {
411
+ return metaType == QMetaType::QSize || metaType == QMetaType::QSizeF;
412
+ }
413
+ static auto rectClass = RubyModule::fromPath("QML::Geometry::Rectangle");
414
+ if (rb_obj_is_kind_of(x, rectClass)) {
415
+ return metaType == QMetaType::QRect || metaType == QMetaType::QRectF;
416
+ }
417
+ static auto listModelClass = RubyModule::fromPath("QML::Data::ListModel");
473
418
 
474
- if (rb_obj_is_kind_of(x, listModelClass)) {
475
- return metaType == QMetaType::QObjectStar;
476
- }
477
- return false;
478
- });
419
+ if (rb_obj_is_kind_of(x, listModelClass)) {
420
+ return metaType == QMetaType::QObjectStar;
421
+ }
422
+ return false;
479
423
  }
480
424
 
481
425
  int RubyValue::defaultMetaType() const
@@ -507,50 +451,48 @@ int RubyValue::defaultMetaType() const
507
451
  default:
508
452
  break;
509
453
  }
510
- return protect([&]() -> int {
511
- if (rb_obj_is_kind_of(x, rb_cTime)) {
512
- return QMetaType::QDateTime;
513
- }
514
- static auto dateTimeClass = RubyModule::fromPath("DateTime");
515
- if (rb_obj_is_kind_of(x, dateTimeClass)) {
516
- return QMetaType::QDateTime;
517
- }
518
- static auto dateClass = RubyModule::fromPath("Date");
519
- if (rb_obj_is_kind_of(x, dateClass)) {
520
- return QMetaType::QDate;
521
- }
454
+ if (rb_obj_is_kind_of(x, rb_cTime)) {
455
+ return QMetaType::QDateTime;
456
+ }
457
+ static auto dateTimeClass = RubyModule::fromPath("DateTime");
458
+ if (rb_obj_is_kind_of(x, dateTimeClass)) {
459
+ return QMetaType::QDateTime;
460
+ }
461
+ static auto dateClass = RubyModule::fromPath("Date");
462
+ if (rb_obj_is_kind_of(x, dateClass)) {
463
+ return QMetaType::QDate;
464
+ }
522
465
 
523
- static auto objectBaseClass = RubyClass::fromPath("QML::QtObjectBase");
524
- if (rb_obj_is_kind_of(x, objectBaseClass)) {
525
- return QMetaType::QObjectStar;
526
- }
527
- if (rb_obj_is_kind_of(x, wrapperRubyClass<Ext_MetaObject>())) {
528
- return QMetaType::type("const QMetaObject*");
529
- }
530
- auto accessModule = RubyModule::fromPath("QML::Access");
531
- if (rb_obj_is_kind_of(x, accessModule)) {
532
- return QMetaType::QObjectStar;
533
- }
466
+ static auto objectBaseClass = RubyClass::fromPath("QML::QtObjectBase");
467
+ if (rb_obj_is_kind_of(x, objectBaseClass)) {
468
+ return QMetaType::QObjectStar;
469
+ }
470
+ if (rb_obj_is_kind_of(x, wrapperRubyClass<Ext_MetaObject>())) {
471
+ return QMetaType::type("const QMetaObject*");
472
+ }
473
+ auto accessModule = RubyModule::fromPath("QML::Access");
474
+ if (rb_obj_is_kind_of(x, accessModule)) {
475
+ return QMetaType::QObjectStar;
476
+ }
534
477
 
535
- static auto pointClass = RubyModule::fromPath("QML::Geometry::Point");
536
- if (rb_obj_is_kind_of(x, pointClass)) {
537
- return QMetaType::QPointF;
538
- }
539
- static auto sizeClass = RubyModule::fromPath("QML::Geometry::Size");
540
- if (rb_obj_is_kind_of(x, sizeClass)) {
541
- return QMetaType::QSizeF;
542
- }
543
- static auto rectClass = RubyModule::fromPath("QML::Geometry::Rectangle");
544
- if (rb_obj_is_kind_of(x, rectClass)) {
545
- return QMetaType::QRectF;
546
- }
478
+ static auto pointClass = RubyModule::fromPath("QML::Geometry::Point");
479
+ if (rb_obj_is_kind_of(x, pointClass)) {
480
+ return QMetaType::QPointF;
481
+ }
482
+ static auto sizeClass = RubyModule::fromPath("QML::Geometry::Size");
483
+ if (rb_obj_is_kind_of(x, sizeClass)) {
484
+ return QMetaType::QSizeF;
485
+ }
486
+ static auto rectClass = RubyModule::fromPath("QML::Geometry::Rectangle");
487
+ if (rb_obj_is_kind_of(x, rectClass)) {
488
+ return QMetaType::QRectF;
489
+ }
547
490
 
548
- static auto listModelClass = RubyModule::fromPath("QML::Data::ListModel");
549
- if (rb_obj_is_kind_of(x, listModelClass)) {
550
- return QMetaType::QObjectStar;
551
- }
552
- return QMetaType::UnknownType;
553
- });
491
+ static auto listModelClass = RubyModule::fromPath("QML::Data::ListModel");
492
+ if (rb_obj_is_kind_of(x, listModelClass)) {
493
+ return QMetaType::QObjectStar;
494
+ }
495
+ return QMetaType::UnknownType;
554
496
  }
555
497
 
556
498
  RubyValue RubyValue::fromVariant(const QVariant &variant)
@@ -565,9 +507,8 @@ RubyValue RubyValue::fromVariant(const QVariant &variant)
565
507
  return from(intValue);
566
508
  }
567
509
  if (!hash.contains(type)) {
568
- fail("QML::ConversionError",
569
- QString("failed to convert QVariant value (%1)")
570
- .arg(QMetaType::typeName(type)));
510
+ throw ConversionError(QString("failed to convert QVariant value (%1)")
511
+ .arg(QMetaType::typeName(type)));
571
512
  }
572
513
  return hash[type](variant);
573
514
  }
@@ -588,10 +529,9 @@ QVariant RubyValue::toVariant(int type) const
588
529
  if (qobj->inherits(metaobj->className())) {
589
530
  return QVariant::fromValue(qobj);
590
531
  }
591
- fail("QML::ConversionError",
592
- QString("failed to convert QObject value (%1 to %2)")
593
- .arg(qobj->metaObject()->className())
594
- .arg(metaobj->className()));
532
+ throw ConversionError(QString("failed to convert QObject value (%1 to %2)")
533
+ .arg(qobj->metaObject()->className())
534
+ .arg(metaobj->className()));
595
535
  }
596
536
  if (enumeratorMetaTypes->contains(type)) {
597
537
  auto intValue = to<int>();
@@ -599,10 +539,9 @@ QVariant RubyValue::toVariant(int type) const
599
539
  *static_cast<int *>(data) = intValue;
600
540
  return QVariant(type, data);
601
541
  }
602
- fail("QML::ConversionError",
603
- QString("failed to convert Ruby value (%1 to %2)")
604
- .arg(rb_obj_classname(x))
605
- .arg(QMetaType::typeName(type)));
542
+ throw ConversionError(QString("failed to convert Ruby value (%1 to %2)")
543
+ .arg(rb_obj_classname(x))
544
+ .arg(QMetaType::typeName(type)));
606
545
  return QVariant();
607
546
  }
608
547
  return hash[type](x);
@@ -634,12 +573,12 @@ RubyValue RubyValue::fromQObject(QObject *obj, bool implicit)
634
573
  auto pointer = Ext_Pointer::fromQObject(obj, false);
635
574
 
636
575
  RubyValue wrapper;
637
- protect([&] {
638
- auto klass = rb_funcall(metaobj, RUBYQML_INTERN("build_class"), 0);
639
- wrapper = rb_obj_alloc(klass);
640
- rb_funcall(wrapper, RUBYQML_INTERN("pointer="), 1, pointer);
641
- rb_obj_call_init(wrapper, 0, nullptr);
642
- });
576
+
577
+ auto klass = rb_funcall(metaobj, RUBYQML_INTERN("build_class"), 0);
578
+ wrapper = rb_obj_alloc(klass);
579
+ rb_funcall(wrapper, RUBYQML_INTERN("pointer="), 1, pointer);
580
+ rb_obj_call_init(wrapper, 0, nullptr);
581
+
643
582
  data->rubyObject = wrapper;
644
583
  return wrapper;
645
584
  }
@@ -653,9 +592,7 @@ QObject *RubyValue::toQObject() const
653
592
  }
654
593
  static auto accessModule = RubyModule::fromPath("QML::Access");
655
594
  if (x.isKindOf(accessModule)) {
656
- auto wrapperFactory = protect([&] {
657
- return rb_funcall(rb_obj_class(x), RUBYQML_INTERN("access_wrapper_factory"), 0);
658
- });
595
+ auto wrapperFactory = rb_funcall(rb_obj_class(x), RUBYQML_INTERN("access_wrapper_factory"), 0);
659
596
  return wrapperRubyClass<Ext_AccessWrapperFactory>().unwrap(wrapperFactory)->create(x);
660
597
  }
661
598
  static auto listModelClass = RubyModule::fromPath("QML::Data::ListModel");
@@ -665,9 +602,8 @@ QObject *RubyValue::toQObject() const
665
602
 
666
603
  static auto objectBaseClass = RubyClass::fromPath("QML::QtObjectBase");
667
604
  if (!x.isKindOf(objectBaseClass)) {
668
- fail("QML::ConversionError",
669
- QString("expected QML::QtObjectbase, got %1")
670
- .arg(x.send("class").send("name").to<QString>()));
605
+ throw ConversionError(QString("expected QML::QtObjectbase, got %1")
606
+ .arg(x.send("class").send("name").to<QString>()));
671
607
  }
672
608
  auto objptr = x.send(RUBYQML_INTERN("pointer"));
673
609
  auto obj = wrapperRubyClass<Ext_Pointer>().unwrap(objptr)->fetchQObject();
@@ -677,9 +613,7 @@ QObject *RubyValue::toQObject() const
677
613
 
678
614
  ID RubyValue::toID() const
679
615
  {
680
- return protect([&] {
681
- return SYM2ID(rb_convert_type(*this, T_SYMBOL, "Symbol", "to_sym"));
682
- });
616
+ return SYM2ID(rb_convert_type(*this, T_SYMBOL, "Symbol", "to_sym"));
683
617
  }
684
618
 
685
619
  void RubyValue::addEnumeratorMetaType(int metaType)