qml 1.0.0 → 1.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c3e17be31c7cb2d6c9530581484a9146c71718e1
4
- data.tar.gz: 0fa4538a3960c37c4afe368986e0d1565ce401c5
3
+ metadata.gz: ab6994a5395ab183bdec0c003033822ea4b2ef99
4
+ data.tar.gz: dbd518f8f5dc09bd4441b82e518c8e086c89e7d3
5
5
  SHA512:
6
- metadata.gz: 643d0c001ba1f018b5784ab472cd789278be85721678c5b4c5dbd1edd9e89beb46b585fa273b12da771594b7d3f6ac147b28ea4e7f72ec4835babe125e08e836
7
- data.tar.gz: 3fdc78678a5790c2123869b66905b40bc24613a6d47cfecbdf322be58ac403d3f60007e9d4856a44b15d64698639d4b6d95b6cc61844fa66610f2322e7fdcf16
6
+ metadata.gz: dbaf73bddc72313761f9b2520edc82e2a309cb8e75fc12d8504d396460045773448cd81e060107d3c8935b566996eb6aff1a8a27cf2352fad71e6aac75e12dad
7
+ data.tar.gz: c36f4bb9facdfa0b85998d12983314d0ab37acfd2a7a4f36b763d45eccdfc44d4a0b9802d5b6e318bacc0037d5daca6070655abe8a2260a5c242292ce1295e57
data/changes.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.0.1 (2015-06-20)
2
+
3
+ * Fixes 100% CPU usage (#21)
4
+
1
5
  ## 1.0.0 (2015-06-16)
2
6
 
3
7
  * A lot of changes (see examples and docs)
@@ -5,7 +5,7 @@
5
5
 
6
6
  VALUE rbqml_mInterface;
7
7
  static qmlbind_interface interface;
8
- static VALUE referenced_objects;
8
+ VALUE rbqml_referenced_objects;
9
9
 
10
10
  qmlbind_interface rbqml_get_interface(void) {
11
11
  return interface;
@@ -24,7 +24,7 @@ static void *new_object_impl(void *p) {
24
24
  VALUE emitterValue = rbqml_signal_emitter_new(data->emitter);
25
25
  rb_funcall(obj, rb_intern("set_signal_emitter"), 1, emitterValue);
26
26
 
27
- rb_hash_aset(referenced_objects, obj, Qnil);
27
+ rb_hash_aset(rbqml_referenced_objects, obj, Qnil);
28
28
  return (void *)obj;
29
29
  }
30
30
 
@@ -37,7 +37,7 @@ static qmlbind_backref new_object(qmlbind_backref class_handle, qmlbind_signal_e
37
37
  }
38
38
 
39
39
  static void *delete_object_impl(void *data) {
40
- rb_hash_delete(referenced_objects, (VALUE)data);
40
+ rb_hash_delete(rbqml_referenced_objects, (VALUE)data);
41
41
  return NULL;
42
42
  }
43
43
 
@@ -151,6 +151,6 @@ void rbqml_init_interface(void) {
151
151
  rb_require("qml/interface");
152
152
  rbqml_mInterface = rb_path2class("QML::Interface");
153
153
  interface = qmlbind_interface_new(handlers);
154
- referenced_objects = rb_hash_new();
155
- rb_gc_register_address(&referenced_objects);
154
+ rbqml_referenced_objects = rb_hash_new();
155
+ rb_gc_register_address(&rbqml_referenced_objects);
156
156
  }
@@ -4,6 +4,7 @@
4
4
  #include "qml.h"
5
5
 
6
6
  extern VALUE rbqml_mInterface;
7
+ extern VALUE rbqml_referenced_objects;
7
8
  qmlbind_interface rbqml_get_interface(void);
8
9
 
9
10
  void rbqml_init_interface(void);
@@ -11,7 +11,8 @@ QMLBIND_API void qmlbind_application_release(qmlbind_application app);
11
11
  QMLBIND_API int qmlbind_application_exec(qmlbind_application app);
12
12
 
13
13
  QMLBIND_API void qmlbind_process_events();
14
- QMLBIND_API void qmlbind_set_tick_callback(void (*func)());
14
+
15
+ QMLBIND_API void qmlbind_next_tick(void (*callback)(void *), void *data);
15
16
 
16
17
  #ifdef __cplusplus
17
18
  }
@@ -49,21 +49,21 @@ typedef QmlBind::SignalEmitter *qmlbind_signal_emitter;
49
49
 
50
50
  #else
51
51
 
52
- typedef struct {} *qmlbind_application;
52
+ typedef struct qmlbind_application_s {} *qmlbind_application;
53
53
 
54
- typedef struct {} *qmlbind_engine;
55
- typedef struct {} *qmlbind_component;
56
- typedef struct {} *qmlbind_plugin;
54
+ typedef struct qmlbind_engine_s {} *qmlbind_engine;
55
+ typedef struct qmlbind_component_s {} *qmlbind_component;
56
+ typedef struct qmlbind_plugin_s {} *qmlbind_plugin;
57
57
 
58
- typedef struct {} *qmlbind_value;
59
- typedef struct {} *qmlbind_iterator;
60
- typedef struct {} *qmlbind_string;
58
+ typedef struct qmlbind_value_s {} *qmlbind_value;
59
+ typedef struct qmlbind_iterator_s {} *qmlbind_iterator;
60
+ typedef struct qmlbind_string_s {} *qmlbind_string;
61
61
 
62
- typedef struct {} *qmlbind_interface;
63
- typedef struct {} *qmlbind_metaobject;
64
- typedef struct {} *qmlbind_exporter;
62
+ typedef struct qmlbind_interface_s {} *qmlbind_interface;
63
+ typedef struct qmlbind_metaobject_s {} *qmlbind_metaobject;
64
+ typedef struct qmlbind_exporter_s {} *qmlbind_exporter;
65
65
 
66
- typedef struct {} *qmlbind_signal_emitter;
66
+ typedef struct qmlbind_signal_emitter_s {} *qmlbind_signal_emitter;
67
67
 
68
68
  #endif
69
69
 
@@ -2,16 +2,12 @@ QT += widgets qml quick core-private
2
2
 
3
3
  TARGET = qmlbind
4
4
  TEMPLATE = lib
5
+ CONFIG += c++11
5
6
 
6
7
  DEFINES += QMLBIND_LIBRARY
7
8
 
8
9
  INCLUDEPATH += $$PWD/include
9
10
 
10
- unix {
11
- target.path = /usr/lib
12
- INSTALLS += target
13
- }
14
-
15
11
  SOURCES += \
16
12
  src/api_application.cpp \
17
13
  src/api_engine.cpp \
@@ -32,31 +28,45 @@ SOURCES += \
32
28
  src/signalemitter.cpp \
33
29
  src/api_signal_emitter.cpp \
34
30
  src/engine.cpp \
35
- src/api_plugin.cpp \
36
- src/ticktimer.cpp
31
+ src/api_plugin.cpp
37
32
 
38
- HEADERS += \
33
+ PUBLIC_HEADERS += \
39
34
  include/qmlbind/application.h \
40
35
  include/qmlbind/engine.h \
41
36
  include/qmlbind/iterator.h \
42
37
  include/qmlbind/qmlbind_global.h \
43
38
  include/qmlbind/value.h \
44
- src/metaobject.h \
45
39
  include/qmlbind/metaobject.h \
46
- src/wrapper.h \
47
40
  include/qmlbind/string.h \
48
41
  include/qmlbind/component.h \
49
42
  include/qmlbind.h \
50
- src/typeregisterer.h \
51
43
  include/qmlbind/register.h \
52
- src/util.h \
53
- src/exporter.h \
54
44
  include/qmlbind/exporter.h \
55
45
  include/qmlbind/interface.h \
46
+ include/qmlbind/signal_emitter.h \
47
+ include/qmlbind/plugin.h \
48
+
49
+ PRIVATE_HEADERS += \
50
+ src/metaobject.h \
51
+ src/wrapper.h \
52
+ src/typeregisterer.h \
53
+ src/util.h \
54
+ src/exporter.h \
56
55
  src/interface.h \
57
56
  src/backref.h \
58
57
  src/signalemitter.h \
59
- include/qmlbind/signal_emitter.h \
60
- src/engine.h \
61
- include/qmlbind/plugin.h \
62
- src/ticktimer.h
58
+ src/engine.h
59
+
60
+ HEADERS = $$PUBLIC_HEADERS $$PRIVATE_HEADERS
61
+
62
+ unix {
63
+ for(header, PUBLIC_HEADERS) {
64
+ path = $${INSTALL_PREFIX}/usr/$${dirname(header)}
65
+ eval(headers_$${path}.files += $$header)
66
+ eval(headers_$${path}.path = $$path)
67
+ eval(INSTALLS *= headers_$${path})
68
+ }
69
+
70
+ target.path = /usr/lib
71
+ INSTALLS += target
72
+ }
@@ -1,6 +1,5 @@
1
1
  #include "qmlbind/application.h"
2
2
  #include "util.h"
3
- #include "ticktimer.h"
4
3
  #include "backref.h"
5
4
  #include <QApplication>
6
5
  #include <QSharedPointer>
@@ -11,22 +10,6 @@ using namespace QmlBind;
11
10
 
12
11
  namespace QmlBind {
13
12
 
14
- class NextTickFunc
15
- {
16
- public:
17
- NextTickFunc(void (*func)(qmlbind_backref), const Backref &data) : mFunc(func), mData(data)
18
- {}
19
-
20
- void operator()()
21
- {
22
- mFunc(mData.backref());
23
- }
24
-
25
- private:
26
- void (*mFunc)(qmlbind_backref);
27
- Backref mData;
28
- };
29
-
30
13
  class AppArgs
31
14
  {
32
15
  public:
@@ -59,8 +42,6 @@ private:
59
42
 
60
43
  }
61
44
 
62
- static void (*tickCallback)();
63
-
64
45
  extern "C" {
65
46
 
66
47
  qmlbind_application qmlbind_application_new(int argc, char **argv)
@@ -68,9 +49,6 @@ qmlbind_application qmlbind_application_new(int argc, char **argv)
68
49
  AppArgs *args = new AppArgs(argc, argv);
69
50
  QApplication *app = new QApplication(args->argc(), args->argv());
70
51
 
71
- TickTimer *timer = new TickTimer(&tickCallback, app);
72
- timer->start();
73
-
74
52
  return app;
75
53
  }
76
54
 
@@ -90,14 +68,11 @@ void qmlbind_process_events()
90
68
  QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
91
69
  }
92
70
 
93
- void qmlbind_set_tick_callback(void (*func)())
94
- {
95
- tickCallback = func;
96
- }
97
-
98
- void qmlbind_next_tick(qmlbind_interface interface, void (*func)(qmlbind_backref), qmlbind_backref data)
71
+ void qmlbind_next_tick(void (*callback)(void *), void *data)
99
72
  {
100
- QTimer::singleShot(0, NextTickFunc(func, Backref(data, *interface)));
73
+ QTimer::singleShot(0, QCoreApplication::instance(), [=] {
74
+ callback(data);
75
+ });
101
76
  }
102
77
 
103
78
  }
