puremvc-ruby 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/puremvc-ruby.rb +13 -0
- data/src/org/puremvc/ruby/core/controller.rb +76 -0
- data/src/org/puremvc/ruby/core/model.rb +57 -0
- data/src/org/puremvc/ruby/core/view.rb +112 -0
- data/src/org/puremvc/ruby/patterns/command/macro_command.rb +59 -0
- data/src/org/puremvc/ruby/patterns/command/simple_command.rb +17 -0
- data/src/org/puremvc/ruby/patterns/facade/facade.rb +161 -0
- data/src/org/puremvc/ruby/patterns/mediator/mediator.rb +37 -0
- data/src/org/puremvc/ruby/patterns/observer/notification.rb +38 -0
- data/src/org/puremvc/ruby/patterns/observer/notifier.rb +27 -0
- data/src/org/puremvc/ruby/patterns/observer/observer.rb +31 -0
- data/src/org/puremvc/ruby/patterns/proxy/proxy.rb +32 -0
- data/version.txt +12 -0
- metadata +75 -0
data/puremvc-ruby.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'src/org/puremvc/ruby')
|
2
|
+
require 'singleton'
|
3
|
+
require 'patterns/facade/facade'
|
4
|
+
require 'patterns/proxy/proxy'
|
5
|
+
require 'patterns/observer/observer'
|
6
|
+
require 'patterns/observer/notification'
|
7
|
+
require 'patterns/observer/notifier'
|
8
|
+
require 'patterns/mediator/mediator'
|
9
|
+
require 'patterns/command/macro_command'
|
10
|
+
require 'patterns/command/simple_command'
|
11
|
+
require 'core/controller'
|
12
|
+
require 'core/model'
|
13
|
+
require 'core/view'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# In PureMVC, the Controller class assumes these responsibilities:
|
2
|
+
# * Remembering which Command is intended to handle which Notification.
|
3
|
+
# * Registering itself as an Observer with the View for each Notification that it has an Command mapping for.
|
4
|
+
# * Creating instances of the proper Command to handle a given Notification when notified by the View.
|
5
|
+
# * Calling the Command's execute method, passing in the Notification.
|
6
|
+
#
|
7
|
+
# Your application must register any Commands with the Controller.
|
8
|
+
#
|
9
|
+
# The simplest way is to subclass Facade, and use its initializeController method to add your registrations.
|
10
|
+
#
|
11
|
+
# * Command refers to SimpleCommand or MacroCommand
|
12
|
+
|
13
|
+
|
14
|
+
class Controller
|
15
|
+
attr_accessor :command_map, :view
|
16
|
+
|
17
|
+
include Singleton
|
18
|
+
|
19
|
+
# This Controller implementation is a Singleton,
|
20
|
+
# so you can not call the constructor
|
21
|
+
# directly, but instead call the static Singleton
|
22
|
+
# Factory method Controller.instance
|
23
|
+
def initialize
|
24
|
+
@command_map = {}
|
25
|
+
initialize_controller
|
26
|
+
end
|
27
|
+
|
28
|
+
# Initialize the Singleton Controller instance.
|
29
|
+
#
|
30
|
+
# Called Automatically by the construcor.
|
31
|
+
#
|
32
|
+
# Note that if you are using a subclass of View in your application, you should also
|
33
|
+
# subclass Controller and override the initialize_controller method in the following way:
|
34
|
+
#
|
35
|
+
# <tt>
|
36
|
+
# def initialize_controller
|
37
|
+
# @view = MyView.instance
|
38
|
+
# end
|
39
|
+
# </tt>
|
40
|
+
def initialize_controller
|
41
|
+
@view = View.instance
|
42
|
+
end
|
43
|
+
|
44
|
+
# If a Command has previously been registered to handle a given Notification, then it is executed
|
45
|
+
def execute_command(notification)
|
46
|
+
return unless @command_map[notification.name]
|
47
|
+
@command_map[notification.name].new().execute(notification)
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# Register a particular Command class as the handler for a particular Notification.
|
52
|
+
#
|
53
|
+
# If a Command has already been registered to handle Notification's with this name, it is
|
54
|
+
# no longer user, the new Command is used instead.
|
55
|
+
#
|
56
|
+
# The Observer for the new Command is only created if this is the first time a Command
|
57
|
+
# has been registered for this Notification name.
|
58
|
+
def register_command(notification_name, command_class)
|
59
|
+
@view.register_observer( notification_name, Observer.new(:execute_command, self) );
|
60
|
+
@command_map[notification_name] = command_class
|
61
|
+
end
|
62
|
+
|
63
|
+
# Check if a command is registered for a given Notification
|
64
|
+
def has_command?(notification_name)
|
65
|
+
!@command_map[notification_name].nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
# Remove a previously registered Command for a given Notification
|
69
|
+
def remove_command(notification_name)
|
70
|
+
@view.remove_observer(notification_name, self)
|
71
|
+
@command_map.delete(notification_name)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
75
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
76
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# In PureMVC, the Model class provides access to model objects (Proxies) by named lookup.
|
2
|
+
#
|
3
|
+
# The Model assumes these responsibilities:
|
4
|
+
# * Maintain a cache of Proxy instances.
|
5
|
+
# * Provide methods for registering, retrieving, and removing Proxy instances.
|
6
|
+
#
|
7
|
+
# Your application must register Proxy instances with the Model.
|
8
|
+
# Typically, you use an Command to create and register Proxy
|
9
|
+
# instances once the Facade has initialized the Core actors.
|
10
|
+
|
11
|
+
class Model
|
12
|
+
|
13
|
+
include Singleton
|
14
|
+
attr_accessor :proxy_map
|
15
|
+
|
16
|
+
|
17
|
+
# This Model implementation is a Singleton, so you can not call the constructor
|
18
|
+
# directly, but instead call the static Singleton Factory method Model.instance
|
19
|
+
def initialize
|
20
|
+
@proxy_map = {}
|
21
|
+
initialize_model
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# Initialize the Singleton Model instance.
|
26
|
+
#
|
27
|
+
# Called automatically by the constructor, this is your opportunity to initialize the Singleton
|
28
|
+
# instance in your subclass without overriding the constructor.
|
29
|
+
def initialize_model
|
30
|
+
end
|
31
|
+
|
32
|
+
# Register a Proxy with the Model.
|
33
|
+
def register_proxy(proxy)
|
34
|
+
@proxy_map[proxy.name] = proxy
|
35
|
+
proxy.on_register
|
36
|
+
end
|
37
|
+
|
38
|
+
# Retrieve a Proxy from the Model
|
39
|
+
def retrieve_proxy(proxy_name)
|
40
|
+
@proxy_map[proxy_name]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Check if a Proxy is registered.
|
44
|
+
def has_proxy?(proxy_name)
|
45
|
+
!@proxy_map[proxy_name].nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
# Remove a Proxy from teh Model.
|
49
|
+
def remove_proxy(proxy_name)
|
50
|
+
proxy = @proxy_map.delete(proxy_name)
|
51
|
+
proxy.on_remove
|
52
|
+
proxy
|
53
|
+
end
|
54
|
+
end
|
55
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
56
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
57
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# In PureMVC, the View class assumes these responsibilities:
|
2
|
+
#
|
3
|
+
# * Maintain a cache of IMediator instances.
|
4
|
+
# * Provide methods for registering, retrieving, and removing Mediators.
|
5
|
+
# * Notifiying Mediators when they are registered or removed.
|
6
|
+
# * Managing the observer lists for each Notification in the application.
|
7
|
+
# * Providing a method for attaching Observers to an Notification's observer list.
|
8
|
+
# * Providing a method for broadcasting an Notification.
|
9
|
+
# * Notifying the Observers of a given Notification when it broadcast.
|
10
|
+
class View
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
attr_accessor :mediator_map, :observer_map
|
14
|
+
|
15
|
+
|
16
|
+
# This View implementation is a Singleton, so you should not call the constructor
|
17
|
+
# directly, but instead call the static Singleton Factory method View.instance.
|
18
|
+
def initialize
|
19
|
+
@mediator_map = {}
|
20
|
+
@observer_map = {}
|
21
|
+
initialize_view
|
22
|
+
end
|
23
|
+
|
24
|
+
# Initialize the Singleton View instance.
|
25
|
+
#
|
26
|
+
# Called automatically by the constructor, this is your opportunity to initialize
|
27
|
+
# the Singleton instance in your subclass without overriding the constructor
|
28
|
+
def initialize_view
|
29
|
+
end
|
30
|
+
|
31
|
+
# Register an Observer to be notified of Notifications with a given name.
|
32
|
+
def register_observer(notification_name, observer)
|
33
|
+
observers = @observer_map[notification_name]
|
34
|
+
if observers.nil?
|
35
|
+
@observer_map[notification_name] = observer
|
36
|
+
else
|
37
|
+
observers = Array(@observer_map[notification_name])
|
38
|
+
observers << observer
|
39
|
+
@observer_map[notification_name] = observers
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Notify the Observers for a particular Notification.
|
44
|
+
#
|
45
|
+
# All previously attached Observers for this Notification's list are notified
|
46
|
+
# and are passed a reference to the Notification in the order in which they were registered.
|
47
|
+
def notify_observers(notification)
|
48
|
+
observers = Array(@observer_map[notification.name])
|
49
|
+
observers.each{|observer| observer.notify_observer(notification)}
|
50
|
+
end
|
51
|
+
|
52
|
+
# Remove the observer for a given notify context from an observer list for a given
|
53
|
+
# Notification name.
|
54
|
+
def remove_observer(notification_name, observer)
|
55
|
+
observers = @observer_map[notification_name]
|
56
|
+
observers = [observers] unless observers.is_a?(Array)
|
57
|
+
@observer_map[notification_name] = observers.reject { |o| o.compare_notify_context(observer) }
|
58
|
+
@observer_map.delete(notification_name) if observers.size.zero?
|
59
|
+
end
|
60
|
+
|
61
|
+
# Register a Mediator instance with the View.
|
62
|
+
#
|
63
|
+
# Registers the Mediator so that it can be retrieved by name and further interrogates
|
64
|
+
# the mediator for its Notification interests.
|
65
|
+
#
|
66
|
+
# If the mediator returns any Notifiation name to be notified about, an Observer is created
|
67
|
+
# encapsulating the Mediator instance's handle_notification method and registering it as an
|
68
|
+
# Observer for all Notifications the Mediator is interested in.
|
69
|
+
def register_mediator(mediator)
|
70
|
+
unless @mediator_map[mediator.name]
|
71
|
+
@mediator_map[mediator.name] = mediator
|
72
|
+
observer = Observer.new(:handle_notification, mediator)
|
73
|
+
mediator.list_notification_interests.each do |interest|
|
74
|
+
register_observer(interest, observer)
|
75
|
+
end
|
76
|
+
mediator.on_register
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Retrieve a mediator from the View.
|
81
|
+
#
|
82
|
+
# returns the previously registered Mediator with the given name.
|
83
|
+
def retrieve_mediator(mediator_name)
|
84
|
+
@mediator_map[mediator_name]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Remove a Mediator from the View.
|
88
|
+
#
|
89
|
+
# returns the Mediator that was removed.
|
90
|
+
def remove_mediator(mediator_name)
|
91
|
+
mediator = @mediator_map[mediator_name]
|
92
|
+
if mediator
|
93
|
+
mediator.list_notification_interests.each do |interest|
|
94
|
+
remove_observer(interest, mediator)
|
95
|
+
end
|
96
|
+
@mediator_map.delete(mediator_name)
|
97
|
+
mediator.on_remove
|
98
|
+
end
|
99
|
+
mediator
|
100
|
+
end
|
101
|
+
|
102
|
+
# Check if a Mediator is registered or not.
|
103
|
+
#
|
104
|
+
# returns whether a Mediator is registered with the given name.
|
105
|
+
def has_mediator?(mediator_name)
|
106
|
+
!@mediator_map[mediator_name].nil?
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
111
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
112
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# A MacroCommand maintains an list of Command Class references called SubCommands
|
2
|
+
#
|
3
|
+
# When execute is called, the MacroCommand instantiates and calls execute on each
|
4
|
+
# of its SubCommands.Each SubCommand will be passed a reference to the original
|
5
|
+
# Notification that was passed to the MacroCommand's execute method.
|
6
|
+
#
|
7
|
+
# Unlike SimpleCommand, your subclass should not override execute, but instead,
|
8
|
+
# should override the initialize_macro_command method, calling add_sub_command
|
9
|
+
# once for each SubCommand to be executed.
|
10
|
+
class MacroCommand
|
11
|
+
attr_accessor :sub_commands
|
12
|
+
|
13
|
+
|
14
|
+
# You should not need to define a constructor,
|
15
|
+
# instead, override the initialize_macro_command method.
|
16
|
+
#
|
17
|
+
# If your subclass does define a constructor, be sure to call super.
|
18
|
+
def initialize
|
19
|
+
@sub_commands = []
|
20
|
+
initialize_macro_command
|
21
|
+
end
|
22
|
+
|
23
|
+
# Initialize the MacroCommand.
|
24
|
+
#
|
25
|
+
# In your subclass, override this method to initialize the MacroCommand's
|
26
|
+
# SubCommand list with Command class references like this:
|
27
|
+
#
|
28
|
+
# <tt>
|
29
|
+
# def initialize_macro_command
|
30
|
+
# add_sub_command( FirstCommand.new )
|
31
|
+
# add_sub_command( SecondCommand.new )
|
32
|
+
# add_sub_command( ThirdCommand.new )
|
33
|
+
# end
|
34
|
+
# </tt>
|
35
|
+
#
|
36
|
+
# Note that SubCommands may be MacroCommands or SimpleCommands.
|
37
|
+
def initialize_macro_command
|
38
|
+
raise NotImplementedError
|
39
|
+
end
|
40
|
+
|
41
|
+
# Add a SubCommand
|
42
|
+
#
|
43
|
+
#The Subcommands will be called in First In/First Out (FIFO) order.
|
44
|
+
def add_sub_command(command)
|
45
|
+
@sub_commands << command
|
46
|
+
end
|
47
|
+
|
48
|
+
# Execute this MacroCommand's Subcommands. The SubCommands will be called in First
|
49
|
+
# In/First Out (FIFO) order.
|
50
|
+
def execute(notification)
|
51
|
+
@sub_commands.each do |command|
|
52
|
+
command.new().execute(notification)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
58
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
59
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Your subclass should override the execute method where your business logic
|
2
|
+
# will handle the Notification.
|
3
|
+
class SimpleCommand < Notifier
|
4
|
+
|
5
|
+
# Fulfill the use-case initiated by the given Notification.
|
6
|
+
#
|
7
|
+
# In the Command Pattern, an application use-case typically
|
8
|
+
# begins with some user action, which results in an Notification being broadcast, which
|
9
|
+
# is handled by business logic in the execute method of an Command.
|
10
|
+
def execute(notification)
|
11
|
+
#override if you want to do something on this event
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
16
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
17
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# In PureMVC, the Facade class assumes these responsibilities:
|
2
|
+
#
|
3
|
+
# * Initializing the Model, View and Controller Singletons.
|
4
|
+
# * Providing all the methods defined by the Model, View, & Controller.
|
5
|
+
# * Providing the ability to override the specific Model, View and Controller Singletons created.
|
6
|
+
# * Providing a single point of contact to the application for registering Commands and notifying Observers
|
7
|
+
class Facade
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
attr_accessor :model, :view, :controller
|
11
|
+
|
12
|
+
# This Facade implementation is a Singleton, so you can not call the constructor
|
13
|
+
# directly, but instead call the static Singleton Factory method Facade.instance
|
14
|
+
def initialize
|
15
|
+
initialize_facade
|
16
|
+
end
|
17
|
+
|
18
|
+
# Initialize the Singleton Facade instance.
|
19
|
+
#
|
20
|
+
# Called automatically by the constructor. Override in your
|
21
|
+
# subclass to do any subclass specific initializations. Be sure to call super.
|
22
|
+
def initialize_facade
|
23
|
+
initialize_model
|
24
|
+
initialize_view
|
25
|
+
initialize_controller
|
26
|
+
end
|
27
|
+
|
28
|
+
# Initialize the Controller.
|
29
|
+
#
|
30
|
+
# Called by the initialize_facade method.
|
31
|
+
# Override this method in your subclass of Facade if one or both of the following are true:
|
32
|
+
# * You wish to initialize a different Controller.
|
33
|
+
# * You have Commands to register with the Controller at startup.
|
34
|
+
#
|
35
|
+
# If you don't want to initialize a different Controller,
|
36
|
+
# call super at the beginning of your method, then register Commands.
|
37
|
+
def initialize_controller
|
38
|
+
return unless @controller.nil?
|
39
|
+
@controller = Controller.instance
|
40
|
+
end
|
41
|
+
|
42
|
+
# Initialize the Model.
|
43
|
+
#
|
44
|
+
# Called by the initialize_facade method.
|
45
|
+
# Override this method in your subclass of Facade if one or both of the following are true:
|
46
|
+
# * You wish to initialize a different Model.
|
47
|
+
# * You have Proxys to register with the Model that do not retrieve a reference to
|
48
|
+
# the Facade at construction time.
|
49
|
+
#
|
50
|
+
# If you don't want to initialize a different Model,
|
51
|
+
# call super at the beginning of your method, then register Proxys.
|
52
|
+
#
|
53
|
+
# Note: This method is rarely overridden; in practice you are morelikely to use a
|
54
|
+
# Command to create and register Proxys with the Model, since Proxys with mutable
|
55
|
+
# data will likely need to send Notifications and thus will likely want to fetch a
|
56
|
+
# reference to the Facade during their construction.
|
57
|
+
def initialize_model
|
58
|
+
return unless @model.nil?
|
59
|
+
@model = Model.instance
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Initialize the View.
|
64
|
+
#
|
65
|
+
# Called by the initialize_facade method.
|
66
|
+
# Override this method in your subclass of Facade if one or both of the following are true:
|
67
|
+
# * You wish to initialize a different View.
|
68
|
+
# * You have Observers to register with the View.
|
69
|
+
#
|
70
|
+
# If you don't want to initialize a different View, call super at the beginning of your
|
71
|
+
# method, then register Mediator instances.
|
72
|
+
#
|
73
|
+
# Note: This method is rarely overridden; in practice you are more likely to use a
|
74
|
+
# Command to create and register Mediators with the View, since Mediator instances
|
75
|
+
# will need to send Notifications and thus will likely want to fetch a reference
|
76
|
+
# to the Facade during their construction.
|
77
|
+
def initialize_view
|
78
|
+
return unless @view.nil?
|
79
|
+
@view = View.instance
|
80
|
+
end
|
81
|
+
|
82
|
+
# Register an Command with the Controller by Notification name.
|
83
|
+
def register_command(name, command_class_ref)
|
84
|
+
@controller.register_command(name, command_class_ref)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Remove a previously registered Command to Notification mapping from the Controller.
|
88
|
+
def remove_command(notification_name)
|
89
|
+
@controller.remove_command(notification_name)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Check if a Command is registered for a given Notification
|
93
|
+
def has_command?(notification_name)
|
94
|
+
@controller.has_command?(notification_name)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Register a Proxy with the Model by name.
|
98
|
+
def register_proxy(proxy)
|
99
|
+
@model.register_proxy(proxy)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Retrieve a Proxy with the Model by name.
|
103
|
+
def retrieve_proxy(proxy_name)
|
104
|
+
@model.retrieve_proxy(proxy_name)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Remove an Proxy from the Model by name.
|
108
|
+
def remove_proxy(proxy_name)
|
109
|
+
proxy = @model.remove_proxy(proxy_name) unless @model.nil?
|
110
|
+
proxy
|
111
|
+
end
|
112
|
+
|
113
|
+
# Check if a Proxy is registered
|
114
|
+
def has_proxy?(proxy_name)
|
115
|
+
@model.has_proxy?(proxy_name)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Register a Mediator with the View.
|
119
|
+
def register_mediator(mediator)
|
120
|
+
@view.register_mediator(mediator) unless @view.nil?
|
121
|
+
end
|
122
|
+
|
123
|
+
# Retrieve a Mediator from the View.
|
124
|
+
def retrieve_mediator(mediator_name)
|
125
|
+
@view.retrieve_mediator(mediator_name)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Remove a Mediator from the View.
|
129
|
+
def remove_mediator(mediator_name)
|
130
|
+
mediator = @view.remove_mediator(mediator_name) unless @view.nil?
|
131
|
+
mediator
|
132
|
+
end
|
133
|
+
|
134
|
+
# Check if a Mediator is registered or not
|
135
|
+
def has_mediator?(mediator_name)
|
136
|
+
@view.has_mediator?(mediator_name)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Create and send a Notification.
|
140
|
+
#
|
141
|
+
# Keeps us from having to construct new notification
|
142
|
+
# instances in our implementation code.
|
143
|
+
def send_notification(notification_name, body=nil, type=nil)
|
144
|
+
notify_observers(Notification.new(notification_name, body, type))
|
145
|
+
end
|
146
|
+
|
147
|
+
# Notify Observers.
|
148
|
+
#
|
149
|
+
# This method is left public mostly for backward compatibility, and to allow
|
150
|
+
# you to send custom notification classes using the facade.
|
151
|
+
#
|
152
|
+
# Usually you should just call send_notification and pass the parameters,
|
153
|
+
# never having to construct the notification yourself.
|
154
|
+
def notify_observers(notification)
|
155
|
+
@view.notify_observers(notification) unless @view.nil?
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
160
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
161
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Mediator < Notifier
|
2
|
+
|
3
|
+
# The name of the Mediator
|
4
|
+
# Typically, a Mediator will be written to serve one specific control or group
|
5
|
+
# controls and so,will not have a need to be dynamically named.
|
6
|
+
attr_accessor :name
|
7
|
+
attr_accessor :view
|
8
|
+
|
9
|
+
def initialize(name="Mediator", view=nil )
|
10
|
+
@name = name
|
11
|
+
@view = view
|
12
|
+
end
|
13
|
+
|
14
|
+
# List the Notification names this Mediator is interested in being notified of.
|
15
|
+
def list_notification_interests
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Handle Notifications.
|
20
|
+
#
|
21
|
+
# Typically this will be handled in a switch statement, with one 'case' entry
|
22
|
+
# per Notification the Mediator is interested in.
|
23
|
+
def handle_notification(note)
|
24
|
+
#override if you want to do something on this event
|
25
|
+
end
|
26
|
+
|
27
|
+
# Called by the View when the Mediator is registered
|
28
|
+
def on_register
|
29
|
+
#override if you want to do something on this event
|
30
|
+
end
|
31
|
+
|
32
|
+
# Called by the View when the Mediator is removed
|
33
|
+
def on_remove
|
34
|
+
#override if you want to do something on this event
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# PureMVC does not rely upon underlying event models such as the one provided with Flash.
|
2
|
+
#
|
3
|
+
# The Observer Pattern as implemented within PureMVC exists to support event-driven
|
4
|
+
# communication between the application and the actors of the MVC triad.
|
5
|
+
#
|
6
|
+
# Notifications are not meant to be a replacement for Events. Generally, Mediator
|
7
|
+
# implementors place event listeners on their view components, which they
|
8
|
+
# then handle in the usual way. This may lead to the broadcast of Notifications to
|
9
|
+
# trigger Commands or to communicate with other Mediators. Proxy and Command
|
10
|
+
# instances communicate with each other and Mediators by broadcasting Notifications.
|
11
|
+
#
|
12
|
+
# A key difference between UI Events and PureMVC Notifications is that Events
|
13
|
+
# follow the 'Chain of Responsibility' pattern, 'bubbling' up the display hierarchy
|
14
|
+
# until some parent component handles the Event, while PureMVC Notifications follow
|
15
|
+
# a 'Publish/Subscribe' pattern. PureMVC classes need not be related to each other in a
|
16
|
+
# parent/child relationship in order to communicate with one another using Notifications.
|
17
|
+
class Notification
|
18
|
+
|
19
|
+
attr_accessor :name, :body, :type
|
20
|
+
|
21
|
+
def initialize(name=nil, body=nil, type=nil)
|
22
|
+
@name = name
|
23
|
+
@body = body
|
24
|
+
@type = type
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get the string representation of the Notification instance.
|
28
|
+
def to_s
|
29
|
+
msg = "Notifcation Name: #{@name}"
|
30
|
+
msg += "\nBody: #{@body.inspect}"
|
31
|
+
msg += "\nType: #{@type.inspect}"
|
32
|
+
msg
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
37
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
38
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# MacroCommand, Command, Mediator and Proxy all have a need to send Notifications.
|
2
|
+
#
|
3
|
+
# The Notifier provides a common method called send_notification that relieves
|
4
|
+
# implementation code of the necessity to actually construct Notifications.
|
5
|
+
#
|
6
|
+
# The Notifier class, which all of the above mentioned classes extend, provides
|
7
|
+
# an initialized reference to the Facade Singleton, which is required for the
|
8
|
+
# convienience method for sending Notifications, but also eases implementation
|
9
|
+
# as these classes have frequent Facade interactions and usually require access
|
10
|
+
# to the facade anyway.
|
11
|
+
class Notifier
|
12
|
+
|
13
|
+
# Create and send an Notification.
|
14
|
+
#
|
15
|
+
# Keeps us from having to construct new Notification instances in our implementation code.
|
16
|
+
def send_notification(notification_name, body=nil, type=nil)
|
17
|
+
facade.send_notification(notification_name, body, type)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Local reference to the Facade Singleton
|
21
|
+
def facade
|
22
|
+
Facade.instance
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
26
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
27
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# An Observer is an object that encapsulates information about an interested object
|
2
|
+
# with a method that should be called when a particular Notification is broadcast.
|
3
|
+
#
|
4
|
+
# In PureMVC, the Observer class assumes these responsibilities:
|
5
|
+
# * Encapsulate the notification (callback) method of the interested object.
|
6
|
+
# * Encapsulate the notification context (this) of the interested object.
|
7
|
+
# * Provide methods for setting the notification method and context.
|
8
|
+
# * Provide a method for notifying the interested object.
|
9
|
+
class Observer
|
10
|
+
attr_accessor :notify, :context
|
11
|
+
|
12
|
+
# The notification method on the interested object should take
|
13
|
+
# one parameter of type Notification
|
14
|
+
def initialize(notify=nil, context=nil)
|
15
|
+
@notify = notify
|
16
|
+
@context = context
|
17
|
+
end
|
18
|
+
|
19
|
+
# Notify the interested object.
|
20
|
+
def notify_observer(notification)
|
21
|
+
@context.send(@notify, notification)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Compare an object to the notification context.
|
25
|
+
def compare_notify_context(object)
|
26
|
+
@context.equal?(object)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
30
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
31
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# In PureMVC, Proxy classes are used to manage parts of the application's data model.
|
2
|
+
#
|
3
|
+
# A Proxy might simply manage a reference to a local data object, in which case
|
4
|
+
# interacting with it might involve setting and getting of its data in synchronous
|
5
|
+
# fashion.
|
6
|
+
#
|
7
|
+
# Proxy classes are also used to encapsulate the application's interaction with
|
8
|
+
# remote services to save or retrieve data, in which case, we adopt an asyncronous
|
9
|
+
# idiom; setting data (or calling a method) on the Proxy and listening for a
|
10
|
+
# Notification to be sent when the Proxy has retrieved the data from the service.
|
11
|
+
class Proxy
|
12
|
+
|
13
|
+
attr_accessor :name, :data
|
14
|
+
def initialize(proxy_name, data=nil)
|
15
|
+
@name = proxy_name
|
16
|
+
@data = data
|
17
|
+
end
|
18
|
+
|
19
|
+
# Called by the Model when the Proxy is registered
|
20
|
+
def on_register
|
21
|
+
#override if you want to do something on this event
|
22
|
+
end
|
23
|
+
|
24
|
+
# Called by the Model when the Proxy is removed
|
25
|
+
def on_remove
|
26
|
+
#override if you want to do something on this event
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
# PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
31
|
+
# PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
32
|
+
# Your reuse is governed by the Creative Commons Attribution 3.0 License
|
data/version.txt
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
PureMVC Port to Ruby by Jake Dempsey <jake.dempsey@puremvc.org>
|
2
|
+
PureMVC - Copyright(c) 2006-2008 Futurescale, Inc., Some rights reserved.
|
3
|
+
--------------------------------------------------------------------------
|
4
|
+
Release Date: 1/14/09
|
5
|
+
Platform: Ruby
|
6
|
+
Version: 1
|
7
|
+
Revision: 0
|
8
|
+
Authors: Jake Dempsey <jake.dempsey@puremvc.org>
|
9
|
+
License: Creative Commons Attribution 3.0 Unported License
|
10
|
+
--------------------------------------------------------------------------
|
11
|
+
|
12
|
+
1.0 - Initial upload of ported code, equivalent to AS3 Standard Version 2.0.4.
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: puremvc-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jake Dempsey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-23 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: jake.dempsey@puremvc.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- version.txt
|
24
|
+
files:
|
25
|
+
- src/org
|
26
|
+
- src/org/puremvc
|
27
|
+
- src/org/puremvc/ruby
|
28
|
+
- src/org/puremvc/ruby/core
|
29
|
+
- src/org/puremvc/ruby/core/controller.rb
|
30
|
+
- src/org/puremvc/ruby/core/model.rb
|
31
|
+
- src/org/puremvc/ruby/core/view.rb
|
32
|
+
- src/org/puremvc/ruby/patterns
|
33
|
+
- src/org/puremvc/ruby/patterns/command
|
34
|
+
- src/org/puremvc/ruby/patterns/command/macro_command.rb
|
35
|
+
- src/org/puremvc/ruby/patterns/command/simple_command.rb
|
36
|
+
- src/org/puremvc/ruby/patterns/facade
|
37
|
+
- src/org/puremvc/ruby/patterns/facade/facade.rb
|
38
|
+
- src/org/puremvc/ruby/patterns/mediator
|
39
|
+
- src/org/puremvc/ruby/patterns/mediator/mediator.rb
|
40
|
+
- src/org/puremvc/ruby/patterns/observer
|
41
|
+
- src/org/puremvc/ruby/patterns/observer/notification.rb
|
42
|
+
- src/org/puremvc/ruby/patterns/observer/notifier.rb
|
43
|
+
- src/org/puremvc/ruby/patterns/observer/observer.rb
|
44
|
+
- src/org/puremvc/ruby/patterns/proxy
|
45
|
+
- src/org/puremvc/ruby/patterns/proxy/proxy.rb
|
46
|
+
- puremvc-ruby.rb
|
47
|
+
- version.txt
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: http://trac.puremvc.org/PureMVC_Ruby/
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
|
53
|
+
require_paths:
|
54
|
+
- .
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.1
|
71
|
+
signing_key:
|
72
|
+
specification_version: 2
|
73
|
+
summary: PureMVC is a lightweight framework for creating applications based upon the classic Model-View-Controller design meta-pattern. This is the specific implementation for the Ruby language based on the Standard Version AS3 reference.
|
74
|
+
test_files: []
|
75
|
+
|