QWebChannel 2019.1.4

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce07be00157d3eee912b213bf18e2b92d1448aa8
4
+ data.tar.gz: 5084ac99eceb709a464ff0fafe5045fc9c0ec65c
5
+ SHA512:
6
+ metadata.gz: cdb5fb1f2450cf76ed90094b43e3fdc3acd65a76f89fe3c610dd8c7a1d993ebf889045ebd584aa76a499bd7eda394e1b66ff4dbb3f854175d364058d156d5c78
7
+ data.tar.gz: 784b99bf85a8d6c6f3a191ade87623ad2da6cf35f885aa5ada5b7f20383eee0f6383e5d16ee297485ea40394090ef9fe7af5f243a9133f04398d1f0968be893a
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../QWebChannel', __FILE__)
4
+
5
+ # require 'Hearch/HearchIndexEntry_pb'
6
+ require 'QWebChannel/QSignal'
7
+ require 'QWebChannel/QObject'
8
+ require 'set'
9
+ require 'oj' #optimized json
10
+ require 'json' #json解析库。
11
+
12
+ module QWebChannelMessageTypes
13
+ SIGNAL=1
14
+ PROPERTYUPDATE=2
15
+ INIT=3
16
+ IDLE=4
17
+ DEBUG=5
18
+ INVOKEMETHOD=6
19
+ CONNECTTOSIGNAL=7
20
+ DISCONNECTFROMSIGNAL=8
21
+ SETPROPERTY=9
22
+ RESPONSE=10
23
+ end
24
+
25
+
26
+ class QWebChannel
27
+ attr_reader :execId
28
+ attr_writer :execId
29
+ attr_reader :execCallbacks
30
+ attr_writer :execCallbacks
31
+ attr_reader :transport
32
+ attr_writer :transport
33
+ attr_reader :objects
34
+ attr_writer :objects
35
+
36
+ def send(data)
37
+ if ( !( data.is_a?(String) ) )
38
+ data=Oj.dump(data)
39
+ end
40
+
41
+ puts "Sending: #{data}"
42
+
43
+ @channel.transport.send(data)
44
+ end
45
+
46
+ def exec(data, &block)
47
+ if !(block_given?)
48
+ @channel.send(data)
49
+ end
50
+
51
+ @channel.execId=@channel.execId+1
52
+ data['id']=@channel.execId
53
+
54
+ puts "data id: #{data['id']}"
55
+
56
+ @channel.execCallbacks[data['id']]=block
57
+ @channel.send(data)
58
+ end
59
+
60
+ def handleResponse(message)
61
+ @channel.execCallbacks[message['id']].call(message['data'])
62
+
63
+ @channel.execCallbacks[message['id']]=nil
64
+ end
65
+
66
+ def handleSignal(message)
67
+ object=@channel.objects[message['object']]
68
+
69
+ if (object)
70
+ object.signalEmitted(message['signal'], message['args'])
71
+ end
72
+ end #def handleSignal(message)
73
+
74
+
75
+ def initialize(websocket, &block)
76
+ @index = nil #索引对象。
77
+ @execId=0
78
+ @execCallbacks={}
79
+ @objects={}
80
+
81
+ @transport=websocket
82
+ @channel = self
83
+
84
+
85
+ @transport.onmessage do |msg, type|
86
+ # puts "Received message: #{msg}"
87
+
88
+ puts "msg type: #{msg.class}"
89
+
90
+ data =msg.to_s
91
+
92
+ puts "data: #{data}"
93
+
94
+ if (data.is_a?(String))
95
+ data=JSON.parse(data)
96
+ end
97
+
98
+ puts "type: #{data.class}"
99
+
100
+ case(data['type'])
101
+ when QWebChannelMessageTypes::SIGNAL
102
+ @channel.handleSignal(data)
103
+ when QWebChannelMessageTypes::RESPONSE
104
+ @channel.handleResponse(data)
105
+ when QWebChannelMessageTypes::PROPERTYUPDATE
106
+ @channel.handlePropertyUpdate(data)
107
+ else
108
+ puts("Invalid message arrived: #{data}")
109
+ end
110
+ end
111
+
112
+
113
+ @channel.exec({'type' => QWebChannelMessageTypes::INIT}) do |data|
114
+
115
+ puts "data type: #{data.class}"
116
+ puts "data content: #{data}"
117
+
118
+ data.each do |objectName, objectContent|
119
+ puts "objectName type: #{objectName.class}"
120
+
121
+ object=QObject.new(objectName, data[objectName], @channel)
122
+ end
123
+
124
+ @channel.objects.each do |objectName, objectObject|
125
+ @channel.objects[objectName].unwrapProperties()
126
+ end
127
+
128
+
129
+ puts "Self: #{self}"
130
+ yield(self)
131
+
132
+
133
+ @channel.exec({ "type" => QWebChannelMessageTypes::IDLE})
134
+ end #@channel.exec({'type' => QWebChannelMessageTypes::INIT}) do |data|
135
+ end #def initialize(websocket, &block)
136
+
137
+ end
@@ -0,0 +1,19 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: HearchIndexEntry.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "com.stupidbeauty.hearch.HearchIndexEntry" do
8
+ optional :keyword, :string, 1
9
+ repeated :articleId, :int32, 2
10
+ end
11
+ end
12
+
13
+ module Com
14
+ module Stupidbeauty
15
+ module Hearch
16
+ HearchIndexEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("com.stupidbeauty.hearch.HearchIndexEntry").msgclass
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'eventmachine'
4
+ require 'ipaddr'
5
+
6
+ class MulticastHandler < EventMachine::Connection
7
+ def castData(packageString)
8
+ multicastHost = '239.173.40.5' #组播组主机地址。
9
+ multicastPort = 11500 #组播组端口。
10
+
11
+ # print("castData\n") #Debug.
12
+ # send_data(packageString)
13
+ send_datagram(packageString, multicastHost, multicastPort) #发送组播数据包。
14
+ end
15
+
16
+ def receive_data(data)
17
+ # puts data
18
+ end
19
+
20
+ def post_init
21
+ # print("post_init\n") #Debug.
22
+ port, host = Socket::unpack_sockaddr_in( get_sockname() )
23
+ ip = IPAddr.new( host ).hton + IPAddr.new("0.0.0.0").hton
24
+ set_sock_opt( Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip )
25
+ end
26
+ end
27
+
@@ -0,0 +1,214 @@
1
+ class QObject
2
+ attr_accessor :__propertyCache__
3
+ attr_accessor :__id__
4
+ attr_accessor :__objectSignals__
5
+ attr_accessor :webChannel
6
+
7
+ def unwrapQObject(response)
8
+ puts "response class: #{response.class}" #debug
9
+ if (response.is_a?(Array))
10
+ ret = []
11
+
12
+ response.each do |responseI|
13
+ ret << @object.unwrapQObject(responseI)
14
+ end
15
+
16
+ return ret
17
+ end #if (response.is_a?(Array))
18
+
19
+
20
+ if (!response || response.is_a?(Fixnum) || response.is_a?(TrueClass) || !response["__QObject*__"] || response.id == nil)
21
+ return response
22
+ end
23
+
24
+ objectId=response.id
25
+
26
+ if (@webChannel.objects[objectId])
27
+ return @webChannel.objects[objectId]
28
+ end
29
+
30
+
31
+ qObject=QObject.new(objectId, response.data, @webChannel)
32
+
33
+ qObject.destroyed.connect() do
34
+ if (@webChannel.objects[objectId]==qObject)
35
+ @webChannel.objects.delete(objectId)
36
+
37
+ propertyNames=[]
38
+
39
+ qObject.each do |propertyName|
40
+ propertyNames << propertyName
41
+ end
42
+
43
+ propertyNames.each do |propertyName|
44
+ qObject.delete(propertyName)
45
+ end
46
+ end #if (@webChannel.objects[objectId]==qObject)
47
+ end #qObject.destroyed.connect() do
48
+
49
+ qObject.unwrapProperties()
50
+
51
+ return qObject
52
+ end #def unwrapQObject(response)
53
+
54
+ def unwrapProperties()
55
+ @object.__propertyCache__.each do |propertyIdx, propertyObject|
56
+ @object.__propertyCache__[propertyIdx]=@object.unwrapQObject(@object.__propertyCache__[propertyIdx])
57
+ end
58
+ end #def unwrapProperties()
59
+
60
+ def []=(signalName, signalObject)
61
+ @signalNameObjectHash[signalName]=signalObject
62
+ end #def []=(signalName, signalObject)
63
+
64
+ def [](signalName)
65
+ @signalNameObjectHash[signalName]
66
+ end #def [](signalName)
67
+
68
+ def bindGetterSetter(propertyInfo)
69
+ propertyIndex=propertyInfo[0]
70
+ propertyName=propertyInfo[1]
71
+ notifySignalData=propertyInfo[2]
72
+
73
+ @object.__propertyCache__[propertyIndex]=propertyInfo[3]
74
+
75
+ if (notifySignalData)
76
+ if (notifySignalData[0] == 1)
77
+ notifySignalData[0]=propertyName+"Changed"
78
+ end
79
+ addSignal(notifySignalData, true)
80
+ end #if (notifySignalData)
81
+
82
+ defineProperty(propertyName) #定义属性。对应于Object.defineProperty.
83
+ end #def bindGetterSetter(propertyInfo)
84
+
85
+ def defineProperty(propertyName)
86
+ # define_property_by_prototype(propertyName)
87
+
88
+
89
+ #getter
90
+ # self.class_eval( " def #{attr_name}; @#{attr_name}; end " )
91
+ self.instance_eval %Q{
92
+ def #{propertyName}
93
+ @object.__propertyCache__[propertyIndex]
94
+ end
95
+ }
96
+
97
+ #setter
98
+ self.instance_eval %Q{
99
+ def #{propertyName}=(val)
100
+
101
+ @object.__propertyCache__[propertyIndex]=val
102
+
103
+ valueToSend=val
104
+
105
+ if (valueToSend.is_a?(QObject) && @webChannel.objects[valueToSend.__id__] != nil)
106
+ valueToSend={"id" => valueToSend.__id__}
107
+
108
+ @webChannel.exec( {"type" => QWebChannelMessageTypes::SETPROPERTY, "object" => @object.__id__ , "property" => propertyIndex, "value" => valueToSend } )
109
+ end
110
+
111
+
112
+
113
+ end
114
+
115
+
116
+ }
117
+
118
+ end #def defineProperty(propertyName)
119
+
120
+ def invokeSignalCallbacks(signalName, signalArgs)
121
+ connections=@object.__objectSignals__[signalName]
122
+
123
+ if (connections) #存在连接。
124
+ connections.each do |callback| #一个个连接地处理。
125
+ callback.call(*signalArgs) #抹平数组。
126
+ end #connections.each do |callback| #一个个连接地处理。
127
+ end #if (connections)
128
+ end #def invokeSignalCallbacks(signalName, signalArgs)
129
+
130
+ def signalEmitted(signalName, signalArgs)
131
+ puts "signalArgs: #{signalArgs}" #debug.
132
+ invokeSignalCallbacks(signalName, self.unwrapQObject(signalArgs))
133
+ end #def signalEmitted(signalName, signalArgs)
134
+
135
+ def addSignal(signalData, isPropertyNotifySignal)
136
+ signalName=signalData[0]
137
+ signalIndex=signalData[1]
138
+
139
+ @object[signalName]=QSignal.new(signalName, signalIndex, @object, isPropertyNotifySignal) #添加信号。
140
+ end #def addSignal(signalData, isPropertyNotifySignal)
141
+
142
+ def addMethod(methodData)
143
+ methodName=methodData[0]
144
+ methodIdx=methodData[1]
145
+
146
+ @object.define_singleton_method(methodName) do |*arguments|
147
+ args=[]
148
+ callback=nil
149
+
150
+ arguments.each do |argument|
151
+ puts "argument class: #{argument.class}" #debug.
152
+ if (argument.is_a?(Proc))
153
+ callback=argument
154
+ elsif ( (argument.is_a?(QObject)) && (@webChannel.objects[argument.__id__] !=nil ) )
155
+ args << ({"id" => argument.__id__})
156
+ else
157
+ args << argument
158
+ end
159
+ end #arguments.each do |argument|
160
+
161
+ puts "__id__: #{@object.__id__}" #debug.
162
+
163
+
164
+ @webChannel.exec({ "type" => QWebChannelMessageTypes::INVOKEMETHOD, "object" => @object.__id__, "method" => methodIdx, "args" => args }) do |response|
165
+ if (response!=nil)
166
+ result = @object.unwrapQObject(response)
167
+
168
+ if (callback)
169
+ callback.call(result)
170
+ end
171
+ end #if (response!=nil)
172
+ end #@webChannel.exec() do |response|
173
+
174
+
175
+ end #@object.define_singleton_method(methodName) do |*arguments|
176
+ end #def addMethod(methodData)
177
+
178
+ def initialize(name, data, webChannel)
179
+ @signalNameObjectHash={} #信号名字与信号对象的映射。
180
+ @__id__=name
181
+ @webChannel=webChannel
182
+ webChannel.objects[name]=self
183
+
184
+ puts "__id__: #{@__id__}" #debug.
185
+
186
+
187
+ @__objectSignals__ = {}
188
+
189
+ @__propertyCache__ = {}
190
+
191
+ @object=self
192
+
193
+ data['methods'].each do |method|
194
+ puts "current method: #{method}" #debug
195
+ addMethod(method)
196
+ end
197
+
198
+ data['properties'].each do |property|
199
+ bindGetterSetter(property)
200
+ end
201
+
202
+ data['signals'].each do |signal|
203
+ addSignal(signal, false)
204
+ end
205
+
206
+ puts "enums: #{data['enums']}" #Debug.
207
+
208
+ if data['enums']
209
+ data['enums'].each do |name|
210
+ @object[name]=data['enums'][name]
211
+ end #data['enums'].each do |name|
212
+ end #if data['enums']
213
+ end
214
+ end
@@ -0,0 +1,31 @@
1
+ class QSignal
2
+ def initialize(signalName, signalIndex, object, isPropertyNotifySignal)
3
+ @signalName=signalName
4
+ @signalIndex=signalIndex
5
+ @object=object
6
+ @webChannel=@object.webChannel
7
+ @isPropertyNotifySignal=isPropertyNotifySignal
8
+ end
9
+
10
+ def connect(callback)
11
+ @object.__objectSignals__[@signalIndex]=@object.__objectSignals__[@signalIndex] || []
12
+ @object.__objectSignals__[@signalIndex] << callback
13
+
14
+ if (!@isPropertyNotifySignal && @signalName!= "destroyed")
15
+ @webChannel.exec( { "type" => QWebChannelMessageTypes::CONNECTTOSIGNAL, "object" => @object.__id__, "signal" => @signalIndex } )
16
+ end
17
+ end #def connect(callback)
18
+
19
+ def disconnect(callback)
20
+ @object.__objectSignals__[signalIndex]=@object.__objectSignals__[signalIndex] || []
21
+ idx=@object.__objectSignals__[signalIndex].indexOf(callback)
22
+
23
+
24
+ @object.__objectSignals__[signalIndex].delete_at(idx)
25
+
26
+ if (!isPropertyNotifySignal && @object.__objectSignals__[signalIndex].length == 0)
27
+ @webChannel.exec( { "type" => QWebChannelMessageTypes::DISCONNECTFROMSIGNAL, "object" => @object.__id__, "signal" => signalIndex } )
28
+ end #if (!isPropertyNotifySignal && @object.__objectSignals__[signalIndex].length == 0)
29
+ end #def disconnect(callback)
30
+ end #class QSignal
31
+
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: QWebChannel
3
+ version: !ruby/object:Gem::Version
4
+ version: 2019.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Hxcan Cai
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-01-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: websocket-eventmachine-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.2.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.2.0
33
+ description: QWebChannel ruby. Work with QWebChannel in pure ruby.
34
+ email: caihuosheng@gmail.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - lib/QWebChannel.rb
40
+ - lib/QWebChannel/HearchIndexEntry_pb.rb
41
+ - lib/QWebChannel/MulticastHandler.rb
42
+ - lib/QWebChannel/QObject.rb
43
+ - lib/QWebChannel/QSignal.rb
44
+ homepage: http://rubygems.org/gems/QWebChannel
45
+ licenses:
46
+ - MIT
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 2.5.2.3
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: QWebChannel ruby.
68
+ test_files: []