@@ -2,14 +2,14 @@
2
2
  #include "fixtures/emptyhandlers.h"
3
3
  #include <qmlbind.h>
4
4
 
5
- TEST_CASE("set_tick_callback")
5
+ TEST_CASE("next_tick")
6
6
  {
7
7
  static bool called;
8
8
  called = false;
9
9
 
10
- qmlbind_set_tick_callback([] {
11
- called = true;
12
- });
10
+ qmlbind_next_tick([] (void *data) {
11
+ *((bool *)data) = true;
12
+ }, &called);
13
13
  qmlbind_process_events();
14
14
 
15
15
  REQUIRE(called);
@@ -10,7 +10,6 @@
10
10
  #include "js_wrapper.h"
11
11
  #include "signal_emitter.h"
12
12
  #include "plugin_loader.h"
13
- #include "dispatcher.h"
14
13
  #include "meta_object.h"
15
14
 
16
15
  VALUE rbqml_mQML;
@@ -67,7 +66,22 @@ static VALUE qml_engine(VALUE module) {
67
66
  rb_raise(rb_eRuntimeError, "QML not yet initialized");
68
67
  }
69
68
  return rbqml_engine;
69
+ }
70
+
71
+ static void nextTickCallback(void *data)
72
+ {
73
+ VALUE block = (VALUE)data;
74
+ rb_proc_call(block, rb_ary_new());
75
+ rb_hash_delete(rbqml_referenced_objects, block);
76
+ }
77
+
78
+ static VALUE qml_next_tick(int argc, VALUE *argv, VALUE module) {
79
+ VALUE block;
80
+ rb_scan_args(argc, argv, "&", &block);
81
+ rb_hash_aset(rbqml_referenced_objects, block, Qnil);
70
82
 
83
+ qmlbind_next_tick(nextTickCallback, (void *)block);
84
+ return block;
71
85
  }
