-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstate_machine.rb
81 lines (68 loc) · 2.13 KB
/
state_machine.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
74
75
76
77
78
79
80
81
load 'subjects.rb'
# Tabla de transiciones usada en la maquina de estados.
class TransitionTable
class TransitionError < RuntimeError
def initialize(state, input)
super "No transition from state #{state.inspect} for input #{input.inspect}"
end
end
def initialize(transitions)
@transitions = transitions
end
# Recive un estado y un input y transiciona al siguiente estado devolviendo la accion a ejecutar.
def call(state, input)
@transitions.fetch([state, input])
rescue KeyError
raise TransitionError.new(state, input)
end
end
# Maquina de estados utilizada para analizar la informacion extraida de SGA
# y crear los objetos necesarios.
class StateMachine
def initialize(transition_function, initial_state)
@transition_function = transition_function
@state = initial_state
end
attr_reader :state
# Recive un input y realiza una transicion en la maquina de estados.
def send_input(input)
@state, output = @transition_function.call(@state, input)
output
end
end
# Haciendo uso de la maquina de estados, realiza acciones segun la transicion ocurrida.
# Recive un objeto Subject y lo completa con toda la informacion necesaria.
class DataExtractor
STATE_TRANSITIONS = TransitionTable.new(
# State, Input Next state, Output
%i[q0 comision] => %i[q1 create_plan],
%i[q1 dia] => %i[q2 create_class],
%i[q2 hora] => %i[q3 append_start_hour],
%i[q3 hora] => %i[q4 append_finish_hour],
%i[q4 dia] => %i[q2 create_class],
%i[q4 comision] => %i[q1 create_plan]
)
attr_reader :subject
def initialize(subject)
@state_machine = StateMachine.new(STATE_TRANSITIONS, :q0)
@subject = subject
end
def handle_event(event, data)
action = @state_machine.send_input(event)
send(action, data) unless action.nil?
end
def create_plan(name)
@actual_plan = Plan.new(name)
@subject.add_plan(@actual_plan)
end
def create_class(day)
@actual_class = Class.new(day)
end
def append_start_hour(hour)
@actual_class.start = hour
end
def append_finish_hour(hour)
@actual_class.finish = hour
@actual_plan.add_class(@actual_class)
end
end