MINT-core 1.0.0
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.
- data/.gemtest +0 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +69 -0
- data/History.txt +3 -0
- data/MINT-core.gemspec +58 -0
- data/Manifest.txt +77 -0
- data/PostInstall.txt +7 -0
- data/README.rdoc +63 -0
- data/Rakefile +29 -0
- data/bin/mint-aui +40 -0
- data/bin/mint-cui-gfx +47 -0
- data/bin/mint-juggernaut.sh +4 -0
- data/bin/mint-tuplespace +12 -0
- data/lib/MINT-core.rb +42 -0
- data/lib/MINT-core/agent/agent.rb +28 -0
- data/lib/MINT-core/agent/aui.rb +52 -0
- data/lib/MINT-core/agent/auicontrol.rb +135 -0
- data/lib/MINT-core/agent/cui-gfx.rb +160 -0
- data/lib/MINT-core/agent/cuicontrol.rb +46 -0
- data/lib/MINT-core/mapping/complementary.rb +100 -0
- data/lib/MINT-core/mapping/mapping.rb +47 -0
- data/lib/MINT-core/mapping/on_state_change.rb +65 -0
- data/lib/MINT-core/mapping/sequential.rb +87 -0
- data/lib/MINT-core/model/aui/AIC.rb +86 -0
- data/lib/MINT-core/model/aui/AIChoice.rb +65 -0
- data/lib/MINT-core/model/aui/AIINChoose.rb +54 -0
- data/lib/MINT-core/model/aui/AIMultiChoice.rb +5 -0
- data/lib/MINT-core/model/aui/AIMultiChoiceElement.rb +56 -0
- data/lib/MINT-core/model/aui/AIO.rb +170 -0
- data/lib/MINT-core/model/aui/AIOUTDiscrete.rb +43 -0
- data/lib/MINT-core/model/aui/AISingleChoice.rb +9 -0
- data/lib/MINT-core/model/aui/AISingleChoiceElement.rb +69 -0
- data/lib/MINT-core/model/aui/AISinglePresence.rb +100 -0
- data/lib/MINT-core/model/aui/aic.png +0 -0
- data/lib/MINT-core/model/aui/aic.scxml +50 -0
- data/lib/MINT-core/model/aui/aichoice.png +0 -0
- data/lib/MINT-core/model/aui/aichoice.scxml +60 -0
- data/lib/MINT-core/model/aui/aio.png +0 -0
- data/lib/MINT-core/model/aui/aio.scxml +43 -0
- data/lib/MINT-core/model/aui/aisinglechoiceelement.png +0 -0
- data/lib/MINT-core/model/aui/aisinglechoiceelement.scxml +71 -0
- data/lib/MINT-core/model/aui/aisinglepresence.png +0 -0
- data/lib/MINT-core/model/aui/aisinglepresence.scxml +58 -0
- data/lib/MINT-core/model/aui/model.rb +50 -0
- data/lib/MINT-core/model/body/gesture_button.rb +26 -0
- data/lib/MINT-core/model/body/handgesture.rb +279 -0
- data/lib/MINT-core/model/body/head.png +0 -0
- data/lib/MINT-core/model/body/head.rb +51 -0
- data/lib/MINT-core/model/body/head.scxml +28 -0
- data/lib/MINT-core/model/cui/gfx/CIC.rb +266 -0
- data/lib/MINT-core/model/cui/gfx/CIO.rb +381 -0
- data/lib/MINT-core/model/cui/gfx/model.rb +204 -0
- data/lib/MINT-core/model/cui/gfx/screen.rb +18 -0
- data/lib/MINT-core/model/device/button.rb +20 -0
- data/lib/MINT-core/model/device/joypad.rb +30 -0
- data/lib/MINT-core/model/device/mouse.rb +171 -0
- data/lib/MINT-core/model/device/pointer.rb +85 -0
- data/lib/MINT-core/model/device/wheel.rb +51 -0
- data/lib/MINT-core/model/interactor.rb +167 -0
- data/lib/MINT-core/model/task.rb +71 -0
- data/lib/MINT-core/overrides/rinda.rb +34 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/AIC_spec.rb +69 -0
- data/spec/AISinglePresence_spec.rb +94 -0
- data/spec/MINT-core_spec.rb +11 -0
- data/spec/aio_agent_spec.rb +234 -0
- data/spec/aio_spec.rb +144 -0
- data/spec/aisinglechoice_spec.rb +152 -0
- data/spec/aisinglechoiceelement_spec.rb +106 -0
- data/spec/cio_spec.rb +369 -0
- data/spec/core_spec.rb +29 -0
- data/spec/music_spec.rb +179 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +7 -0
- data/tasks/rspec.rake +21 -0
- metadata +227 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
module MINT
|
2
|
+
class Pointer < Element
|
3
|
+
property :x, Integer, :default => -1
|
4
|
+
property :y, Integer, :default => -1
|
5
|
+
|
6
|
+
def initialize_statemachine
|
7
|
+
if @statemachine.blank?
|
8
|
+
@statemachine = Statemachine.build do
|
9
|
+
|
10
|
+
trans :disconnected,:connect, :connected
|
11
|
+
trans :connected, :disconnect, :disconnected
|
12
|
+
|
13
|
+
superstate :connected do
|
14
|
+
trans :stopped, :move, :moving
|
15
|
+
trans :moving,:move, :moving
|
16
|
+
trans :moving,:stop,:stopped
|
17
|
+
|
18
|
+
state :moving do
|
19
|
+
on_entry :start_timeout
|
20
|
+
on_exit :stop_timeout
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def cache_coordinates(x,y)
|
28
|
+
@cached_x = x
|
29
|
+
@cached_y = y
|
30
|
+
end
|
31
|
+
|
32
|
+
def start_timeout
|
33
|
+
if not @timer
|
34
|
+
@timer = EventMachine::Timer.new(0.1) do
|
35
|
+
attribute_set(:x, @cached_x)
|
36
|
+
attribute_set(:y, @cached_y)
|
37
|
+
|
38
|
+
process_event("stop")
|
39
|
+
|
40
|
+
end
|
41
|
+
else
|
42
|
+
puts "timer already started!!!"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def stop_timeout
|
46
|
+
if @timer
|
47
|
+
@timer.cancel
|
48
|
+
@timer = nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def restart_timeout
|
52
|
+
stop_timeout
|
53
|
+
start_timeout
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Pointer3D < Pointer
|
58
|
+
property :z, Integer, :default => -1
|
59
|
+
attr_accessor :cached_x, :cached_y,:cached_z
|
60
|
+
|
61
|
+
def cache_coordinates(x,y,z=nil)
|
62
|
+
@cached_x = x if (x)
|
63
|
+
@cached_y = y if (y)
|
64
|
+
@cached_z = z if (z)
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
def start_timeout
|
70
|
+
if not @timer
|
71
|
+
@timer = EventMachine::Timer.new(0.1) do
|
72
|
+
attribute_set(:x, @cached_x)
|
73
|
+
attribute_set(:y, @cached_y)
|
74
|
+
attribute_set(:z, @cached_z)
|
75
|
+
|
76
|
+
process_event("stop")
|
77
|
+
|
78
|
+
end
|
79
|
+
else
|
80
|
+
puts "timer already started!!!"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module MINT
|
2
|
+
class Wheel < Element
|
3
|
+
|
4
|
+
def initialize_statemachine
|
5
|
+
if @statemachine.blank?
|
6
|
+
@statemachine = Statemachine.build do
|
7
|
+
|
8
|
+
trans :disconnected,:connect, :connected
|
9
|
+
trans :connected, :disconnect, :disconnected
|
10
|
+
|
11
|
+
superstate :connected do
|
12
|
+
trans :stopped,:regress, :regressing
|
13
|
+
trans :stopped,:progress, :progressing
|
14
|
+
|
15
|
+
trans :regressing, :regress, :regressing
|
16
|
+
trans :regressing, :stop, :stopped
|
17
|
+
trans :regressing, :progress, :progressing
|
18
|
+
|
19
|
+
trans :progressing, :progress, :progressing
|
20
|
+
trans :progressing, :stop, :stopped
|
21
|
+
trans :progressing, :regress, :regressing
|
22
|
+
|
23
|
+
state :regressing do
|
24
|
+
on_entry :start_timeout
|
25
|
+
on_exit :stop_timeout
|
26
|
+
end
|
27
|
+
state :progressing do
|
28
|
+
on_entry :start_timeout
|
29
|
+
on_exit :stop_timeout
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
def start_timeout
|
36
|
+
if not @timer
|
37
|
+
@timer = EventMachine::Timer.new(0.3) do
|
38
|
+
process_event("stop")
|
39
|
+
end
|
40
|
+
else
|
41
|
+
puts "timer already started!!!"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
def stop_timeout
|
45
|
+
if @timer
|
46
|
+
@timer.cancel
|
47
|
+
@timer = nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module MINT
|
2
|
+
# An {Element} is the basic abstract element of the complete MINT markup language. Nearly all other
|
3
|
+
# classes are derived from {MINT::Element} since early everything can be activated by {#state} and has
|
4
|
+
# a {#name}.
|
5
|
+
#
|
6
|
+
class Element
|
7
|
+
include DataMapper::Resource
|
8
|
+
private
|
9
|
+
property :id, Serial
|
10
|
+
property :classtype, Discriminator
|
11
|
+
|
12
|
+
# Each abstract {Element} needs to have a name that we will use as the primary key for each model.
|
13
|
+
property :name, String
|
14
|
+
|
15
|
+
# States of the {Element} Reflects the actual atomic states of the interactors state machine.
|
16
|
+
property :states, String
|
17
|
+
|
18
|
+
# reflects all active states including abstract superstates of an interactor as a |-seperated state id list
|
19
|
+
property :abstract_states, String
|
20
|
+
|
21
|
+
#always contains the new atomic states that have been entered by the event that has been processed - especially useful for parallel states
|
22
|
+
property :new_states, String
|
23
|
+
|
24
|
+
protected
|
25
|
+
before :save, :save_statemachine
|
26
|
+
|
27
|
+
public
|
28
|
+
|
29
|
+
def to_dot(filename)
|
30
|
+
if not @statemachine
|
31
|
+
initialize_statemachine
|
32
|
+
end
|
33
|
+
@statemachine.to_dot(:output => filename)
|
34
|
+
end
|
35
|
+
def states
|
36
|
+
if not @statemachine
|
37
|
+
initialize_statemachine
|
38
|
+
recover_statemachine
|
39
|
+
end
|
40
|
+
@statemachine.states_id
|
41
|
+
end
|
42
|
+
|
43
|
+
def new_states
|
44
|
+
if attribute_get(:new_states)
|
45
|
+
return attribute_get(:new_states).split("|").map &:to_sym if attribute_get(:new_states).class!=Array
|
46
|
+
return attribute_get(:new_states)
|
47
|
+
else return []
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def states= states
|
52
|
+
if not @statemachine # if called on element creation using the states hash!
|
53
|
+
initialize_statemachine
|
54
|
+
end
|
55
|
+
@statemachine.states=states
|
56
|
+
save_statemachine
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(attributes = {}, &block)
|
60
|
+
super(attributes, &block)
|
61
|
+
recover_statemachine
|
62
|
+
end
|
63
|
+
|
64
|
+
# The sync event method is overwritten in the derived classes to prevent synchronization cycles by setting an empty callback
|
65
|
+
def sync_event(event)
|
66
|
+
process_event(event)
|
67
|
+
end
|
68
|
+
|
69
|
+
def process_event(event, callback=nil)
|
70
|
+
|
71
|
+
states = process_event!(event,callback)
|
72
|
+
if states
|
73
|
+
save_statemachine
|
74
|
+
states
|
75
|
+
else
|
76
|
+
false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def process_event!(event, callback=nil)
|
81
|
+
if not @statemachine
|
82
|
+
initialize_statemachine
|
83
|
+
recover_statemachine
|
84
|
+
end
|
85
|
+
if callback
|
86
|
+
@statemachine.context = callback
|
87
|
+
else
|
88
|
+
@statemachine.context = self
|
89
|
+
end
|
90
|
+
begin
|
91
|
+
old_states = @statemachine.states_id
|
92
|
+
old_abstract_states = @statemachine.abstract_states
|
93
|
+
@statemachine.process_event(event)
|
94
|
+
calc_new_states = @statemachine.states_id-old_states
|
95
|
+
calc_new_states = calc_new_states + (@statemachine.abstract_states - old_abstract_states)
|
96
|
+
calc_new_states = @statemachine.states_id if calc_new_states.length==0
|
97
|
+
attribute_set(:new_states, calc_new_states.join('|'))
|
98
|
+
rescue Statemachine::TransitionMissingException
|
99
|
+
p "#{self.name} is in state #{self.states} and could not handle #{event}"
|
100
|
+
return false
|
101
|
+
end
|
102
|
+
@statemachine.states_id
|
103
|
+
end
|
104
|
+
|
105
|
+
def is_in?(state)
|
106
|
+
if not @statemachine
|
107
|
+
initialize_statemachine
|
108
|
+
recover_statemachine
|
109
|
+
end
|
110
|
+
@statemachine.In(state)
|
111
|
+
end
|
112
|
+
protected
|
113
|
+
def initialize_statemachine
|
114
|
+
if @statemachine.blank?
|
115
|
+
@statemachine = Statemachine.build do
|
116
|
+
trans :initialized, :run, :running
|
117
|
+
trans :running, :done, :finished
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def save_statemachine
|
125
|
+
if not @statemachine
|
126
|
+
initialize_statemachine
|
127
|
+
recover_statemachine
|
128
|
+
end
|
129
|
+
attribute_set(:states, @statemachine.states_id.join('|'))
|
130
|
+
attribute_set(:abstract_states, @statemachine.abstract_states.concat(@statemachine.states_id).join('|'))
|
131
|
+
# attribute_set(:new_states,new_states) if new_states and new_states.length>0 # second condition to
|
132
|
+
save!
|
133
|
+
end
|
134
|
+
|
135
|
+
# @TODO check this for parallel states!
|
136
|
+
def recover_statemachine
|
137
|
+
if (@statemachine.blank?)
|
138
|
+
initialize_statemachine
|
139
|
+
end
|
140
|
+
if attribute_get(:states)
|
141
|
+
if attribute_get(:states).is_a? Array # @TODO this should not occur!!
|
142
|
+
@statemachine.states=attribute_get(:states)
|
143
|
+
else
|
144
|
+
@statemachine.states=attribute_get(:states).split('|').map &:intern
|
145
|
+
end
|
146
|
+
|
147
|
+
else
|
148
|
+
attribute_set(:states, @statemachine.states_id.join('|'))
|
149
|
+
attribute_set(:abstract_states, @statemachine.abstract_states.concat(@statemachine.states_id).join('|'))
|
150
|
+
end
|
151
|
+
if not attribute_get(:new_states)
|
152
|
+
attribute_set(:new_states, @statemachine.states_id.join('|'))
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def is_set(attribute)
|
157
|
+
self.attribute_get(attribute)!=nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class IR <Element
|
162
|
+
end
|
163
|
+
|
164
|
+
class IN < IR
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module MINT
|
2
|
+
# TASK MODEL
|
3
|
+
|
4
|
+
|
5
|
+
# A {Task} defines the basic control flow object, has a {#parent} task, unless it's the root task and a textual,
|
6
|
+
# unstructured {#description}.
|
7
|
+
#
|
8
|
+
class Task < Element
|
9
|
+
# belongs_to :parent, "Task"
|
10
|
+
property :description, Text
|
11
|
+
|
12
|
+
def initialize_statemachine
|
13
|
+
if @statemachine.blank?
|
14
|
+
|
15
|
+
@statemachine = Statemachine.build do
|
16
|
+
trans :initialized, :run, :running
|
17
|
+
trans :running, :stop, :done
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# Each {InteractionTask} is linked to one abstract interaction container
|
25
|
+
# {MINT::AIC}
|
26
|
+
#
|
27
|
+
class InteractionTask < Task
|
28
|
+
# has 1, :AIC @TODO - Mappings unklar
|
29
|
+
belongs_to :pts, "PTS"
|
30
|
+
end
|
31
|
+
|
32
|
+
# An {ApplicationTask} is completely executed by the computer without any human intervention
|
33
|
+
# through it's internal processing. An {ApplicationTask} can generate or manipulate
|
34
|
+
# Domain objects through it's internal processing. The {ApplicationTask} is used to model service
|
35
|
+
# calls to the functional core of the application or it can enable other {Task}s if it is used to model
|
36
|
+
# sensor information.
|
37
|
+
#
|
38
|
+
class ApplicationTask < Task
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# {InputInteractionTask}s describe {Task}s realizing some interaction techniques to enable the user
|
43
|
+
# interacting with the system. {InputInteractionTask}s include selecting objects, editing data or enabling the
|
44
|
+
# user to control some actions explicitly through events. If an {InputInteractionTask} is marked as synchronous
|
45
|
+
# it has to contain at least one control object that the user can issue to proceed the {Task}.
|
46
|
+
#
|
47
|
+
class InputInteractionTask < InteractionTask
|
48
|
+
end
|
49
|
+
|
50
|
+
# {OutputInteractionTask}s present information to the user. This could be raw structured data like documents or tables
|
51
|
+
# or multimedia output such as video or sound. [OutputInteractionTask}s read the objects that are associated with
|
52
|
+
# the task once if the are marked as synchronous or until they get disabled by another {ApplicationTask}'s or an
|
53
|
+
# {InputInteractionTask} if they are marked as asynchronous.
|
54
|
+
#
|
55
|
+
class OutputInteractionTask < InteractionTask
|
56
|
+
end
|
57
|
+
|
58
|
+
# A Presentation Task set {PTS} contains a set of active interaction tasks that should be presented or manipulated by the
|
59
|
+
# user
|
60
|
+
#
|
61
|
+
class PTS < Element
|
62
|
+
def initialize_statemachine
|
63
|
+
if @statemachine.blank?
|
64
|
+
@statemachine = Statemachine.build do
|
65
|
+
trans :initialized, :calculate, :calculating
|
66
|
+
trans :calculating, :done, :finished
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "rinda/tuplespace"
|
2
|
+
|
3
|
+
module Rinda
|
4
|
+
class TupleSpace
|
5
|
+
def take_all(tuple)
|
6
|
+
read_all(tuple).each { |t|
|
7
|
+
take(t)
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
# fixed Templates to support partially matching
|
15
|
+
class Template
|
16
|
+
def match(tuple)
|
17
|
+
return false unless tuple.respond_to?(:size)
|
18
|
+
return false unless tuple.respond_to?(:fetch)
|
19
|
+
return false unless self.size <= tuple.size
|
20
|
+
each do |k, v|
|
21
|
+
begin
|
22
|
+
it = tuple.fetch(k)
|
23
|
+
rescue
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
next if v.nil?
|
27
|
+
next if v == it
|
28
|
+
next if v === it
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
return true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/MINT-core.rb'}"
|
9
|
+
puts "Loading MINT-core gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|