Skip to content

Instantly share code, notes, and snippets.

@jdmorlan
Created October 6, 2015 14:30
Show Gist options
  • Save jdmorlan/a518446462fcc59fadde to your computer and use it in GitHub Desktop.
Save jdmorlan/a518446462fcc59fadde to your computer and use it in GitHub Desktop.
Naive implementation of Flux in Ruby for understanding
# 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