hakuban 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hakuban/ffi.rb +12 -8
- data/lib/hakuban/hakuban.rb +131 -36
- data/lib/hakuban/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aca4a31cd75c69917785c7d5d3110c9db07d44c9be8394b37714fcae3019b5f6
|
4
|
+
data.tar.gz: a3c81f4d62a36fbac4bbdf6cf709909bcc132b4330e62de9b2fb39ddd4e48e72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a59840edfda985efda0031603f8901a24026b6edcc044f6ac61f3c04d6e8c4cae9199eb2b10b8496810b4182f85337907ee518f3d136c4a8bb829f10f66eb9d
|
7
|
+
data.tar.gz: bf7e24798ea39f0524075fcacc5a47bf8f060d72a797d2b7b92827be1b6cda252df2e8da8e64cd4c8e937b2ef08f5ae21e87ff15e3174ed9164ef2a6b64d7642
|
data/lib/hakuban/ffi.rb
CHANGED
@@ -32,6 +32,7 @@ module Hakuban::FFI
|
|
32
32
|
|
33
33
|
class FFIObjectExposeState < FFI::Struct
|
34
34
|
layout :version_length, :size_t, :version, :pointer, :data_type_length, :size_t, :data_type, :pointer, :raw_length, :size_t, :raw, :pointer
|
35
|
+
attr_accessor :data_type_strings
|
35
36
|
|
36
37
|
def self.construct(version, data_type, data)
|
37
38
|
state = FFIObjectExposeState::new
|
@@ -40,7 +41,8 @@ module Hakuban::FFI
|
|
40
41
|
state[:version].write_array_of_int64(version)
|
41
42
|
state[:data_type_length] = data_type.size
|
42
43
|
state[:data_type] = FFI::MemoryPointer.new(:pointer, data_type.size)
|
43
|
-
state
|
44
|
+
state.data_type_strings = data_type.map {|string| FFI::MemoryPointer.from_string(string)}
|
45
|
+
state[:data_type].write_array_of_pointer(state.data_type_strings)
|
44
46
|
state[:raw] = FFI::MemoryPointer.from_string(data)
|
45
47
|
state[:raw_length] = data.size
|
46
48
|
state
|
@@ -61,7 +63,8 @@ module Hakuban::FFI
|
|
61
63
|
|
62
64
|
class FFIObjectDescriptor < FFI::Struct
|
63
65
|
layout :tags_count, :size_t, :tags, :pointer, :json, :pointer
|
64
|
-
|
66
|
+
attr_accessor :tags_strings
|
67
|
+
|
65
68
|
def tags
|
66
69
|
self[:tags].read_array_of_pointer(self[:tags_count]).map { |string| JSON.parse(string.read_string()) } # does this copy the string?
|
67
70
|
end
|
@@ -71,12 +74,11 @@ module Hakuban::FFI
|
|
71
74
|
end
|
72
75
|
|
73
76
|
def self.construct(tags,json)
|
74
|
-
tags_strings = tags.map { |tag| JSON.dump(tag) }
|
75
|
-
tags_strings_array = FFI::MemoryPointer.new(:pointer, tags_strings.size)
|
76
|
-
tags_strings_array.write_array_of_pointer(tags_strings.map {|string| FFI::MemoryPointer.from_string(string)})
|
77
77
|
descriptor = FFIObjectDescriptor.new
|
78
78
|
descriptor[:tags_count] = tags.size
|
79
|
-
descriptor
|
79
|
+
descriptor.tags_strings = tags.map { |tag| FFI::MemoryPointer.from_string(JSON.dump(tag)) }
|
80
|
+
descriptor[:tags] = FFI::MemoryPointer.new(:pointer, descriptor.tags_strings.size)
|
81
|
+
descriptor[:tags].write_array_of_pointer(descriptor.tags_strings)
|
80
82
|
descriptor[:json] = FFI::MemoryPointer.from_string(JSON.dump(json))
|
81
83
|
descriptor
|
82
84
|
end
|
@@ -146,7 +148,9 @@ module Hakuban::FFI
|
|
146
148
|
attach_function :hakuban_object_callback_unregister, [ :pointer ], :void, blocking: true
|
147
149
|
|
148
150
|
attach_function :hakuban_tokio_init_multi_thread, [ :size_t ], :pointer
|
149
|
-
attach_function :hakuban_tokio_websocket_connector_new, [ :pointer, :string ], FFITokioWebsocketConnectorNewResult.by_value
|
150
|
-
attach_function :
|
151
|
+
attach_function :hakuban_tokio_websocket_connector_new, [ :pointer, :pointer, :string ], FFITokioWebsocketConnectorNewResult.by_value
|
152
|
+
attach_function :hakuban_tokio_websocket_connector_drop, [ :pointer, :pointer ], :void
|
153
|
+
|
154
|
+
attach_function :hakuban_logger_initialize, [ :string ], :uint8
|
151
155
|
|
152
156
|
end
|
data/lib/hakuban/hakuban.rb
CHANGED
@@ -4,6 +4,8 @@ require_relative './ffi.rb'
|
|
4
4
|
|
5
5
|
#TODO: explicit drops?
|
6
6
|
#TODO: privative methods
|
7
|
+
#TODO: error classes
|
8
|
+
|
7
9
|
|
8
10
|
module Hakuban
|
9
11
|
|
@@ -28,6 +30,19 @@ module Hakuban
|
|
28
30
|
end
|
29
31
|
|
30
32
|
|
33
|
+
@@logger_initialized = false
|
34
|
+
|
35
|
+
def self.logger_initialize(default_level, skip_if_already_initialized = false)
|
36
|
+
if @@logger_initialized and !skip_if_already_initialized
|
37
|
+
raise "Logger already initialized. This can't be done more than once. Make sure logger_initialize is called before any LocalNode gets constructed."
|
38
|
+
end
|
39
|
+
if not @@logger_initialized
|
40
|
+
raise "Invalid default log level string" if FFI::hakuban_logger_initialize(default_level) != 0
|
41
|
+
@@logger_initialized = true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
31
46
|
class LocalNode
|
32
47
|
|
33
48
|
#TODO: explicit drop
|
@@ -35,7 +50,8 @@ module Hakuban
|
|
35
50
|
attr_reader :local_node_pointer #todo: hide
|
36
51
|
|
37
52
|
def initialize(name=nil)
|
38
|
-
|
53
|
+
Hakuban::logger_initialize("hakuban=warn", true)
|
54
|
+
result = FFI::hakuban_local_node_new(name || File.basename(caller_locations(0..1)[1].path))
|
39
55
|
Hakuban::raise_if_error(result)
|
40
56
|
@local_node_pointer = ::FFI::AutoPointer.new(result[:local_node_pointer], FFI::method(:hakuban_local_node_drop))
|
41
57
|
end
|
@@ -111,6 +127,11 @@ module Hakuban
|
|
111
127
|
def hash
|
112
128
|
[@tags.hash, @json.hash].hash
|
113
129
|
end
|
130
|
+
|
131
|
+
def inspect
|
132
|
+
"#<ObjectDescriptor @tags={%s}, @json=%p>"%[self.tags.map(&:inspect).join(","), self.json]
|
133
|
+
end
|
134
|
+
|
114
135
|
end
|
115
136
|
|
116
137
|
|
@@ -213,12 +234,13 @@ module Hakuban
|
|
213
234
|
def drop
|
214
235
|
@object_observe_pointer.free
|
215
236
|
@object_observe_pointer = nil
|
216
|
-
@queues.values.each { |pointer| pointer.free }
|
217
237
|
@queues.clear
|
218
238
|
end
|
219
239
|
|
220
|
-
def manage(
|
221
|
-
|
240
|
+
def manage(manager=nil)
|
241
|
+
manager ||= ObjectManager.new
|
242
|
+
manager.contract = self
|
243
|
+
manager
|
222
244
|
end
|
223
245
|
|
224
246
|
end
|
@@ -264,15 +286,20 @@ module Hakuban
|
|
264
286
|
@queues.delete(queue)
|
265
287
|
end
|
266
288
|
|
289
|
+
def inspect
|
290
|
+
"#<ObjectExpose #{@descriptor}>"
|
291
|
+
end
|
292
|
+
|
267
293
|
def drop
|
268
294
|
@object_expose_pointer.free
|
269
295
|
@object_expose_pointer = nil
|
270
|
-
@queues.values.each { |pointer| pointer.free }
|
271
296
|
@queues.clear
|
272
297
|
end
|
273
298
|
|
274
|
-
def manage(
|
275
|
-
|
299
|
+
def manage(manager=nil)
|
300
|
+
manager ||= ObjectManager.new
|
301
|
+
manager.contract = self
|
302
|
+
manager
|
276
303
|
end
|
277
304
|
|
278
305
|
end
|
@@ -280,7 +307,7 @@ module Hakuban
|
|
280
307
|
|
281
308
|
class ObjectObserveState
|
282
309
|
|
283
|
-
attr_reader :data, :data_type, :data_version
|
310
|
+
attr_reader :data, :data_type, :data_version, :synchronized
|
284
311
|
|
285
312
|
def initialize(raw_state)
|
286
313
|
@raw_state = raw_state
|
@@ -302,7 +329,7 @@ module Hakuban
|
|
302
329
|
end
|
303
330
|
|
304
331
|
def inspect
|
305
|
-
"#<ObjectObserveState version
|
332
|
+
"#<ObjectObserveState @synchronized=%p @version=%p>"%[@synchronized, @data_version]
|
306
333
|
end
|
307
334
|
|
308
335
|
end
|
@@ -357,12 +384,13 @@ module Hakuban
|
|
357
384
|
def drop
|
358
385
|
@tag_observe_pointer.free
|
359
386
|
@tag_observe_pointer = nil
|
360
|
-
@queues.values.each { |pointer| pointer.free }
|
361
387
|
@queues.clear
|
362
388
|
end
|
363
389
|
|
364
|
-
def manage(
|
365
|
-
ObjectManager
|
390
|
+
def manage(manager=nil)
|
391
|
+
manager ||= ObjectManager.new
|
392
|
+
manager.contract = self
|
393
|
+
manager
|
366
394
|
end
|
367
395
|
|
368
396
|
end
|
@@ -418,12 +446,13 @@ module Hakuban
|
|
418
446
|
def drop
|
419
447
|
@tag_expose_pointer.free
|
420
448
|
@tag_expose_pointer = nil
|
421
|
-
@queues.values.each { |pointer| pointer.free }
|
422
449
|
@queues.clear
|
423
450
|
end
|
424
451
|
|
425
|
-
def manage(
|
426
|
-
ObjectManager
|
452
|
+
def manage(manager=nil)
|
453
|
+
manager ||= ObjectManager.new
|
454
|
+
manager.contract = self
|
455
|
+
manager
|
427
456
|
end
|
428
457
|
|
429
458
|
end
|
@@ -452,10 +481,10 @@ module Hakuban
|
|
452
481
|
|
453
482
|
#TODO: drop
|
454
483
|
|
455
|
-
def initialize(url)
|
456
|
-
result = FFI::hakuban_tokio_websocket_connector_new(Tokio.pointer, url)
|
484
|
+
def initialize(local_node, url)
|
485
|
+
result = FFI::hakuban_tokio_websocket_connector_new(Tokio.pointer, local_node.local_node_pointer, url)
|
457
486
|
Hakuban::raise_if_error(result)
|
458
|
-
@websocket_connector_pointer = result[:websocket_connector_pointer]
|
487
|
+
@websocket_connector_pointer = ::FFI::AutoPointer.new(result[:websocket_connector_pointer], WebsocketConnector.generate_drop)
|
459
488
|
end
|
460
489
|
|
461
490
|
def start(local_node)
|
@@ -464,38 +493,99 @@ module Hakuban
|
|
464
493
|
self
|
465
494
|
end
|
466
495
|
|
496
|
+
def self.generate_drop
|
497
|
+
proc { |pointer|
|
498
|
+
FFI::hakuban_tokio_websocket_connector_drop(Tokio.pointer, pointer)
|
499
|
+
}
|
500
|
+
end
|
501
|
+
|
467
502
|
end
|
468
503
|
|
469
504
|
|
470
505
|
# convenience utils
|
471
506
|
|
472
|
-
|
507
|
+
#TODO: replace this mess (<Hash, dynamic mixings) with some "deref"
|
508
|
+
class ObjectManager < Hash
|
509
|
+
|
510
|
+
module ObservedObjectManager
|
511
|
+
def descriptor; self.values.first.descriptor; end
|
512
|
+
def state; self.values.first.state; end
|
513
|
+
def data; self.values.first.data; end
|
514
|
+
def version; self.values.first.verison; end
|
515
|
+
def synchronized; self.values.first.synchronized; end
|
516
|
+
def construct_object(contract, descriptor); ObservedObject.new(contract, descriptor); end
|
517
|
+
end
|
518
|
+
|
519
|
+
module ExposedObjectManager
|
520
|
+
def descriptor; self.values.first.descriptor; end
|
521
|
+
def state=(params); self.values.first.state = params; end
|
522
|
+
def data=(params); self.values.first.data = params; end
|
523
|
+
def state_set(params); self.values.first.state_set(params); end
|
524
|
+
def data_set(params); self.values.first.data_set(params); end
|
525
|
+
def construct_object(contract, descriptor); ExposedObject.new(contract, descriptor); end
|
526
|
+
end
|
527
|
+
|
528
|
+
module ObservedTagManager
|
529
|
+
def construct_object(contract, descriptor); ObservedObject.new(contract, descriptor); end
|
530
|
+
end
|
531
|
+
|
532
|
+
module ExposedTagManager
|
533
|
+
def construct_object(contract, descriptor); ExposedObject.new(contract, descriptor); end
|
534
|
+
end
|
473
535
|
|
474
536
|
attr_reader :objects, :contract
|
475
537
|
|
476
|
-
def
|
538
|
+
def contract=(contract)
|
539
|
+
raise "You can't change contracts, sorry." if @contract
|
477
540
|
@contract = contract
|
478
|
-
@
|
541
|
+
case @contract.class.name
|
542
|
+
when "Hakuban::ObjectObserve" then singleton_class.include(ObservedObjectManager)
|
543
|
+
when "Hakuban::ObjectExpose" then singleton_class.include(ExposedObjectManager)
|
544
|
+
when "Hakuban::TagObserve" then singleton_class.include(ObservedTagManager)
|
545
|
+
when "Hakuban::TagExpose" then singleton_class.include(ExposedTagManager)
|
546
|
+
else raise
|
547
|
+
end
|
548
|
+
|
479
549
|
@queue = Queue.new
|
480
|
-
contract.send_events_to(@queue, :object)
|
550
|
+
@contract.send_events_to(@queue, :object)
|
551
|
+
if @contract.kind_of?(ObjectObserve) or @contract.kind_of?(ObjectExpose)
|
552
|
+
event, param, descriptor = @queue.pop
|
553
|
+
raise if event != :object or param != :insert or not descriptor
|
554
|
+
self[descriptor] = self.construct_object(@contract, descriptor)
|
555
|
+
end
|
556
|
+
|
481
557
|
@thread = Thread.new {
|
482
558
|
loop {
|
483
|
-
event = @queue.shift
|
484
|
-
case event
|
559
|
+
event,param,descriptor = @queue.shift
|
560
|
+
case [event, param]
|
485
561
|
when [:control, :quit]
|
486
562
|
break
|
487
563
|
when [:object, :insert]
|
488
|
-
|
564
|
+
self[descriptor] = construct_object(@contract, descriptor)
|
565
|
+
object_insert(self[descriptor])
|
489
566
|
when [:object, :change]
|
490
|
-
|
567
|
+
object_change(self[descriptor])
|
491
568
|
when [:object, :remove]
|
492
|
-
|
493
|
-
deleted.drop if deleted.respond_to?(:drop)
|
569
|
+
object_remove(delete(descriptor))
|
494
570
|
end
|
495
571
|
}
|
496
572
|
}
|
497
573
|
end
|
498
574
|
|
575
|
+
|
576
|
+
def object_insert(object)
|
577
|
+
# noop default
|
578
|
+
end
|
579
|
+
|
580
|
+
def object_change(object)
|
581
|
+
# noop default
|
582
|
+
end
|
583
|
+
|
584
|
+
def object_remove(object)
|
585
|
+
# noop default
|
586
|
+
end
|
587
|
+
|
588
|
+
|
499
589
|
def drop
|
500
590
|
@contract.stop_sending_objects_events_to(@queue)
|
501
591
|
@queue.push [:control, :quit]
|
@@ -509,11 +599,10 @@ module Hakuban
|
|
509
599
|
def initialize(contract, descriptor)
|
510
600
|
@contract, @descriptor = contract, descriptor
|
511
601
|
end
|
512
|
-
end
|
513
|
-
|
602
|
+
end
|
514
603
|
|
515
|
-
#TODO:
|
516
|
-
|
604
|
+
#TODO: remove the arity thing...
|
605
|
+
class ObservedObject < ManagedObject
|
517
606
|
def state
|
518
607
|
if @contract.method(:object_state).arity == 1
|
519
608
|
@contract.object_state(@descriptor)
|
@@ -530,22 +619,28 @@ module Hakuban
|
|
530
619
|
end
|
531
620
|
end
|
532
621
|
|
533
|
-
|
534
|
-
def
|
622
|
+
class ExposedObject < ManagedObject
|
623
|
+
def state_set(state)
|
535
624
|
if @contract.method(:set_object_state).arity == 4
|
536
625
|
@contract.set_object_state(@descriptor, *state)
|
537
626
|
else
|
538
627
|
@contract.set_object_state(*state)
|
539
628
|
end
|
540
629
|
end
|
541
|
-
def
|
542
|
-
|
630
|
+
def state=(state)
|
631
|
+
state_set(state)
|
632
|
+
end
|
633
|
+
def data_set(value)
|
634
|
+
timestamp = Time.new.to_f
|
543
635
|
if @contract.method(:set_object_state).arity == 4
|
544
636
|
@contract.set_object_state(@descriptor,[1, timestamp.floor, ((timestamp - timestamp.floor)*1000000000).floor, 0],[],value)
|
545
637
|
else
|
546
638
|
@contract.set_object_state([1, timestamp.floor, ((timestamp - timestamp.floor)*1000000000).floor, 0],[],value)
|
547
639
|
end
|
548
640
|
end
|
641
|
+
def data=(value)
|
642
|
+
data_set(value)
|
643
|
+
end
|
549
644
|
end
|
550
645
|
end
|
551
646
|
|
data/lib/hakuban/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hakuban
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yunta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|