Guest User

Untitled

a guest
Feb 21st, 2018
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.07 KB | None | 0 0
  1. module KeyValueObserving
  2. attr_accessor :bindings
  3.  
  4. def self.included(base)
  5. base.extend(ClassMethods)
  6. base.extend(SharedMethods)
  7. end
  8.  
  9. module SharedMethods
  10. def did_change_value_for(attribute)
  11. puts "updated value for #{attribute} on #{self}"
  12. bindings_for(attribute).each do |binding|
  13. binding.object.send("#{binding.attribute}=", binding.key_path.target_property)
  14. end
  15. end
  16. end
  17. include SharedMethods
  18.  
  19. module ClassMethods
  20. def kvc_accessor(*accessors)
  21. accessors.each do |accessor|
  22. define_method accessor do
  23. instance_variable_get "@#{accessor}"
  24. end
  25. define_method :"#{accessor}=" do |value|
  26. instance_variable_set "@#{accessor}", value
  27. did_change_value_for(accessor.to_s)
  28. end
  29. end
  30. end
  31. end
  32. end
  33.  
  34. module Bindable
  35. def self.included(base)
  36. base.extend(SharedMethods)
  37. end
  38. attr_accessor :bindings
  39.  
  40. module SharedMethods
  41. def bind(attribute,path)
  42. binding = Ribbon.new(self,attribute,path)
  43. self.send("#{attribute}=", binding.key_path.target_property)
  44. return binding
  45. end
  46.  
  47. def bindings
  48. @bindings
  49. end
  50.  
  51. def bindings_for(attribute)
  52. @bindings ||= {}
  53. @bindings[attribute] || []
  54. end
  55.  
  56. def add_binding_for_attribute(binding,attribute)
  57. @bindings ||= {}
  58. @bindings[attribute] ? @bindings[attribute] << binding : @bindings[attribute] = [binding]
  59. end
  60. end
  61. include SharedMethods
  62. end
  63.  
  64. class KeyPath
  65. def initialize(path)
  66. @path = path
  67. end
  68.  
  69. def step_through(path)
  70. callee = Object.module_eval(path.shift)
  71. while caller = path.shift
  72. callee = callee.send(caller)
  73. end
  74. return callee
  75. end
  76.  
  77. def target_object
  78. step_through(@path.split('.')[0..-2])
  79. end
  80.  
  81. def target_property_name
  82. @path.split('.').last
  83. end
  84.  
  85. def target_property
  86. step_through(@path.split('.'))
  87. end
  88. end
  89.  
  90. class Ribbon
  91. attr_reader :key_path, :object, :attribute
  92. def initialize(object, attribute, key_path)
  93. @object = object
  94. @attribute = attribute
  95. @key_path = KeyPath.new(key_path)
  96. @bound_object = @key_path.target_object
  97. @bound_property = @key_path.target_property_name
  98. self.connect
  99. end
  100.  
  101. def connect
  102. @bound_object.add_binding_for_attribute(self,@bound_property)
  103. end
  104. end
  105.  
  106. class Controller
  107. include KeyValueObserving
  108. include Bindable
  109. def self.kvc_accessor(*accessors)
  110. accessors.each do |accessor|
  111. define_method accessor do
  112. instance_variable_get "@#{accessor}"
  113. end
  114. define_method :"#{accessor}=" do |value|
  115. instance_variable_set "@#{accessor}", value
  116. did_change_value_for(accessor.to_s)
  117. end
  118. m = Module.new do
  119. define_method accessor do
  120. self.shared_instance.send(accessor)
  121. end
  122.  
  123. define_method :"#{accessor}=" do |value|
  124. self.shared_instance.send(:"#{accessor}=", value)
  125. did_change_value_for(accessor.to_s)
  126. end
  127. end
  128. self.extend(m)
  129. end
  130. end
  131.  
  132. def self.shared_instance
  133. @shared_instance ||= self.new
  134. end
  135. end
  136.  
  137. class ArrayController < Controller
  138. kvc_accessor :arranged_objects, :selection
  139. end
  140.  
  141. class Model
  142. include Bindable
  143. include KeyValueObserving
  144. end
  145.  
  146. class View
  147. include KeyValueObserving
  148. include Bindable
  149. kvc_accessor :data_source
  150.  
  151. def initialize(options={:bind => {}})
  152. options[:bind].each do |property,path|
  153. bind property, path
  154. end
  155. end
  156.  
  157. def did_change_value_for(attribute)
  158. redraw
  159. end
  160.  
  161. def redraw
  162. puts "I was updated and redrew!"
  163. end
  164. end
  165.  
  166. class Note < Model
  167. @data = [Note.new,Note.new,Note.new]
  168. def self.all
  169. @data
  170. end
  171.  
  172. def self.all=(ary)
  173. @data = ary
  174. self.did_change_value_for('all')
  175. end
  176. end
  177.  
  178. class NotesController < ArrayController
  179. shared_instance
  180. bind 'arranged_objects', 'Note.all'
  181. end
  182.  
  183. # v = NoteList.new({:bind => {'data_source' => 'NotesController.arranged_objects'}})
  184. class NoteList < View
  185.  
  186. end
Add Comment
Please, Sign In to add comment