72
86
 
73
87
  void Init_qml(void)
@@ -85,11 +99,11 @@ void Init_qml(void)
85
99
  rbqml_init_js_wrapper();
86
100
  rbqml_init_signal_emitter();
87
101
  rbqml_init_plugin_loader();
88
- rbqml_init_dispatcher();
89
102
  rbqml_init_meta_object();
90
103
 
91
104
  rb_define_module_function(rbqml_mQML, "initialized?", qml_initialized_p, 0);
92
105
  rb_define_module_function(rbqml_mQML, "init_impl", qml_init, 1);
93
106
  rb_define_module_function(rbqml_mQML, "application", qml_application, 0);
94
107
  rb_define_module_function(rbqml_mQML, "engine", qml_engine, 0);
108
+ rb_define_module_function(rbqml_mQML, "next_tick", qml_next_tick, -1);
95
109
  }
data/lib/qml.rb CHANGED
@@ -9,7 +9,6 @@ require 'qml/plugins'
9
9
  require 'qml/component'
10
10
  require 'qml/engine'
11
11
  require 'qml/application'
12
- require 'qml/dispatcher'
13
12
  require 'qml/signal'
14
13
  require 'qml/reactive'
15
14
  require 'qml/access'
@@ -1,3 +1,3 @@
1
1
  module QML
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryohei Ikegami
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-16 00:00:00.000000000 Z
11
+ date: 2015-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -146,8 +146,6 @@ files:
146
146
  - ext/qml/component.h
