Skip to content

Instantly share code, notes, and snippets.

@scizo
Created April 25, 2012 01:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scizo/2485396 to your computer and use it in GitHub Desktop.
Save scizo/2485396 to your computer and use it in GitHub Desktop.
Observer / Tk Demo
require 'observer'
class TestObservable
include Observable
def initialize(name)
@name = name
end
def change_with(value)
changed
notify_observers @name, value
end
end
class TestObserver
def initialize(name)
@name = name
end
def update(observable, value)
puts "Observer #{@name} observered #{observable} change with #{value}"
end
end
# Make observables
bill = TestObservable.new('Bill')
fred = TestObservable.new('Fred')
# Make observers
john = TestObserver.new('John')
bill.add_observer(john)
fred.add_observer(john)
will = TestObserver.new('Will')
bill.add_observer(will)
fred.add_observer(will)
# Change the observables
bill.change_with(12)
fred.change_with(9001)
require 'tk'
require 'observer'
class StockPrice
def self.fetch(symbol)
60 + rand(80)
end
end
class Ticker
include Observable
@mutex = Mutex.new
@tickers = {}
class << self
def ticker(symbol)
@mutex.synchronize do
return @tickers[symbol] if @tickers[symbol]
@tickers[symbol] = Ticker.new(symbol)
end
end
def run
Thread.new do
loop do
fetch_stocks
sleep 2
end
end
end
def fetch_stocks
@mutex.synchronize do
@tickers.each do |symbol, ticker|
ticker.price = StockPrice.fetch(symbol)
end
end
end
end
attr_reader :symbol, :price
def initialize(symbol)
@symbol = symbol
end
def price=(price)
unless @price == price
changed # Must call changed in order for observers to actually be notified
@price = price
notify_observers(@price)
end
end
end
class StockViewer
def initialize(root, row, ticker)
@symbol_label = TkLabel.new(root) do
text ticker.symbol
grid({
:row => row,
:column => 1,
:stick => 'nsew'
})
end
@price_label = TkLabel.new(root) do
text 'waiting...'
grid({
:row => row,
:column => 2,
:stick => 'nsew'
})
end
ticker.add_observer(self)
end
def update(price)
@price_label.text price
end
end
class Application
def add_stock(entry)
ticker = Ticker.ticker(entry.value)
StockViewer.new(@root, @row, ticker)
@row += 1
entry.value = ""
end
def initialize
@row = 2
@root = TkRoot.new do
title "Stock Watcher"
end
TkGrid.columnconfigure(@root, 1, :weight => 1)
TkGrid.columnconfigure(@root, 2, :weight => 1)
entry = TkEntry.new(@root) do
width 10
grid({
:row => 1,
:column => 1,
:sticky => 'nsew'
})
end
handler = proc { add_stock(entry) }
TkButton.new(@root) do
text "Add Stock"
grid({
:row => 1,
:column => 2,
:sticky => 'nsew'
})
command handler
end
Ticker.run
Tk.mainloop
end
end
Application.new
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment