Remove Ruby implementation... *sniff*

This commit is contained in:
Joe Cheng
2012-06-26 21:56:13 -07:00
parent 6955573dd0
commit 6a394cc30e
7 changed files with 0 additions and 398 deletions

View File

@@ -1,5 +0,0 @@
source 'https://rubygems.org'
gem 'em-websocket'
gem 'eventmachine_httpserver'
gem 'json'

View File

@@ -1,18 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.2.8)
em-websocket (0.3.6)
addressable (>= 2.1.1)
eventmachine (>= 0.12.9)
eventmachine (0.12.10)
eventmachine_httpserver (0.2.1)
json (1.7.3)
PLATFORMS
ruby
DEPENDENCIES
em-websocket
eventmachine_httpserver
json

19
hash.rb
View File

@@ -1,19 +0,0 @@
require 'shiny'
require 'digest/sha1'
require 'digest/md5'
shinyapp = ShinyApp.new
input1 = React::ObservableValue.new {
shinyapp.session.get('input1') + (shinyapp.session.get('addnewline') ? "\n" : '')
}
shinyapp.define_output('md5_hash') do
Digest::MD5.hexdigest(input1.value)
end
shinyapp.define_output('sha1_hash') do
Digest::SHA1.hexdigest(input1.value)
end
shinyapp.run

View File

@@ -1,172 +0,0 @@
module React
class Context
private
@@next_id = 0
@@current_context = nil
@@pending_invalidate = []
public
def self.current!
return current || raise("No current context")
end
def self.current
@@current_context
end
attr_reader :id
def initialize
# The ID can used to identify/sort/dedupe contexts
@id = @@next_id += 1
# Indicates whether this context is invalidated, i.e. its
# callbacks have been called or are about to be called
@invalidated = false
# List of callbacks to be called after invalidation
@callbacks = []
end
# Run a block with this context as the current context. The
# original current context will be restored after the block
# is executed.
def run
old_ctx = @@current_context
@@current_context = self
begin
return yield
ensure
@@current_context = old_ctx
end
end
def invalidate
return if @invalidated
@invalidated = true
@@pending_invalidate << self
end
# Register a callback to be called after this context is
# invalidated (or immediately if it's already invalidated).
# The callback takes one argument, the context.
def on_invalidate(&callback)
if @invalidated
callback.call(self)
else
@callbacks << callback
end
end
def execute_callbacks
@callbacks.each {|callback| callback.call(self)}
end
# Execute all callbacks on invalidated contexts. Will do this
# repeatedly if the callbacks themselves cause more invalidations.
def self.flush
while !@@pending_invalidate.empty?
contexts = @@pending_invalidate
@@pending_invalidate = []
contexts.each {|context| context.execute_callbacks}
end
end
end
class Session
def initialize
# Key is variable name, value is variable value
@values = Hash.new
# Key is variable name, value is { Context IDs => Contexts }
@dependencies = Hash.new
end
def get(name)
cur_ctx = React::Context.current!
@dependencies[name] = @dependencies[name] || Hash.new
if !@dependencies[name].has_key?(cur_ctx.id)
@dependencies[name][cur_ctx.id] = cur_ctx
cur_ctx.on_invalidate do
@dependencies[name].delete(cur_ctx.id)
end
end
return @values[name]
end
def set(name, value)
if @values.has_key?(name) && @values[name] == value
return
end
@values[name] = value
if @dependencies[name]
@dependencies[name].each_value {|ctx| ctx.invalidate}
end
end
end
# Stores (and caches) a single dependent value in a context
class ObservableValue
def initialize(&valueProc)
@valueProc = valueProc
@dependencies = Hash.new
@initialized = false
end
def value
if !@initialized
@initialized = true
update_value
end
cur_ctx = React::Context.current!
@dependencies[cur_ctx.id] = cur_ctx
cur_ctx.on_invalidate do
@dependencies.delete cur_ctx.id
end
@value
end
private
def update_value
old_value = @value
ctx = Context.new
ctx.on_invalidate do
update_value
end
ctx.run do
@value = @valueProc.call
end
if old_value != @value
@dependencies.each_value {|dep_ctx| dep_ctx.invalidate}
end
end
end
# Runs the given proc whenever its dependencies change
class Observer
def initialize(&proc)
@proc = proc
run
end
def run
ctx = React::Context.new
ctx.on_invalidate do
run
end
ctx.run &@proc
end
end
end