147
147
  - ext/qml/conversion.c
148
148
  - ext/qml/conversion.h
149
- - ext/qml/dispatcher.c
150
- - ext/qml/dispatcher.h
151
149
  - ext/qml/engine.c
152
150
  - ext/qml/engine.h
153
151
  - ext/qml/exporter.c
@@ -207,8 +205,6 @@ files:
207
205
  - ext/qml/lib/libqmlbind/qmlbind/src/metaobject.h
208
206
  - ext/qml/lib/libqmlbind/qmlbind/src/signalemitter.cpp
209
207
  - ext/qml/lib/libqmlbind/qmlbind/src/signalemitter.h
210
- - ext/qml/lib/libqmlbind/qmlbind/src/ticktimer.cpp
211
- - ext/qml/lib/libqmlbind/qmlbind/src/ticktimer.h
212
208
  - ext/qml/lib/libqmlbind/qmlbind/src/typeregisterer.cpp
213
209
  - ext/qml/lib/libqmlbind/qmlbind/src/typeregisterer.h
214
210
  - ext/qml/lib/libqmlbind/qmlbind/src/util.h
@@ -259,7 +255,6 @@ files:
259
255
  - lib/qml/data/list_model.rb
260
256
  - lib/qml/data/list_model_access.rb
261
257
  - lib/qml/data/query_model.rb
262
- - lib/qml/dispatcher.rb
263
258
  - lib/qml/engine.rb
264
259
  - lib/qml/errors.rb
265
260
  - lib/qml/interface.rb
