Class: Hakuban::ObjectManager

Inherits:
Object
  • Object
show all
Defined in:
lib/hakuban/manager.rb

Direct Known Subclasses

AsyncObjectManager, ThreadObjectManager

Defined Under Namespace

Classes: Event

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(contract, object_class, block) ⇒ ObjectManager

Returns a new instance of ObjectManager.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/hakuban/manager.rb', line 15

def initialize(contract, object_class, block)
	@contract = contract
	@objects_mutex = Mutex.new
	@objects = {}
	@running_handlers = {}
	@event_queue = Queue.new

	# This callback gets called from a separate thread, with no async reactor running.
	# So, we only use it to forward actions to the main thread.
	@ffi_callback = proc { |descriptor, action|
		@event_queue << Event.new(action: action, descriptor: descriptor)
	}
	@ffi_events = @contract.new_callback_event_queue
	@ffi_events.callback_register(&@ffi_callback)

	@async = async_run {
		while @event_queue and event = @event_queue.shift
			@objects_mutex.synchronize {
				case event.action
				when :insert
					raise  if @objects[event.descriptor]
					@objects[event.descriptor] = object_class.new(@contract, event.descriptor)
					@event_queue << Event.new(action: :handler_start, descriptor: event.descriptor)  if block
				when :change
					raise  if not @objects[event.descriptor]
					@objects[event.descriptor].do_change(:change)
				when :remove
					raise  if not @objects[event.descriptor]
					@objects[event.descriptor].do_change(:remove)
					@objects.delete(event.descriptor)
				when :handler_start
					if (object = @objects[event.descriptor]) and !object.handler_already_run and !@running_handlers[event.descriptor]
						descriptor_for_lambda = event.descriptor	
						@running_handlers[event.descriptor] = async_run {
							object.run(block)
							@event_queue << Event.new(action: :handler_finished, descriptor: descriptor_for_lambda)  if @event_queue
						}
					end
				when :handler_finished
					raise  if not @running_handlers[event.descriptor]
					@running_handlers.delete(event.descriptor)
					@event_queue << Event.new(action: :handler_start, descriptor: event.descriptor)  if @objects[event.descriptor]
				when :drop
					@ffi_events.callback_unregister
					@objects.values.each { |object| object.do_change(:remove) }
					while @running_handlers.size > 0
						event = @event_queue.shift
						@running_handlers.delete(event.descriptor)  if event.action == :handler_finished
					end
					@event_queue.clear
					@objects.clear
					@contract.drop
					@contract, @event_queue = nil, nil
					break
				end
			}
		end
	}
end

Instance Attribute Details

#contractObject (readonly)

Returns the value of attribute contract.



11
12
13
# File 'lib/hakuban/manager.rb', line 11

def contract
  @contract
end

Instance Method Details

#dropObject



90
91
92
93
# File 'lib/hakuban/manager.rb', line 90

def drop
	drop_nonblock
	async_join(@async)
end

#drop_nonblockObject



96
97
98
99
100
# File 'lib/hakuban/manager.rb', line 96

def drop_nonblock
	if @contract
		@event_queue << Event.new(action: :drop)
	end
end

#objectObject



83
84
85
86
87
# File 'lib/hakuban/manager.rb', line 83

def object
	@objects_mutex.synchronize {
		@objects.values.first
	}
end

#objectsObject



76
77
78
79
80
# File 'lib/hakuban/manager.rb', line 76

def objects
	@objects_mutex.synchronize {
		@objects.dup
	}
end