woyo-world 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41529c0e59bef04bb41b1732e50ef7f75ec94b0f
4
- data.tar.gz: 6df39185e8e284a7beb7985adecbbae2741e8edc
3
+ metadata.gz: d6b8db18d440d61ddaf291c7db149e5fa35f8a98
4
+ data.tar.gz: 393a37a546f63d71e2132374c927f0571d475c4b
5
5
  SHA512:
6
- metadata.gz: 18d325950bf55638c7f88ca8c24008affbea3f1fc123f2e24d2dca9fd193b20ef5d247113fbf3abe8b3598b887e063373f2ac92e50bf24213397d3498d55757a
7
- data.tar.gz: 044aecb2e1e1c830c6ed1fb450be14fe7ebc76b338312a63c0616dcf8a651ec85d205b57a5c5da626287d2da7d022aac342e095c9a70decf32c25534262b61e0
6
+ metadata.gz: 465dab73ed8d398391a9e7ca63bac830b205a7622e895a5b1fc736ad36d7c2f36179a5713f7bece47aaf53ab6ecdb438937f9c8b026f730f5d3b9eff1e8f2f08
7
+ data.tar.gz: 033f7d8ddf1839495ead16bb0d65ae6e4e7df2469bb31ab7e5e7993483a41c7d8e4d1485d43eccd3844f2fd1ce0f6813fe02497ccd8bc9ca4e36bffe836dc076
@@ -1,31 +1,75 @@
1
+ require_relative 'group'
2
+
3
+ class Hash
4
+ alias_method :names, :keys
5
+ end
1
6
 
2
7
  module Woyo
3
8
 
4
9
  module Attributes
5
10
 
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+
15
+ def self.prepended(base)
16
+ base.singleton_class.prepend(ClassMethods) # base.extend(ClassMethods) also seems to work, what's the diff ?
17
+ end
18
+
19
+ def initialize *args
20
+ initialize_attributes
21
+ initialize_groups
22
+ initialize_boolean_groups
23
+ initialize_is_overrides
24
+ #super # we'll need this if we prepend Attributes again
25
+ end
26
+
6
27
  module ClassMethods
7
28
 
8
- def create_attribute_methods_with_define_method attr, default = nil
29
+ def define_attr_methods attr, default = nil
30
+ define_attr_default attr, default
31
+ define_attr_equals attr
32
+ define_attr attr
33
+ if default == true || default == false # boolean convenience methods
34
+ define_attr? attr
35
+ define_attr! attr
36
+ end
37
+ end
38
+
39
+ def define_attr_default attr, default
40
+ define_method "#{attr}_default" do
41
+ if default.respond_to? :call
42
+ return default.arity == 0 ? default.call : default.call(self)
43
+ end
44
+ default
45
+ end
46
+ end
47
+
48
+ def define_attr_equals attr
9
49
  define_method "#{attr}=" do |arg|
10
50
  attributes[attr] = arg
11
51
  end
52
+ end
53
+
54
+ def define_attr attr
12
55
  define_method attr do |arg = nil|
13
- if arg.nil?
14
- unless attributes.has_key? attr
15
- if default.respond_to? :call
16
- if default.arity == 0
17
- attributes[attr] = default.call # todo: is this the same as ? ... instance_eval &default
18
- else
19
- attributes[attr] = default.call(self)
20
- end
21
- else
22
- attributes[attr] = default
23
- end
24
- end
25
- attributes[attr]
26
- else
27
- attributes[attr] = arg
28
- end
56
+ return attributes[attr] = arg unless arg.nil?
57
+ return attributes[attr] unless attributes[attr].kind_of? Hash
58
+ true_attribute_match = attributes[attr].detect { |name,value| attributes[name] == true }
59
+ return true_attribute_match[1] if true_attribute_match
60
+ attributes[attr]
61
+ end
62
+ end
63
+
64
+ def define_attr? attr
65
+ define_method "#{attr}?" do
66
+ ( send attr ) ? true : false
67
+ end
68
+ end
69
+
70
+ def define_attr! attr
71
+ define_method "#{attr}!" do
72
+ send "#{attr}=", true
29
73
  end
30
74
  end
31
75
 
@@ -35,24 +79,124 @@ module Attributes
35
79
  attrs.each do |attr|
