phenomenal 0.9.0 → 0.11.11.24.3
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/LICENSE +1 -1
- data/README +4 -3
- data/Rakefile +0 -3
- data/demo.rb +24 -0
- data/demo_age.rb +89 -0
- data/demo_dsl.rb +28 -0
- data/lib/phenomenal.rb +2 -15
- data/lib/phenomenal/adaptation.rb +12 -22
- data/lib/phenomenal/context.rb +134 -127
- data/lib/phenomenal/dsl.rb +14 -41
- data/lib/phenomenal/logger.rb +1 -0
- data/lib/phenomenal/manager.rb +35 -117
- data/phenomenal.gemspec +15 -0
- data/{spec → test}/test_classes.rb +0 -3
- data/test/test_cop_adaptation.rb +168 -0
- data/test/test_cop_composition.rb +84 -0
- data/test/test_cop_conflictpolicy.rb +177 -0
- data/test/test_cop_infrastructure.rb +129 -0
- data/test_declaration.rb +18 -0
- metadata +29 -70
- data/lib/phenomenal/feature.rb +0 -8
- data/lib/phenomenal/relationships/context_relationships.rb +0 -22
- data/lib/phenomenal/relationships/dsl.rb +0 -18
- data/lib/phenomenal/relationships/feature_relationships.rb +0 -42
- data/lib/phenomenal/relationships/implication.rb +0 -35
- data/lib/phenomenal/relationships/relationship.rb +0 -42
- data/lib/phenomenal/relationships/relationships_manager.rb +0 -63
- data/lib/phenomenal/relationships/relationships_store.rb +0 -73
- data/lib/phenomenal/relationships/requirement.rb +0 -26
- data/lib/phenomenal/relationships/suggestion.rb +0 -41
- data/lib/phenomenal/version.rb +0 -3
- data/spec/adaptation_spec.rb +0 -64
- data/spec/behavior/adaptation_spec.rb +0 -5
- data/spec/behavior/combined_contexts_spec.rb +0 -5
- data/spec/behavior/composition_spec.rb +0 -5
- data/spec/behavior/conflict_policy_spec.rb +0 -5
- data/spec/behavior/open_context.rb +0 -5
- data/spec/behavior/relationships_spec.rb +0 -249
- data/spec/context_spec.rb +0 -268
- data/spec/dsl_spec.rb +0 -181
- data/spec/feature_spec.rb +0 -5
- data/spec/manager_spec.rb +0 -84
- data/spec/proc_spec.rb +0 -20
- data/spec/relationships/context_relationships_spec.rb +0 -13
- data/spec/relationships/dsl_spec.rb +0 -13
- data/spec/relationships/feature_relationships_spec.rb +0 -13
- data/spec/relationships/relationship_spec.rb +0 -31
- data/spec/relationships/relationships_manager_spec.rb +0 -15
- data/spec/relationships/relationships_store_spec.rb +0 -19
- data/spec/spec_helper.rb +0 -18
data/LICENSE
CHANGED
data/README
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
Build gem command:
|
2
|
+
gem build phenomenal.gemspec
|
3
|
+
Test gem command:
|
4
|
+
rake test
|
data/Rakefile
CHANGED
data/demo.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'lib/phenomenal.rb'
|
2
|
+
class Foo
|
3
|
+
def initialize
|
4
|
+
@inst_var = "bar"
|
5
|
+
end
|
6
|
+
def print
|
7
|
+
"Base: " +@inst_var
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
pnml_define_context(:demo)
|
12
|
+
pnml_add_adaptation(:demo, Foo, :print) do
|
13
|
+
pnml_proceed + " adaptation: "+ @inst_var
|
14
|
+
end
|
15
|
+
|
16
|
+
f = Foo.new
|
17
|
+
puts f.print
|
18
|
+
|
19
|
+
pnml_activate_context(:demo)
|
20
|
+
puts f.print
|
21
|
+
|
22
|
+
pnml_deactivate_context(:demo)
|
23
|
+
puts f.print
|
24
|
+
|
data/demo_age.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require_relative "./lib/phenomenal.rb"
|
2
|
+
|
3
|
+
pnml_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
|
4
|
+
|
5
|
+
class Plop
|
6
|
+
@@klass_var = "PPPP"
|
7
|
+
@klass_inst_var = "xD"
|
8
|
+
attr_accessor :test
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@test = ">BOR<"
|
12
|
+
end
|
13
|
+
|
14
|
+
def print(arg)
|
15
|
+
"0 -> Test: #{self.test} default Plop.print(arg): ARG: #{arg.to_s}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.plop(arg)
|
19
|
+
"SELF 0 #{arg} KlassVar: #{@@klass_var} INSTKLS #{@klass_inst_var}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
pnml_define_context(:level1)
|
24
|
+
|
25
|
+
pnml_add_adaptation(:level1,Plop,:print) do |arg|
|
26
|
+
pnml_proceed(arg) + "\n" + "1 -> level1 ARG1: #{arg.to_s}"
|
27
|
+
end
|
28
|
+
|
29
|
+
pnml_add_adaptation(:level1,Plop,:plop) do |arg|
|
30
|
+
pnml_proceed(arg) + "\n" + "1 -> SELF level1 ARG1: #{arg.to_s} INSTKLS #{@kls_var}"
|
31
|
+
end
|
32
|
+
|
33
|
+
pnml_define_context(:level2)
|
34
|
+
|
35
|
+
pnml_add_adaptation(:level2,Plop,:print) do |arg|
|
36
|
+
pnml_proceed(arg) + "\n" + "2 -> level2 ARG2: #{arg.to_s}"
|
37
|
+
end
|
38
|
+
|
39
|
+
pnml_add_adaptation(:level2,Plop,:plop) do |arg|
|
40
|
+
pnml_proceed(arg) + "\n" + "2 -> SELF level2 ARG2: #{arg.to_s} INSTKLS #{@kls_inst_var}"
|
41
|
+
end
|
42
|
+
|
43
|
+
pnml_define_context(:level3)
|
44
|
+
|
45
|
+
pnml_add_adaptation(:level3,Plop,:print) do |arg|
|
46
|
+
pnml_proceed(arg) + "\n" + "3 -> level3 ARG3: #{arg.to_s}"
|
47
|
+
end
|
48
|
+
|
49
|
+
pnml_define_context(:level4)
|
50
|
+
|
51
|
+
pnml_add_adaptation(:level4,Plop,:print) do |arg|
|
52
|
+
pnml_proceed(arg) + "\n" + "4 -> TEST4: #{@test} level4 ARG4: #{arg.to_s}"
|
53
|
+
end
|
54
|
+
|
55
|
+
p = Plop.new
|
56
|
+
|
57
|
+
puts "=============> LEVEL 0 <===============\n"+
|
58
|
+
p.print("foo")+
|
59
|
+
"\n======================================="
|
60
|
+
|
61
|
+
pnml_activate_context(:level1)
|
62
|
+
puts "=============> LEVEL 1 <===============\n"+
|
63
|
+
p.print("foo1")+
|
64
|
+
"\n======================================="
|
65
|
+
|
66
|
+
pnml_activate_context(:level2)
|
67
|
+
puts "=============> LEVEL 2 <===============\n"+
|
68
|
+
p.print("foo2")+
|
69
|
+
"\n======================================="
|
70
|
+
|
71
|
+
pnml_activate_context(:level3)
|
72
|
+
puts "=============> LEVEL 3 <===============\n"+
|
73
|
+
p.print("foo3")+
|
74
|
+
"\n======================================="
|
75
|
+
p.test=">BAR<"
|
76
|
+
pnml_activate_context(:level4)
|
77
|
+
puts "=============> LEVEL 4 <===============\n"+
|
78
|
+
p.print("foo4")+
|
79
|
+
"\n======================================="
|
80
|
+
|
81
|
+
pnml_deactivate_context(:level3)
|
82
|
+
puts "=============> LEVEL 4 -3 <===============\n"+
|
83
|
+
p.print("foo4-2")+
|
84
|
+
"\n======================================="
|
85
|
+
|
86
|
+
puts "\n\n========> LEVEL 4 -3 KLASS METH<===========\n"+
|
87
|
+
Plop.plop(">KLASS_METH_ARG<") +
|
88
|
+
"\n======================================="
|
89
|
+
|
data/demo_dsl.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'lib/phenomenal.rb'
|
2
|
+
class Foo
|
3
|
+
def initialize
|
4
|
+
@inst_var = "bar"
|
5
|
+
end
|
6
|
+
def print
|
7
|
+
"Base: " +@inst_var
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context :Test do
|
12
|
+
implies :plop
|
13
|
+
|
14
|
+
adaptations_for Foo
|
15
|
+
adapt :print do
|
16
|
+
pnml_proceed + "ADAPT"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
f = Foo.new
|
21
|
+
puts f.print
|
22
|
+
|
23
|
+
pnml_activate_context(:Test)
|
24
|
+
puts f.print
|
25
|
+
|
26
|
+
pnml_deactivate_context(:Test)
|
27
|
+
puts f.print
|
28
|
+
|
data/lib/phenomenal.rb
CHANGED
@@ -1,24 +1,11 @@
|
|
1
1
|
# Load the gem files in the system
|
2
2
|
module Phenomenal end
|
3
|
-
#Relationships
|
4
|
-
require_relative "./phenomenal/relationships/context_relationships.rb"
|
5
|
-
require_relative "./phenomenal/relationships/feature_relationships.rb"
|
6
|
-
require_relative "./phenomenal/relationships/relationships_store.rb"
|
7
|
-
require_relative "./phenomenal/relationships/relationships_manager.rb"
|
8
|
-
require_relative "./phenomenal/relationships/relationship.rb"
|
9
|
-
require_relative "./phenomenal/relationships/requirement.rb"
|
10
|
-
require_relative "./phenomenal/relationships/implication.rb"
|
11
|
-
require_relative "./phenomenal/relationships/suggestion.rb"
|
12
|
-
|
13
|
-
# Core
|
14
3
|
require_relative "./phenomenal/adaptation.rb"
|
15
4
|
require_relative "./phenomenal/conflict_policies.rb"
|
16
5
|
require_relative "./phenomenal/context.rb"
|
17
|
-
require_relative "./phenomenal/feature.rb"
|
18
6
|
require_relative "./phenomenal/logger.rb"
|
19
7
|
require_relative "./phenomenal/manager.rb"
|
20
8
|
require_relative "./phenomenal/proc.rb"
|
21
|
-
|
22
|
-
# DSL
|
23
|
-
require_relative "./phenomenal/relationships/dsl.rb"
|
24
9
|
require_relative "./phenomenal/dsl.rb"
|
10
|
+
|
11
|
+
|
@@ -1,16 +1,14 @@
|
|
1
1
|
# Represent a method adaptation for a particular context
|
2
2
|
class Phenomenal::Adaptation
|
3
3
|
attr_accessor :context, :klass, :method_name, :implementation, :src_file,
|
4
|
-
:src_line
|
4
|
+
:src_line
|
5
5
|
|
6
|
-
def initialize(context,klass, method_name,
|
6
|
+
def initialize(context,klass, method_name, implementation)
|
7
7
|
@context = context
|
8
8
|
@klass = klass
|
9
9
|
@method_name = method_name
|
10
10
|
@implementation = implementation
|
11
|
-
@instance_adaptation=instance_adapatation
|
12
11
|
|
13
|
-
check_validity
|
14
12
|
# Save the source location if any, this is used to find again the adaptation
|
15
13
|
# in a ctxt_proceed call. It always exists except for method directly
|
16
14
|
# implemented in C -> Not a problem because these one never use ctxt_proceed
|
@@ -33,7 +31,9 @@ class Phenomenal::Adaptation
|
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
36
|
-
#
|
34
|
+
#TODO check for better implem
|
35
|
+
#TODO we are forced to keep unBoundMethod bind code,
|
36
|
+
# so allow user to use unbound meth?
|
37
37
|
# Bind the implementation corresponding to this adaptation to 'instance' when
|
38
38
|
# instance_method or to implementation klass when class method
|
39
39
|
def bind(instance,*args,&block)
|
@@ -52,28 +52,18 @@ class Phenomenal::Adaptation
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
# True if the adapted method is an instance method
|
56
|
+
def instance_adaptation?
|
57
|
+
klass.instance_methods.include?(method_name)
|
58
|
+
end
|
59
|
+
|
55
60
|
#True if the adaptation concern the class n_klass and method n_method
|
56
|
-
def concern?(klass,method_name
|
57
|
-
self.klass==klass &&
|
58
|
-
self.method_name==method_name &&
|
59
|
-
self.instance_adaptation==instance_adaptation
|
61
|
+
def concern?(klass,method_name)
|
62
|
+
self.klass==klass && self.method_name==method_name
|
60
63
|
end
|
61
64
|
|
62
|
-
alias_method :instance_adaptation?, :instance_adaptation
|
63
|
-
|
64
65
|
# String representation
|
65
66
|
def to_s
|
66
67
|
":#{context.name} => #{klass.name}.#{method_name} :: #{src_file}:#{src_line}"
|
67
68
|
end
|
68
|
-
|
69
|
-
private
|
70
|
-
def check_validity
|
71
|
-
if klass.instance_methods.include?(method_name) && !instance_adaptation? ||
|
72
|
-
!klass.instance_methods.include?(method_name) && instance_adaptation?
|
73
|
-
Phenomenal::Logger.instance.error(
|
74
|
-
"Illegal adaptation for context: #{context}" +
|
75
|
-
" for #{klass.name}.#{method_name}, type mismatch"
|
76
|
-
)
|
77
|
-
end
|
78
|
-
end
|
79
69
|
end
|
data/lib/phenomenal/context.rb
CHANGED
@@ -1,72 +1,47 @@
|
|
1
1
|
# Represent a first class context
|
2
2
|
class Phenomenal::Context
|
3
|
-
include Phenomenal::ContextRelationships
|
4
3
|
@@total_activations = 0
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
context = self.new(context)
|
11
|
-
else
|
12
|
-
context = manager.find_context(context)
|
13
|
-
if !context.instance_of?(self)
|
14
|
-
Phenomenal::Logger.instance.error(
|
15
|
-
"Only #{self.name} can be used with this keyword"
|
16
|
-
)
|
17
|
-
end
|
4
|
+
|
5
|
+
def self.create(*args,&block)
|
6
|
+
if args.length==1
|
7
|
+
if !Phenomenal::Manager.instance.context_defined?(args[0])
|
8
|
+
context = Phenomenal::Context.new(args[0])
|
18
9
|
end
|
10
|
+
context.add_adaptations(&block)
|
19
11
|
else #Combined contexts
|
20
|
-
|
21
|
-
context = self.new
|
22
|
-
context.parent=closest_feature # Set parent
|
23
|
-
instances = Array.new
|
24
|
-
first = contexts.first
|
25
|
-
contexts.each do |c|
|
26
|
-
# Use the object instance if already available
|
27
|
-
# otherwise create it
|
28
|
-
if manager.context_defined?(c)
|
29
|
-
c = manager.find_context(c)
|
30
|
-
if !nested && c!=first && !c.instance_of?(self)
|
31
|
-
Phenomenal::Logger.instance.error(
|
32
|
-
"Only #{self.name} can be used with this keyword"
|
33
|
-
)
|
34
|
-
end
|
35
|
-
else
|
36
|
-
c = self.new(c)
|
37
|
-
end
|
38
|
-
instances.push(c)
|
39
|
-
manager.shared_contexts[c]= Array.new if !manager.shared_contexts[c]
|
40
|
-
manager.shared_contexts[c].push(context)
|
41
|
-
end
|
42
|
-
manager.combined_contexts[context] = instances
|
43
|
-
else
|
44
|
-
context = manager.find_context(*contexts)
|
45
|
-
end
|
12
|
+
#TODO
|
46
13
|
end
|
47
|
-
context.add_adaptations(&block)
|
48
|
-
context
|
49
14
|
end
|
50
15
|
|
51
|
-
|
52
|
-
|
16
|
+
def self.create_feature(*args,&block)
|
17
|
+
context = self.create(*args,&block)
|
18
|
+
context.persistent=true
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :activation_age, :activation_frequency, :priority, :adaptations,
|
22
|
+
:activation_count, :persistent, :required, :implied, :guessed, :is_implied, :is_required
|
53
23
|
attr_reader :manager,:name
|
54
24
|
|
55
|
-
def initialize(name=nil, manager=nil)
|
25
|
+
def initialize(name=nil, priority=nil,persistent=false,manager=nil)
|
26
|
+
@persistent = persistent
|
56
27
|
@manager = manager || Phenomenal::Manager.instance
|
57
28
|
@name = name
|
29
|
+
@priority = priority
|
58
30
|
@activation_age = 0
|
59
31
|
@activation_count = 0
|
60
32
|
@adaptations = Array.new
|
61
33
|
@manager.register_context(self)
|
62
|
-
@
|
63
|
-
@
|
34
|
+
@implied = Array.new
|
35
|
+
@is_implied = {}
|
36
|
+
@required = Array.new
|
37
|
+
@is_required = {}
|
38
|
+
@guessed = Array.new
|
64
39
|
end
|
65
40
|
|
66
41
|
# Unregister the context from the context manager,
|
67
42
|
# This context shoudn't be used after.
|
68
43
|
# The context has to be inactive before being forgetted
|
69
|
-
# TODO
|
44
|
+
# TODO Find a way to avoid the use of forgeted context (use forgeted flag?)
|
70
45
|
def forget
|
71
46
|
if active?
|
72
47
|
Phenomenal::Logger.instance.error(
|
@@ -74,26 +49,24 @@ class Phenomenal::Context
|
|
74
49
|
)
|
75
50
|
else
|
76
51
|
manager.unregister_context(self)
|
77
|
-
forgotten=true
|
78
52
|
end
|
79
53
|
end
|
80
54
|
|
81
55
|
# Add a new method adaptation to the context
|
82
56
|
# Return the adaptation just created
|
83
|
-
def add_adaptation(klass, method_name,
|
57
|
+
def add_adaptation(klass, method_name,umeth=nil, &implementation)
|
84
58
|
if umeth
|
85
59
|
implementation = umeth
|
86
|
-
instance = klass.instance_methods.include?(method_name)
|
87
60
|
end
|
88
|
-
if adaptations.find{ |i| i.concern?(klass,method_name
|
61
|
+
if adaptations.find{ |i| i.concern?(klass,method_name) }
|
89
62
|
Phenomenal::Logger.instance.error(
|
90
63
|
"Error: Illegal duplicated adaptation in context: #{self} for " +
|
91
64
|
"#{klass.name}:#{method_name}"
|
92
65
|
)
|
93
66
|
else
|
94
|
-
if klass.instance_methods.include?(method_name)
|
67
|
+
if klass.instance_methods.include?(method_name)
|
95
68
|
method = klass.instance_method(method_name)
|
96
|
-
elsif klass.methods.include?(method_name)
|
69
|
+
elsif klass.methods.include?(method_name)
|
97
70
|
method = klass.method(method_name)
|
98
71
|
else
|
99
72
|
Phenomenal::Logger.instance.error(
|
@@ -112,31 +85,17 @@ class Phenomenal::Context
|
|
112
85
|
end
|
113
86
|
|
114
87
|
adaptation = Phenomenal::Adaptation.new(
|
115
|
-
self, klass, method_name,
|
88
|
+
self, klass, method_name, implementation
|
116
89
|
)
|
117
90
|
adaptations.push(adaptation)
|
118
91
|
manager.register_adaptation(adaptation)
|
119
92
|
adaptation
|
120
93
|
end
|
121
94
|
end
|
122
|
-
|
123
|
-
# Catch nested context calls and transform them in nested contexts creation
|
124
|
-
def context(context,*contexts,&block)
|
125
|
-
check_validity
|
126
|
-
Phenomenal::Context.create(self,context,*contexts,true,self,&block)
|
127
|
-
end
|
128
|
-
alias_method :phen_context,:context
|
129
|
-
|
130
|
-
# Catch nested feature calls and transform them in nested contexts creation
|
131
|
-
def feature(feature,*features, &block)
|
132
|
-
check_validity
|
133
|
-
Phenomenal::Feature.create(self,feature,*features,true,self,&block)
|
134
|
-
end
|
135
|
-
alias_method :phen_feature,:feature
|
136
95
|
|
137
96
|
# Add multiple adaptations at definition time
|
138
97
|
def add_adaptations(&block)
|
139
|
-
instance_eval(&block)
|
98
|
+
instance_eval(&block)
|
140
99
|
end
|
141
100
|
|
142
101
|
# Set the current adapted class for the next adapt calls
|
@@ -146,18 +105,41 @@ class Phenomenal::Context
|
|
146
105
|
|
147
106
|
# Adapt a method for @current_adapted_class
|
148
107
|
def adapt(method,&block)
|
149
|
-
add_adaptation(@current_adapted_class,method
|
108
|
+
add_adaptation(@current_adapted_class,method,&block)
|
150
109
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
110
|
+
|
111
|
+
|
112
|
+
# Requires
|
113
|
+
def requires(*args)
|
114
|
+
args.each do |context|
|
115
|
+
if !required.include?(context)
|
116
|
+
required.push(context)
|
117
|
+
end
|
118
|
+
end
|
155
119
|
end
|
156
120
|
|
121
|
+
# Implies
|
122
|
+
def implies(*args)
|
123
|
+
args.each do |context|
|
124
|
+
if !implies.include?(context)
|
125
|
+
implied.push(context)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Guess
|
131
|
+
def guess(*args)
|
132
|
+
args.each do |context|
|
133
|
+
if !guessed.include?(context)
|
134
|
+
guessed.push(context)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
157
139
|
# Remove a method adaptation from the context
|
158
|
-
def remove_adaptation(klass,method_name
|
140
|
+
def remove_adaptation(klass,method_name)
|
159
141
|
adaptation_index =
|
160
|
-
adaptations.find_index{ |i| i.concern?(klass, method_name
|
142
|
+
adaptations.find_index{ |i| i.concern?(klass, method_name) }
|
161
143
|
if !adaptation_index
|
162
144
|
Phenomenal::Logger.instance.error(
|
163
145
|
"Error: Illegal deleting of an inexistent adaptation in context: " +
|
@@ -171,20 +153,75 @@ class Phenomenal::Context
|
|
171
153
|
|
172
154
|
# Activate the context
|
173
155
|
def activate
|
174
|
-
|
175
|
-
|
176
|
-
|
156
|
+
#TODO
|
157
|
+
# check_required
|
158
|
+
# activate_implicated
|
159
|
+
# activate_guessed
|
160
|
+
@@total_activations = @@total_activations+1
|
161
|
+
self.activation_age = @@total_activations
|
177
162
|
self.activation_count = self.activation_count+1
|
178
163
|
manager.activate_context(self)
|
179
164
|
self
|
180
|
-
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def check_required
|
168
|
+
required.each do |context_name|
|
169
|
+
context = manager.find_context(context_name)
|
170
|
+
if !context.active?
|
171
|
+
context.is_required[self.__id__] = self
|
172
|
+
Phenomenal::Logger.instance.error(
|
173
|
+
"Error: Required context #{context_name} not active."
|
174
|
+
)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def activate_implicated
|
180
|
+
activated = Array.new
|
181
|
+
begin
|
182
|
+
implicated.each do |context_name|
|
183
|
+
context = manager.find_context(context_name)
|
184
|
+
if !context.active?
|
185
|
+
context.activate
|
186
|
+
context.is_implied[self.__id__] = self
|
187
|
+
activated.push
|
188
|
+
end
|
189
|
+
end
|
190
|
+
rescue PhenomenalError => error
|
191
|
+
activated.reverse.each do |context|
|
192
|
+
context.deactivate
|
193
|
+
end
|
194
|
+
Phenomenal::Logger.instance.error(
|
195
|
+
"Error: Implication not satisfied for context #{name} : \n"+error
|
196
|
+
)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def activate_guessed
|
201
|
+
begin
|
202
|
+
implicated.each do |context_name|
|
203
|
+
context = manager.find_context(context_name)
|
204
|
+
if !context.active?
|
205
|
+
context.activate
|
206
|
+
end
|
207
|
+
end
|
208
|
+
rescue PhenomenalError # Don't care of error in case of guess
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
def can_activate
|
215
|
+
#TODO for exclude relations
|
216
|
+
true
|
217
|
+
end
|
218
|
+
|
219
|
+
|
181
220
|
|
182
221
|
# Deactivate the context
|
183
|
-
def deactivate
|
184
|
-
check_validity
|
222
|
+
def deactivate
|
185
223
|
was_active = active?
|
186
224
|
if self.activation_count>0
|
187
|
-
#Deactivation
|
188
225
|
self.activation_count = self.activation_count-1
|
189
226
|
end
|
190
227
|
if was_active && !active?
|
@@ -193,26 +230,25 @@ class Phenomenal::Context
|
|
193
230
|
self
|
194
231
|
end
|
195
232
|
|
233
|
+
def can_deactivate
|
234
|
+
#TODO for other relations
|
235
|
+
true
|
236
|
+
end
|
237
|
+
|
196
238
|
# True if the context is active
|
197
239
|
def active?
|
198
240
|
activation_count>0
|
199
241
|
end
|
200
242
|
|
201
|
-
# True if the context has just became active
|
202
|
-
def just_activated?
|
203
|
-
activation_count==1
|
204
|
-
end
|
205
|
-
|
206
|
-
# True if the context is anonymous
|
207
|
-
def anonymous?
|
208
|
-
name.nil?
|
209
|
-
end
|
210
|
-
|
211
243
|
# Return the activation age of the context:
|
212
244
|
# The age counter minus the age counter when the context was activated
|
213
245
|
# for the last time
|
214
246
|
def age
|
215
|
-
|
247
|
+
if activation_age == 0
|
248
|
+
@@total_activations
|
249
|
+
else
|
250
|
+
@@total_activations-activation_age
|
251
|
+
end
|
216
252
|
end
|
217
253
|
|
218
254
|
# Return context informations:
|
@@ -220,50 +256,21 @@ class Phenomenal::Context
|
|
220
256
|
# - List of the adaptations
|
221
257
|
# - Active state
|
222
258
|
# - Activation age
|
223
|
-
|
224
|
-
def information
|
259
|
+
def informations
|
225
260
|
{
|
226
261
|
:name=>name,
|
227
262
|
:adaptations=>adaptations,
|
228
263
|
:active=>active?,
|
229
|
-
:
|
230
|
-
:activation_count=>activation_count,
|
231
|
-
:type=>self.class.name
|
264
|
+
:activation_age=>age
|
232
265
|
}
|
233
266
|
end
|
234
267
|
|
235
|
-
# Return the closest parent feature of the context
|
236
|
-
def parent_feature
|
237
|
-
p = parent
|
238
|
-
while p!=nil && !p.is_a?(Phenomenal::Feature) do
|
239
|
-
p=p.parent
|
240
|
-
end
|
241
|
-
if p.nil?
|
242
|
-
manager.default_context
|
243
|
-
else
|
244
|
-
p
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
268
|
# String representation of the context
|
249
269
|
def to_s
|
250
270
|
if name
|
251
271
|
name.to_s
|
252
|
-
elsif self==manager.default_context
|
253
|
-
"'Default context'"
|
254
|
-
elsif manager.combined_contexts[self]
|
255
|
-
"'Combined context : #{manager.combined_contexts[self].flatten}'"
|
256
272
|
else
|
257
|
-
"
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
private
|
262
|
-
def check_validity
|
263
|
-
if forgotten
|
264
|
-
Phenomenal::Logger.instance.error(
|
265
|
-
"Action not allowed anymore when context has been forgotten"
|
266
|
-
)
|
273
|
+
"Anonymous context"
|
267
274
|
end
|
268
275
|
end
|
269
276
|
end
|