@@ -1,31 +0,0 @@
1
- #include "dispatcher.h"
2
-
3
- VALUE rbqml_cDispatcher;
4
- int callback_enabled = 1;
5
-
6
- static void tick_callback_impl() {
7
- VALUE dispatcher = rb_funcall(rbqml_cDispatcher, rb_intern("instance"), 0);
8
- rb_funcall(dispatcher, rb_intern("run_tasks"), 0);
9
- }
10
-
11
- static void tick_callback() {
12
- if (__sync_fetch_and_add(&callback_enabled, 0)) {
13
- rb_thread_call_with_gvl((void *(*)(void *))&tick_callback_impl, NULL);
14
- }
15
- }
16
-
17
- static VALUE dispatcher_callback_enabled_set(VALUE self, VALUE enabled) {
18
- if (RTEST(enabled)) {
19
- __sync_fetch_and_or(&callback_enabled, 1);
20
- } else {
21
- __sync_fetch_and_and(&callback_enabled, 0);
22
- }
23
- return enabled;
24
- }
25
-
26
- void rbqml_init_dispatcher(void) {
27
- rbqml_cDispatcher = rb_define_class_under(rb_path2class("QML"), "Dispatcher", rb_cObject);
28
- rb_define_private_method(rbqml_cDispatcher, "callback_enabled=", &dispatcher_callback_enabled_set, 1);
29
-
30
- qmlbind_set_tick_callback(&tick_callback);
31
- }
@@ -1,7 +0,0 @@
1
- #pragma once
2
-
3
- #include "qml.h"
4
-
5
- extern VALUE rbqml_cDispatcher;
6
-
7
- void rbqml_init_dispatcher(void);
@@ -1,15 +0,0 @@
1
- #include "ticktimer.h"
2
-
3
- TickTimer::TickTimer(Callback *whereCallback, QObject *parent) : QTimer(parent), mWhereCallback(whereCallback)
4
- {
5
- setInterval(0);
6
- setSingleShot(false);
7
- connect(this, SIGNAL(timeout()), this, SLOT(onTimeout()));
8
- }
9
-
10
- void TickTimer::onTimeout()
11
- {
12
- if (*mWhereCallback) {
13
- (*mWhereCallback)();
14
- }
15
- }
@@ -1,19 +0,0 @@
1
- #pragma once
2
-
3
- #include <QTimer>
4
-
5
- class TickTimer : public QTimer
6
- {
7
- Q_OBJECT
8
- public:
9
- typedef void (*Callback)();
10
-
11
- explicit TickTimer(Callback *whereCallback, QObject *parent = 0);
12
-
13
- private slots:
14
- void onTimeout();
15
-
16
- private:
17
- Callback *mWhereCallback;
18
- };
19
-
@@ -1,61 +0,0 @@
1
- require 'singleton'
2
- require 'monitor'
3
-
4
- module QML
5
-
6
- class Dispatcher
7
- include Singleton
8
- include MonitorMixin
9
-
10
- MAX_DURATION = 1/10.to_r
11
-
12
- def initialize
13
- super
14
- @tasks = []
15
- end
16
-
17
- def add_task(&task)
18
- synchronize do
19
- callback_enabled = true if @tasks.empty?
20
- @tasks << task
21
- end
22
- end
23
-
24
- def empty?
25
- synchronize do
26
- @tasks.empty?
27
- end
28
- end
29
-
30
- def run_tasks
31
- synchronize do
32
- start_time = Time.now
33
- loop do
34
- break if @tasks.empty?
35
- break if start_time.to_r - Time.now.to_r > MAX_DURATION
36
- task = @tasks.shift
37
- task.call
38
- end
39
- callback_enabled = false if @tasks.empty?
40
- end
41
- end
42
- end
43
-
44
- # Runs a block asynchronously within the event loop.
45
- #
46
- # QML UI is not thread-safe and can only be accessed from the main thread.
47
- # Use this method to set results of asynchronous tasks to UI.
48
- # @example
49
- # def on_button_clicked
50
- # Thread.new do
51
- # result = do_task
52
- # QML.next_tick do
53
- # set_result_to_ui(result)
54
- # end
55
- # end
56
- # end
57
- def next_tick(&block)
58
- Dispatcher.instance.add_task(&block)
59
- end
60
- module_function :next_tick
61
- end