Created
October 6, 2015 14:30
-
-
Save jdmorlan/a518446462fcc59fadde to your computer and use it in GitHub Desktop.
Naive implementation of Flux in Ruby for understanding
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Framework Code | |
class Operator | |
def initialize(dispatcher) | |
@dispatcher = dispatcher | |
@views = [] | |
end | |
def add_view(view) | |
@views.push(view) | |
end | |
def handle_event(resources, action) | |
@dispatcher.notify(Message.new(resources, action)) | |
end | |
end | |
class Dispatcher | |
def initialize | |
@stores = [] | |
end | |
def add_store(store) | |
@stores.push(store) | |
end | |
def notify(message) | |
@stores.each { |s| s.notify(message) } | |
end | |
end | |
class Action | |
def initialize(operation) | |
@operation = operation | |
end | |
# Need a waitFor method that allows you to specify | |
# the order that stores are updated. | |
end | |
class Message | |
attr_reader :data_types, :action | |
def initialize(data_types, action) | |
@data_types = data_types | |
@action = action | |
end | |
end | |
class Store | |
attr_reader :data_type | |
def initialize(data_type) | |
@data = [] | |
@actions = {} | |
@store_type = data_type.to_s.downcase.to_sym | |
end | |
def add(obj) | |
@data.push(obj) | |
end | |
def add_action(name, action) | |
@actions[name] = action | |
end | |
# Define what you want to happen to the list of items when | |
# a specific action is called on the store. | |
def notify(message) | |
if message.data_types.include?(@store_type) | |
action = @actions.fetch(message.action) | |
if !action.nil? | |
action.call(@data, @store_type) | |
end | |
end | |
end | |
end | |
class View | |
def initialize(operator) | |
@operator = operator | |
end | |
def handle_event(resource, action) | |
@operator.handle_event(resource, action) | |
end | |
end | |
# User Defined Classes | |
class Book | |
attr_reader :title | |
def initialize(title) | |
@title = title | |
end | |
end | |
class Movie | |
attr_reader :title, :budget | |
def initialize(title, budget) | |
@title = title | |
@budget = budget | |
end | |
end | |
class BookView < View | |
def initialize(operator) | |
super(operator) | |
end | |
def display_books_event | |
handle_event([:book], :display) | |
end | |
end | |
class MovieView < View | |
def initialize(operator) | |
super(operator) | |
end | |
def display_movies_event | |
handle_event([:movie], :display) | |
end | |
def display_low_budget_event | |
handle_event([:movie], :low_budget) | |
end | |
end | |
# Wiring everything up | |
book_one = Book.new('Tale of Two Citites') | |
book_two = Book.new('To Kill A Mockingbird') | |
movie_one = Movie.new('Inception', 100) | |
movie_two = Movie.new('Forest Gump', 33) | |
book_store = Store.new(Book) | |
movie_store = Store.new(Movie) | |
book_store.add(book_one) | |
book_store.add(book_two) | |
movie_store.add(movie_one) | |
movie_store.add(movie_two) | |
display = lambda do |items, store| | |
puts "***** Display Items From #{store} *****" | |
items.each do |item| | |
puts item.title | |
end | |
end | |
getLowBudgetMovies = lambda do |movies, store| | |
puts "***** Low Budget Films *****" | |
movies.select { |m| m.budget <= 44 } | |
.each { |m| puts m.title } | |
end | |
book_store.add_action(:display, display) | |
movie_store.add_action(:display, display) | |
movie_store.add_action(:low_budget, getLowBudgetMovies) | |
dispatcher = Dispatcher.new | |
dispatcher.add_store(book_store) | |
dispatcher.add_store(movie_store) | |
operator = Operator.new(dispatcher) | |
movie_view = MovieView.new(operator) | |
book_view = BookView.new(operator) | |
# Calling Events on the View | |
book_view.display_books_event | |
movie_view.display_movies_event | |
movie_view.display_low_budget_event# Framework Code | |
class Operator | |
def initialize(dispatcher) | |
@dispatcher = dispatcher | |
@views = [] | |
end | |
def add_view(view) | |
@views.push(view) | |
end | |
def handle_event(resources, action) | |
@dispatcher.notify(Message.new(resources, action)) | |
end | |
end | |
class Dispatcher | |
def initialize | |
@stores = [] | |
end | |
def add_store(store) | |
@stores.push(store) | |
end | |
def notify(message) | |
@stores.each { |s| s.notify(message) } | |
end | |
end | |
class Action | |
def initialize(operation) | |
@operation = operation | |
end | |
# Need a waitFor method that allows you to specify | |
# the order that stores are updated. | |
end | |
class Message | |
attr_reader :data_types, :action | |
def initialize(data_types, action) | |
@data_types = data_types | |
@action = action | |
end | |
end | |
class Store | |
attr_reader :data_type | |
def initialize(data_type) | |
@data = [] | |
@actions = {} | |
@store_type = data_type.to_s.downcase.to_sym | |
end | |
def add(obj) | |
@data.push(obj) | |
end | |
def add_action(name, action) | |
@actions[name] = action | |
end | |
# Define what you want to happen to the list of items when | |
# a specific action is called on the store. | |
def notify(message) | |
if message.data_types.include?(@store_type) | |
action = @actions.fetch(message.action) | |
if !action.nil? | |
action.call(@data, @store_type) | |
end | |
end | |
end | |
end | |
class View | |
def initialize(operator) | |
@operator = operator | |
end | |
def handle_event(resource, action) | |
@operator.handle_event(resource, action) | |
end | |
end | |
# User Defined Classes | |
class Book | |
attr_reader :title | |
def initialize(title) | |
@title = title | |
end | |
end | |
class Movie | |
attr_reader :title, :budget | |
def initialize(title, budget) | |
@title = title | |
@budget = budget | |
end | |
end | |
class BookView < View | |
def initialize(operator) | |
super(operator) | |
end | |
def display_books_event | |
handle_event([:book], :display) | |
end | |
end | |
class MovieView < View | |
def initialize(operator) | |
super(operator) | |
end | |
def display_movies_event | |
handle_event([:movie], :display) | |
end | |
def display_low_budget_event | |
handle_event([:movie], :low_budget) | |
end | |
end | |
# Wiring everything up | |
book_one = Book.new('Tale of Two Citites') | |
book_two = Book.new('To Kill A Mockingbird') | |
movie_one = Movie.new('Inception', 100) | |
movie_two = Movie.new('Forest Gump', 33) | |
book_store = Store.new(Book) | |
movie_store = Store.new(Movie) | |
book_store.add(book_one) | |
book_store.add(book_two) | |
movie_store.add(movie_one) | |
movie_store.add(movie_two) | |
display = lambda do |items, store| | |
puts "***** Display Items From #{store} *****" | |
items.each do |item| | |
puts item.title | |
end | |
end | |
getLowBudgetMovies = lambda do |movies, store| | |
puts "***** Low Budget Films *****" | |
movies.select { |m| m.budget <= 44 } | |
.each { |m| puts m.title } | |
end | |
book_store.add_action(:display, display) | |
movie_store.add_action(:display, display) | |
movie_store.add_action(:low_budget, getLowBudgetMovies) | |
dispatcher = Dispatcher.new | |
dispatcher.add_store(book_store) | |
dispatcher.add_store(movie_store) | |
operator = Operator.new(dispatcher) | |
movie_view = MovieView.new(operator) | |
book_view = BookView.new(operator) | |
# Calling Events on the View | |
book_view.display_books_event | |
movie_view.display_movies_event | |
movie_view.display_low_budget_event |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment