qml 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)