View File

@@ -1,156 +0,0 @@
require 'eventmachine'
require 'evma_httpserver'
require 'em-websocket'
require 'pathname'
require 'json'
require 'react'
class WebServer < EM::Connection
include EM::HttpServer
def post_init
super
no_environment_strings
@basepath = File.join(Dir.pwd, 'www')
end
def resolve_path(path)
# It's not a valid path if it doesn't start with /
return nil if path !~ /^\//
abspath = File.join(@basepath, "./#{path}")
# Resolves '..', etc.
abspath = Pathname.new(abspath).cleanpath.to_s
return false if abspath[0...(@basepath.size + 1)] != @basepath + '/'
return false if !File.exist?(abspath)
return abspath
end
def process_http_request
# the http request details are available via the following instance variables:
# @http_protocol
# @http_request_method
# @http_cookie
# @http_if_none_match
# @http_content_type
# @http_path_info
# @http_request_uri
# @http_query_string
# @http_post_content
# @http_headers
response = EM::DelegatedHttpResponse.new(self)
path = @http_path_info
path = '/index.html' if path == '/'
resolved_path = resolve_path(path)
if !resolved_path
response.status = 404
response.content_type 'text/html'
response.content = '<h1>404 Not Found</h1>'
else
response.status = 200
response.content_type case resolved_path
when /\.html?$/
'text/html'
when /\.js$/
'text/javascript'
when /\.css$/
'text/css'
when /\.png$/
'image/png'
when /\.jpg$/
'image/jpeg'
when /\.gif$/
'image/gif'
end
response.content = File.read(resolved_path)
end
response.send_response
end
end
def run_shiny_app(shinyapp)
EventMachine.run do
EventMachine.start_server '0.0.0.0', 8100, WebServer
puts "Listening on port 8100"
EventMachine::WebSocket.start(:host => '0.0.0.0', :port => 8101) do |ws|
shinyapp.websocket = ws
ws.onclose { exit(0) }
ws.onmessage do |msg|
begin
puts "RECV: #{msg}"
msg_obj = JSON.parse(msg)
case msg_obj['method']
when 'init'
msg_obj['data'].each do |k, v|
shinyapp.session.set(k, v)
end
React::Context.flush
shinyapp.instantiate_outputs
when 'update'
msg_obj['data'].each do |k, v|
shinyapp.session.set(k, v)
end
end
React::Context.flush
shinyapp.flush_output
rescue Exception => e
puts "ERROR: #{e}"
puts e.backtrace.collect {|x| "\t#{x}"}
raise
end
end
end
end
end
class ShinyApp
attr_reader :session
def initialize
@session = React::Session.new
@outputs = {}
@invalidated_output_values = Hash.new
end
def websocket=(value)
@websocket = value
end
def define_output(name, &proc)
@outputs[name] = proc
end
def instantiate_outputs
@outputs.keys.each do |name|
proc = @outputs.delete(name)
React::Observer.new do
value = proc.call
@invalidated_output_values[name] = value
end
end
end
def flush_output
return if @invalidated_output_values.empty?
data = @invalidated_output_values
@invalidated_output_values = Hash.new
puts "SEND: #{JSON.generate(data)}"
@websocket.send(JSON.generate(data))
end
def run
run_shiny_app self
end
end

View File

@@ -1,23 +0,0 @@
require 'react'
include React
def print_observable_value(obsVal)
Observer.new { puts obsVal.value }
end
sess = Session.new
sess.set('user', '')
user = ObservableValue.new { sess.get('user') }
user_caps = ObservableValue.new { user.value.upcase }
# This will print the value not just once, but every
# time the value changes
print_observable_value(user_caps)
sess.set('user', 'jcheng')
Context.flush # pay no attention to the man behind the curtain
sess.set('user', 'jjallaire')
sess.set('user', 'jwpaulson')
Context.flush

5
run.sh
View File

@@ -1,5 +0,0 @@
#!/bin/sh
SCRIPT=${1:-hash.rb}
bundle exec ruby -Ilib "$SCRIPT"