36
80
  if attr.kind_of? Hash
37
81
  attr.each do |attr_sym,default_value|
38
- @attributes << attr_sym
39
- create_attribute_methods_with_define_method attr_sym, default_value
82
+ @attributes << attr_sym unless @attributes.include? attr_sym
83
+ define_attr_methods attr_sym, default_value
40
84
  end
41
85
  else
42
- @attributes << attr
43
- create_attribute_methods_with_define_method attr
86
+ unless @attributes.include? attr
87
+ @attributes << attr
88
+ define_attr_methods attr
89
+ end
44
90
  end
45
91
  end
46
92
  end
47
93
 
48
- end
94
+ def attribute *attrs
95
+ self.attributes *attrs
96
+ end
97
+
98
+ def groups
99
+ @groups ||= {}
100
+ end
49
101
 
50
- def self.included(base)
51
- base.extend(ClassMethods)
102
+ def group sym, *attrs
103
+ @groups ||= {}
104
+ group = @groups[sym] ? @groups[sym] : ( @groups[sym] = [] )
105
+ self.attributes *attrs
106
+ attrs.each do |attr|
107
+ if attr.kind_of? Hash
108
+ attr.each do |attr_sym,default_value|
109
+ group << attr_sym
110
+ end
111
+ else
112
+ group << attr
113
+ end
114
+ end
115
+ define_method sym do
116
+ groups[sym]
117
+ end
118
+ group
119
+ end
120
+
121
+ def boolean_groups
122
+ @boolean_groups ||={}
123
+ end
124
+
125
+ def group! sym, *attrs
126
+ @boolean_groups ||= {}
127
+ group = @boolean_groups[sym] ? @boolean_groups[sym] : ( @boolean_groups[sym] = [] )
128
+ self.attributes *attrs
129
+ attrs.each do |attr|
130
+ define_attr? attr
131
+ define_attr! attr
132
+ if attr.kind_of? Hash
133
+ attr.each do |attr_sym,default_value|
134
+ group << attr_sym
135
+ end
136
+ else
137
+ group << attr
138
+ end
139
+ end
140
+ define_method sym do
141
+ boolean_groups[sym]
142
+ end
143
+ group
144
+ end
145
+
146
+ def is *attrs
147
+ @is_overrides ||= []
148
+ attrs.each do |attr|
149
+ @is_overrides << attr unless @is_overrides.include? attr
150
+ self.attribute( { attr => true } )
151
+ end
152
+ end
153
+
154
+ def is_overrides
155
+ @is_overrides ||= []
156
+ end
157
+
158
+ end # module ClassMethods
159
+
160
+ def initialize_attributes
161
+ @attributes = self.class.attributes.each_with_object(Woyo::Attributes::AttributesHash.new) do |attr,hash|
162
+ hash[attr] = send "#{attr}_default"
163
+ end
52
164
  end
53
-
165
+
166
+ def initialize_groups
167
+ @groups = {}
168
+ self.class.groups.each { |sym,members| @groups[sym] = Woyo::Attributes::Group.new @attributes, *members }
169
+ @groups
170
+ end
171
+
172
+ def initialize_boolean_groups
173
+ @boolean_groups = {}
174
+ self.class.boolean_groups.each { |sym,members| @boolean_groups[sym] = Woyo::Attributes::BooleanGroup.new @attributes, *members }
175
+ @boolean_groups
176
+ end
177
+
178
+ def initialize_is_overrides
179
+ self.class.is_overrides.each { |attr| send "#{attr}!" }
180
+ end
181
+
54
182
  def attributes
55
- @attributes ||= {}
183
+ @attributes
184
+ end
185
+
186
+ def groups
187
+ @groups
188
+ end
189
+
190
+ def boolean_groups
191
+ @boolean_groups
192
+ end
193
+
194
+ def is? attr
195
+ send "#{attr}?"
196
+ end
197
+
198
+ def is attr
199
+ send "#{attr}=", true
56
200
  end
57
201
 
58
202
  end
@@ -0,0 +1,101 @@
1
+ require 'forwardable'
2
+
3
+ module Woyo
4
+
5
+ module Attributes
6
+
7
+ class AttributesHash < Hash
8
+
9
+ alias_method :names, :keys
10
+ alias_method :set, :[]=
11
+
12
+ attr_reader :listeners
13
+
14
+ def initialize
15
+ @listeners = {}
16
+ end
17
+
18
+ def add_attribute_listener attr, listener
19
+ @listeners[attr] = listener
20
+ end
21
+
22
+ def []= attr, value
23
+ old_value = self[attr]
24
+ super
25
+ if ( listener = @listeners[attr] ) && value != old_value
26
+ listener.notify attr, value
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ class Group
33
+
34
+ extend Forwardable
35
+
36
+ def_delegators :@members, :count
37
+ def_delegators :@attributes, :[], :[]=
38
+
39
+ attr_reader :members, :attributes
40
+
41
+ def initialize attributes, *members
42
+ @attributes = attributes
43
+ @members = members
44
+ end
45
+
46
+ def names
47
+ @members
48
+ end
49
+
50
+ def values
51
+ @attributes.values_at *@members
52
+ end
53
+
54
+ end
55
+
56
+ class BooleanGroup < Group
57
+
58
+ attr_reader :default
59
+
60
+ def initialize attributes, *members
61
+ super
62
+ @default = @members.first
63
+ self[@default] = true
64
+ @members.each { |member| @attributes.add_attribute_listener member, self }
65
+ end
66
+
67
+ def []= this_member, value
68
+ raise '#{this_member} is not a member of this group' unless @members.include? this_member
69
+ super
70
+ if value #true
71
+ # sync group members via AttributesHash#set to prevent triggering notify
72
+ @members.each { |member| @attributes.set(member,false) unless member == this_member }
73
+ else #false
74
+ if self.count == 2 # binary group
75
+ @members.each { |member| @attributes.set member ,(member != this_member ) }
76
+ else
77
+ self[@default] = true # revert to default
78
+ end
79
+ end
80
+ end
81
+
82
+ def notify this_member, value
83
+ # assuming value==true for now
84
+ # sync group members via AttributesHash#set to prevent re-triggering notify
85
+ @members.each { |member| @attributes.set(member,false) unless member == this_member }
86
+ end
87
+
88
+ def value
89
+ @members.detect { |member| @attributes[member] } # name of first member with true value
90
+ end
91
+
92
+ def default!
93
+ self[@default] = true
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+
@@ -1,3 +1,3 @@
1
1
  module Woyo
2
- WORLD_VERSION = "0.0.5"
2
+ WORLD_VERSION = "0.0.6"
3
3
  end
@@ -6,12 +6,26 @@ class Way < WorldObject
6
6
 
7
7
  attributes :description, name: lambda { |this| this.id.to_s.capitalize }
8
8
 
9
+ group! :passable, :closed, :open # defaults to closed: true
10
+
11
+ def world
12
+ from ? from.world : nil
13
+ end
14
+
15
+ def close!
16
+ closed!
17
+ end
18
+
9
19
  def from
10
20
  @from ||= context
11
21
  end
12
22
 
13
- def world
14
- from ? from.world : nil
23
+ def to arg=nil
24
+ if arg.nil?
25
+ @to
26
+ else
27
+ self.to = arg
28
+ end
15
29
  end
16
30
 
17
31
  def to= arg
@@ -26,15 +40,16 @@ class Way < WorldObject
26
40
  else
27
41
  @to = Location.new arg # create free-standing destination location
28
42
  end
43
+ self.open!
44
+ else
45
+ raise "Symbol required, but #{arg.class} : '#{arg}' given."
29
46
  end
30
47
  end
31
48
 
32
- def to arg=nil
33
- if arg.nil?
34
- @to
35
- else
36
- self.to = arg
37
- end
49
+ attribute :going
50
+
51
+ def go
52
+ { go: open?, going: self.going }
38
53
  end
39
54
 
40
55
  end
@@ -6,6 +6,7 @@ module Woyo
6
6
 
7
7
  class WorldObject
8
8
 
9
+ #prepend Attributes
9
10
  include Attributes
10
11
  include DSL
11
12
 
@@ -15,6 +16,7 @@ class WorldObject
15
16
  def initialize id, context: nil, &block
16
17
  @id = id.to_s.downcase.to_sym
17
18
  @context = context
19
+ super # initializes attributes
18
20
  evaluate &block
19
21
  end
20
22