Compare commits
48 Commits
new-volt
...
diy-render
Author | SHA1 | Date | |
---|---|---|---|
c0bdfe149c | |||
5ec7ea6d56 | |||
ee788b3507 | |||
85e099382d | |||
7d214e7013 | |||
c5a07be6ac | |||
b3de7c9b5e | |||
516b041bed | |||
a25d292e1f | |||
167353fdf3 | |||
95c4d656b3 | |||
3319b0cd98 | |||
7820c5eff0 | |||
a56e811699 | |||
83e0c8a925 | |||
7885ae93c4 | |||
caa1da342c | |||
b8a0e5f8a3 | |||
b43bffc940 | |||
1ad5681827 | |||
cf1d32e520 | |||
68f67eda54 | |||
ed2a054ca6 | |||
3fa685a0bb | |||
0d4813df13 | |||
5f2f35cbcf | |||
15fd4ea7c6 | |||
b21ca406c8 | |||
6925a3fefa | |||
c49c73bb3d | |||
8b743fbcd5 | |||
977156ba51 | |||
287277ef59 | |||
0e430e8b00 | |||
a6c22cf6e0 | |||
5c60f29fbf | |||
87c649c622 | |||
1f7c06d626 | |||
ef1235d3e8 | |||
ef60cbdc45 | |||
e7e85b8d73 | |||
bb5caa9bf1 | |||
3c959fecb2 | |||
4257bc446f | |||
a49ef347ff | |||
71ed4f60d7 | |||
7d2120fdd5 | |||
9af1937a71 |
38
Gemfile
38
Gemfile
@ -1,27 +1,17 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem 'volt', :path => "../volt"
|
gem "opal" , :github => "opal/opal"
|
||||||
|
gem 'opal-browser'
|
||||||
# volt uses mongo as the default data store.
|
|
||||||
gem 'volt-mongo', '~> 0.1.0'
|
|
||||||
|
|
||||||
# The following gem's are optional for themeing
|
|
||||||
# Twitter bootstrap
|
|
||||||
gem 'volt-bootstrap', '~> 0.0.10'
|
|
||||||
|
|
||||||
# Asset compilation gems, they will be required when needed.
|
|
||||||
gem 'csso-rails', '~> 0.3.4', require: false
|
|
||||||
gem 'uglifier', '>= 2.4.0', require: false
|
|
||||||
|
|
||||||
gem 'opal-pixi' , :path => "../opal-pixi"
|
|
||||||
|
|
||||||
#gem "salama" , "0.2" , :path => "../salama"
|
#gem "salama" , "0.2" , :path => "../salama"
|
||||||
|
|
||||||
gem "parslet" , path: "../parslet"
|
gem "parslet" , github: "salama/parslet"
|
||||||
gem "salama" , path: "../salama"
|
gem "salama" , github: "salama/salama"
|
||||||
gem "salama-reader" , path: "../salama-reader"
|
gem "salama-reader" , github: "salama/salama-reader"
|
||||||
gem "salama-object-file" , path: "../salama-object-file"
|
gem "salama-arm" , github: "salama/salama-arm"
|
||||||
|
gem "salama-object-file" , github: "salama/salama-object-file"
|
||||||
|
gem "sass"
|
||||||
|
gem "susy"
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
# Testing dependencies
|
# Testing dependencies
|
||||||
@ -32,13 +22,3 @@ group :test do
|
|||||||
gem 'chromedriver2-helper', '~> 0.0.8'
|
gem 'chromedriver2-helper', '~> 0.0.8'
|
||||||
gem 'poltergeist', '~> 1.5.0'
|
gem 'poltergeist', '~> 1.5.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Server for MRI
|
|
||||||
platform :mri, :mingw do
|
|
||||||
# The implementation of ReadWriteLock in Volt uses concurrent ruby and ext helps performance.
|
|
||||||
gem 'concurrent-ruby-ext', '~> 0.8.0'
|
|
||||||
|
|
||||||
# Thin is the default volt server, Puma is also supported
|
|
||||||
gem 'thin', '~> 1.6.0'
|
|
||||||
gem 'bson_ext', '~> 1.9.0'
|
|
||||||
end
|
|
||||||
|
156
Gemfile.lock
156
Gemfile.lock
@ -1,56 +1,49 @@
|
|||||||
PATH
|
GIT
|
||||||
remote: ../opal-pixi
|
remote: git://github.com/opal/opal.git
|
||||||
|
revision: c604685071f8560d3357044683a99b80b210a99b
|
||||||
specs:
|
specs:
|
||||||
opal-pixi (0.1.0)
|
opal (0.9.0.dev)
|
||||||
opal (~> 0.7.0)
|
hike (~> 1.2)
|
||||||
|
sourcemap (~> 0.1.0)
|
||||||
|
sprockets (~> 3.1)
|
||||||
|
tilt (>= 1.4)
|
||||||
|
|
||||||
PATH
|
GIT
|
||||||
remote: ../parslet
|
remote: git://github.com/salama/parslet.git
|
||||||
|
revision: b8bf8db20a242eb6bd8fec88027e3b2ae19276e8
|
||||||
specs:
|
specs:
|
||||||
parslet (1.7.0)
|
parslet (1.7.0)
|
||||||
|
|
||||||
PATH
|
GIT
|
||||||
remote: ../salama
|
remote: git://github.com/salama/salama-arm.git
|
||||||
|
revision: 0bd5091e3f284ecf040e0086a41d2449cd5afb7a
|
||||||
|
specs:
|
||||||
|
salama-arm (0.0.1)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/salama/salama-object-file.git
|
||||||
|
revision: fbae6a02764dbe97e01e4833f9ffffe09879b100
|
||||||
|
specs:
|
||||||
|
salama-object-file (0.2.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/salama/salama-reader.git
|
||||||
|
revision: 841592c667acea1e796f950851262e6938b231bc
|
||||||
|
specs:
|
||||||
|
salama-reader (0.2.0)
|
||||||
|
parslet (~> 1.7.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/salama/salama.git
|
||||||
|
revision: df95b8b54de103523743cbfd5c46d87af84c6b09
|
||||||
specs:
|
specs:
|
||||||
salama (0.2.0)
|
salama (0.2.0)
|
||||||
salama-object-file (~> 0.2)
|
salama-object-file (~> 0.2)
|
||||||
salama-reader (~> 0.2)
|
salama-reader (~> 0.2)
|
||||||
|
|
||||||
PATH
|
|
||||||
remote: ../salama-object-file
|
|
||||||
specs:
|
|
||||||
salama-object-file (0.2.0)
|
|
||||||
|
|
||||||
PATH
|
|
||||||
remote: ../salama-reader
|
|
||||||
specs:
|
|
||||||
salama-reader (0.2.0)
|
|
||||||
parslet (~> 1.7.0)
|
|
||||||
|
|
||||||
PATH
|
|
||||||
remote: ../volt
|
|
||||||
specs:
|
|
||||||
volt (0.9.4)
|
|
||||||
bcrypt (~> 3.1.9)
|
|
||||||
bundler (>= 1.5)
|
|
||||||
concurrent-ruby (= 0.8.0)
|
|
||||||
configurations (~> 2.0.0.pre)
|
|
||||||
faye-websocket (~> 0.9.2)
|
|
||||||
listen (~> 3.0.1)
|
|
||||||
opal (~> 0.7.2)
|
|
||||||
pry (~> 0.10.1)
|
|
||||||
rack (~> 1.5.0)
|
|
||||||
sass (~> 3.2.5)
|
|
||||||
sprockets-sass (~> 1.0.0)
|
|
||||||
thor (~> 0.19.0)
|
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
bcrypt (3.1.10)
|
|
||||||
bson (1.9.2)
|
|
||||||
bson_ext (1.9.2)
|
|
||||||
bson (~> 1.9.2)
|
|
||||||
capybara (2.4.4)
|
capybara (2.4.4)
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
nokogiri (>= 1.3.3)
|
nokogiri (>= 1.3.3)
|
||||||
@ -62,58 +55,28 @@ GEM
|
|||||||
chromedriver2-helper (0.0.8)
|
chromedriver2-helper (0.0.8)
|
||||||
nokogiri
|
nokogiri
|
||||||
cliver (0.3.2)
|
cliver (0.3.2)
|
||||||
coderay (1.1.0)
|
|
||||||
concurrent-ruby (0.8.0)
|
|
||||||
ref (~> 1.0, >= 1.0.5)
|
|
||||||
concurrent-ruby-ext (0.8.0)
|
|
||||||
concurrent-ruby (~> 0.8.0)
|
|
||||||
configurations (2.0.0)
|
|
||||||
csso-rails (0.3.4)
|
|
||||||
execjs (>= 1)
|
|
||||||
daemons (1.2.3)
|
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.2.5)
|
||||||
eventmachine (1.0.7)
|
|
||||||
execjs (2.5.2)
|
|
||||||
faye-websocket (0.9.2)
|
|
||||||
eventmachine (>= 0.12.0)
|
|
||||||
websocket-driver (>= 0.5.1)
|
|
||||||
ffi (1.9.10)
|
ffi (1.9.10)
|
||||||
hike (1.2.3)
|
hike (1.2.3)
|
||||||
json (1.8.3)
|
|
||||||
listen (3.0.2)
|
|
||||||
rb-fsevent (>= 0.9.3)
|
|
||||||
rb-inotify (>= 0.9)
|
|
||||||
method_source (0.8.2)
|
|
||||||
mime-types (2.6.1)
|
mime-types (2.6.1)
|
||||||
mini_portile (0.6.2)
|
mini_portile (0.6.2)
|
||||||
mongo (1.9.2)
|
|
||||||
bson (~> 1.9.2)
|
|
||||||
multi_json (1.11.2)
|
multi_json (1.11.2)
|
||||||
nokogiri (1.6.6.2)
|
nokogiri (1.6.6.2)
|
||||||
mini_portile (~> 0.6.0)
|
mini_portile (~> 0.6.0)
|
||||||
opal (0.7.2)
|
opal-browser (0.2.0)
|
||||||
hike (~> 1.2)
|
opal
|
||||||
sourcemap (~> 0.1.0)
|
paggio
|
||||||
sprockets (>= 2.2.3, < 3.0.0)
|
|
||||||
tilt (~> 1.4)
|
|
||||||
opal-rspec (0.4.3)
|
opal-rspec (0.4.3)
|
||||||
opal (>= 0.7.0, < 0.9)
|
opal (>= 0.7.0, < 0.9)
|
||||||
|
paggio (0.2.4)
|
||||||
poltergeist (1.5.1)
|
poltergeist (1.5.1)
|
||||||
capybara (~> 2.1)
|
capybara (~> 2.1)
|
||||||
cliver (~> 0.3.1)
|
cliver (~> 0.3.1)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
websocket-driver (>= 0.2.0)
|
websocket-driver (>= 0.2.0)
|
||||||
pry (0.10.1)
|
rack (1.6.4)
|
||||||
coderay (~> 1.1.0)
|
|
||||||
method_source (~> 0.8.1)
|
|
||||||
slop (~> 3.4)
|
|
||||||
rack (1.5.5)
|
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rb-fsevent (0.9.5)
|
|
||||||
rb-inotify (0.9.5)
|
|
||||||
ffi (>= 0.5.0)
|
|
||||||
ref (1.0.5)
|
|
||||||
rspec (3.2.0)
|
rspec (3.2.0)
|
||||||
rspec-core (~> 3.2.0)
|
rspec-core (~> 3.2.0)
|
||||||
rspec-expectations (~> 3.2.0)
|
rspec-expectations (~> 3.2.0)
|
||||||
@ -128,34 +91,18 @@ GEM
|
|||||||
rspec-support (~> 3.2.0)
|
rspec-support (~> 3.2.0)
|
||||||
rspec-support (3.2.2)
|
rspec-support (3.2.2)
|
||||||
rubyzip (1.1.7)
|
rubyzip (1.1.7)
|
||||||
sass (3.2.19)
|
sass (3.4.16)
|
||||||
selenium-webdriver (2.43.0)
|
selenium-webdriver (2.43.0)
|
||||||
childprocess (~> 0.5)
|
childprocess (~> 0.5)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
rubyzip (~> 1.0)
|
rubyzip (~> 1.0)
|
||||||
websocket (~> 1.0)
|
websocket (~> 1.0)
|
||||||
slop (3.6.0)
|
|
||||||
sourcemap (0.1.1)
|
sourcemap (0.1.1)
|
||||||
sprockets (2.12.4)
|
sprockets (3.3.2)
|
||||||
hike (~> 1.2)
|
|
||||||
multi_json (~> 1.0)
|
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (~> 1.1, != 1.3.0)
|
susy (2.2.5)
|
||||||
sprockets-sass (1.0.3)
|
sass (>= 3.3.0, < 3.5)
|
||||||
sprockets (~> 2.0)
|
tilt (2.0.1)
|
||||||
tilt (~> 1.1)
|
|
||||||
thin (1.6.3)
|
|
||||||
daemons (~> 1.0, >= 1.0.9)
|
|
||||||
eventmachine (~> 1.0)
|
|
||||||
rack (~> 1.0)
|
|
||||||
thor (0.19.1)
|
|
||||||
tilt (1.4.1)
|
|
||||||
uglifier (2.7.1)
|
|
||||||
execjs (>= 0.3.0)
|
|
||||||
json (>= 1.8.0)
|
|
||||||
volt-bootstrap (0.0.10)
|
|
||||||
volt-mongo (0.1.1)
|
|
||||||
mongo (~> 1.9.0)
|
|
||||||
websocket (1.2.2)
|
websocket (1.2.2)
|
||||||
websocket-driver (0.5.4)
|
websocket-driver (0.5.4)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
@ -167,22 +114,21 @@ PLATFORMS
|
|||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
bson_ext (~> 1.9.0)
|
|
||||||
capybara (~> 2.4.2)
|
capybara (~> 2.4.2)
|
||||||
chromedriver2-helper (~> 0.0.8)
|
chromedriver2-helper (~> 0.0.8)
|
||||||
concurrent-ruby-ext (~> 0.8.0)
|
opal!
|
||||||
csso-rails (~> 0.3.4)
|
opal-browser
|
||||||
opal-pixi!
|
|
||||||
opal-rspec (~> 0.4.2)
|
opal-rspec (~> 0.4.2)
|
||||||
parslet!
|
parslet!
|
||||||
poltergeist (~> 1.5.0)
|
poltergeist (~> 1.5.0)
|
||||||
rspec (~> 3.2.0)
|
rspec (~> 3.2.0)
|
||||||
salama!
|
salama!
|
||||||
|
salama-arm!
|
||||||
salama-object-file!
|
salama-object-file!
|
||||||
salama-reader!
|
salama-reader!
|
||||||
|
sass
|
||||||
selenium-webdriver (~> 2.43.0)
|
selenium-webdriver (~> 2.43.0)
|
||||||
thin (~> 1.6.0)
|
susy
|
||||||
uglifier (>= 2.4.0)
|
|
||||||
volt!
|
BUNDLED WITH
|
||||||
volt-bootstrap (~> 0.0.10)
|
1.10.5
|
||||||
volt-mongo (~> 0.1.0)
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
// Place your apps css here
|
|
Binary file not shown.
Before Width: | Height: | Size: 237 B |
File diff suppressed because it is too large
Load Diff
@ -1,8 +0,0 @@
|
|||||||
# Specify which components you wish to include when
|
|
||||||
# the "home" component loads.
|
|
||||||
|
|
||||||
# bootstrap css framework
|
|
||||||
component 'bootstrap'
|
|
||||||
|
|
||||||
|
|
||||||
Opal.use_gem("salama")
|
|
@ -1,10 +0,0 @@
|
|||||||
# Place any code you want to run when the component is included on the client
|
|
||||||
# or server.
|
|
||||||
|
|
||||||
# To include code only on the client use:
|
|
||||||
# if RUBY_PLATFORM == 'opal'
|
|
||||||
#
|
|
||||||
# To include code only on the server, use:
|
|
||||||
# unless RUBY_PLATFORM == 'opal'
|
|
||||||
# ^^ this will not send compile in code in the conditional to the client.
|
|
||||||
# ^^ this include code required in the conditional.
|
|
@ -1,7 +0,0 @@
|
|||||||
# See https://github.com/voltrb/volt#routes for more info on routes
|
|
||||||
|
|
||||||
client '/about', action: 'about'
|
|
||||||
|
|
||||||
# The main route, this should be last. It will match any params not
|
|
||||||
# previously matched.
|
|
||||||
client '/', {}
|
|
@ -1,36 +0,0 @@
|
|||||||
# By default Volt generates this controller for your Main component
|
|
||||||
require "salama"
|
|
||||||
|
|
||||||
if RUBY_PLATFORM == 'opal'
|
|
||||||
require "main/lib/main_view"
|
|
||||||
end
|
|
||||||
|
|
||||||
Virtual::Machine.boot
|
|
||||||
|
|
||||||
module Main
|
|
||||||
class MainController < Volt::ModelController
|
|
||||||
|
|
||||||
def index
|
|
||||||
MainView.new()
|
|
||||||
end
|
|
||||||
|
|
||||||
def about
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# The main template contains a #template binding that shows another
|
|
||||||
# template. This is the path to that template. It may change based
|
|
||||||
# on the params._component, params._controller, and params._action values.
|
|
||||||
def main_path
|
|
||||||
"#{params._component || 'main'}/#{params._controller || 'main'}/#{params._action || 'index'}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Determine if the current nav component is the active one by looking
|
|
||||||
# at the first part of the url against the href attribute.
|
|
||||||
def active_tab?
|
|
||||||
url.path.split('/')[1] == attrs.href.split('/')[1]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,46 +0,0 @@
|
|||||||
require 'opal/pixi'
|
|
||||||
require 'native'
|
|
||||||
require "salama"
|
|
||||||
|
|
||||||
require_relative "registers_view"
|
|
||||||
require_relative "object_view"
|
|
||||||
require_relative "space_view"
|
|
||||||
|
|
||||||
class MainView
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@container = PIXI::Container.new
|
|
||||||
|
|
||||||
height = `window.innerHeight`
|
|
||||||
width = `window.innerWidth`
|
|
||||||
renderer = PIXI::WebGLRenderer.new( width - 100 , height - 100, {"backgroundColor" => 0xFFFFFF})
|
|
||||||
body = Native(`window.document.body`)
|
|
||||||
# bit of a hack as it assumes index's structure
|
|
||||||
html_con = body.firstElementChild
|
|
||||||
html_con.insertBefore renderer.view , html_con.lastElementChild
|
|
||||||
|
|
||||||
registers = RegisterView.new(height - 150)
|
|
||||||
@container.add_child registers
|
|
||||||
|
|
||||||
ParseTask.parse(1).then do |result|
|
|
||||||
is = Ast::Expression.from_basic(result)
|
|
||||||
Virtual::Compiler.compile( is , Virtual.machine.space.get_main )
|
|
||||||
Virtual.machine.run_before Virtual::Machine::FIRST_PASS
|
|
||||||
end.fail do |error|
|
|
||||||
raise "Error: #{error}"
|
|
||||||
end
|
|
||||||
space = SpaceView.new
|
|
||||||
@container.add_child space
|
|
||||||
|
|
||||||
animate = Proc.new do
|
|
||||||
`requestAnimationFrame(animate)`
|
|
||||||
registers.draw_me
|
|
||||||
space.draw_me
|
|
||||||
renderer.render @container
|
|
||||||
end
|
|
||||||
animate.call
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :container
|
|
||||||
end
|
|
@ -1,38 +0,0 @@
|
|||||||
|
|
||||||
class ObjectView
|
|
||||||
|
|
||||||
attr_accessor :text , :object , :attributes
|
|
||||||
|
|
||||||
def initialize o
|
|
||||||
super()
|
|
||||||
self.text = PIXI::Text.new("no")
|
|
||||||
self.text.position = PIXI::Point.new( rand(1000) , rand(550))
|
|
||||||
puts "NO O " unless o
|
|
||||||
self.object = o
|
|
||||||
self.text.text = short
|
|
||||||
@attributes = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def short
|
|
||||||
object.class.name.split("::").last[0 .. 3]
|
|
||||||
end
|
|
||||||
|
|
||||||
def is_parfait
|
|
||||||
object.class.name.split("::").first == "Parfait"
|
|
||||||
end
|
|
||||||
def set name , val
|
|
||||||
@attributes[name] = val
|
|
||||||
self.text.text = short + @attributes.length.to_s
|
|
||||||
end
|
|
||||||
def get(name)
|
|
||||||
@attributes[name]
|
|
||||||
end
|
|
||||||
def position
|
|
||||||
#raise "NONAME" unless self.text
|
|
||||||
self.text.position
|
|
||||||
end
|
|
||||||
|
|
||||||
def distance to
|
|
||||||
self.position - to.position
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,21 +0,0 @@
|
|||||||
|
|
||||||
class RegisterView < PIXI::Container
|
|
||||||
|
|
||||||
@@register_names = (0..8).collect {|i| "r#{i}"}
|
|
||||||
|
|
||||||
def initialize at_y
|
|
||||||
super()
|
|
||||||
@registers = {}
|
|
||||||
x = 0
|
|
||||||
@@register_names.each do |name|
|
|
||||||
reg = PIXI::Text.new( name )
|
|
||||||
reg.position = PIXI::Point.new x , at_y
|
|
||||||
x += reg.width + 20
|
|
||||||
@registers[name] = reg
|
|
||||||
self.add_child reg
|
|
||||||
end
|
|
||||||
def draw_me
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,159 +0,0 @@
|
|||||||
|
|
||||||
require "math"
|
|
||||||
|
|
||||||
PIXI::Point.class_eval do
|
|
||||||
alias_native :y=
|
|
||||||
|
|
||||||
def add point
|
|
||||||
self.x += point.x
|
|
||||||
self.x = 0 if self.x < 0
|
|
||||||
self.x = 1100 if self.x > 1100
|
|
||||||
self.y += point.y
|
|
||||||
self.y = 0 if self.y < 0
|
|
||||||
self.y = 550 if self.y > 550
|
|
||||||
end
|
|
||||||
|
|
||||||
def scale_by num
|
|
||||||
min = 0.001
|
|
||||||
num = min if num <= min
|
|
||||||
self.x = self.x / num
|
|
||||||
self.y = self.y / num
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class SpaceView < PIXI::Graphics
|
|
||||||
include Sof::Util
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
super()
|
|
||||||
space = Virtual.machine.space
|
|
||||||
# just a way to get the space into a list. objects is an id => occurence mapping.
|
|
||||||
# occurence.object is the object
|
|
||||||
objects = Sof::Members.new(space).objects
|
|
||||||
@objects = objects
|
|
||||||
puts "Objects #{objects.length}"
|
|
||||||
# create a mapping from id to volt models
|
|
||||||
@view_objects = {}
|
|
||||||
|
|
||||||
@objects.each do |i , o|
|
|
||||||
next unless o.object
|
|
||||||
view = ObjectView.new o.object
|
|
||||||
@view_objects[i] = view
|
|
||||||
add_child view.text
|
|
||||||
end
|
|
||||||
fill_attributes
|
|
||||||
end
|
|
||||||
|
|
||||||
# should almost be called draw by now
|
|
||||||
def draw_me
|
|
||||||
update_positions
|
|
||||||
self.clear
|
|
||||||
@view_objects.each do |i , view|
|
|
||||||
self.lineStyle(4, 0xffd900, 2)
|
|
||||||
puts "v" if view.nil?
|
|
||||||
view.attributes.each do |n , v |
|
|
||||||
next if n == :id
|
|
||||||
next unless v.is_a? ObjectView
|
|
||||||
next unless v.is_parfait
|
|
||||||
puts "v2" if view.nil?
|
|
||||||
puts "0" if v.nil?
|
|
||||||
self.moveTo( view.position.x , view.position.y )
|
|
||||||
self.lineTo( v.position.x , v.position.y )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def force from , to
|
|
||||||
dir_x = from.x - to.x - 100
|
|
||||||
dir_x2 = dir_x * dir_x
|
|
||||||
dir_y = from.y - to.y - 100
|
|
||||||
dir_y2 = dir_y * dir_y
|
|
||||||
if( dir_x2 < 0.1 and dir_y2 < 0.1 )
|
|
||||||
puts "Were close"
|
|
||||||
dir_x = rand(10) - 5
|
|
||||||
dir_y = rand(10) - 5
|
|
||||||
end
|
|
||||||
f = dir_x * dir_x + dir_y * dir_y
|
|
||||||
f = 0.01 if f < 0.01
|
|
||||||
f = f / 100
|
|
||||||
#puts "force #{f}"
|
|
||||||
PIXI::Point.new( dir_x / f , dir_y / f)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_positions
|
|
||||||
@view_objects.each do |i , view|
|
|
||||||
view.attributes.each do |n , v |
|
|
||||||
next if n == :id
|
|
||||||
next unless v.is_a? ObjectView
|
|
||||||
next unless v.is_parfait
|
|
||||||
puts "v2" if view.nil?
|
|
||||||
puts "0" if v.nil?
|
|
||||||
view.position.add force( view.position , v.position )
|
|
||||||
end
|
|
||||||
offset = 0.0
|
|
||||||
view.position.add force( view.position , PIXI::Point.new(view.position.x , -offset) )
|
|
||||||
view.position.add force( view.position , PIXI::Point.new(-offset , view.position.y) )
|
|
||||||
view.position.add force( view.position , PIXI::Point.new(view.position.x , 550 + offset) )
|
|
||||||
view.position.add force( view.position , PIXI::Point.new(1000 + offset , view.position.y) )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def fill_attributes
|
|
||||||
@view_objects.each do |i , view|
|
|
||||||
ob = view.object
|
|
||||||
next if is_value?(ob)
|
|
||||||
case ob.class.name
|
|
||||||
when "Array" , "Parfait::List"
|
|
||||||
fill_array view
|
|
||||||
when "Hash" , "Parfait::Dictionary"
|
|
||||||
fill_hash view
|
|
||||||
else
|
|
||||||
next if ob.class.name.include?("::") and !ob.class.name.include?("Parfait")
|
|
||||||
next if ob.class.name == "Proc"
|
|
||||||
next if ob.class.name == "String"
|
|
||||||
next if ob.class.name == "Numeric"
|
|
||||||
next if ob.class.name == "Class"
|
|
||||||
#puts "object #{ob.class.name}"
|
|
||||||
|
|
||||||
attributes = attributes_for(ob)
|
|
||||||
attributes.each do |a|
|
|
||||||
next if a == "html_safe"
|
|
||||||
next if a == "constructor"
|
|
||||||
next if a == "toString"
|
|
||||||
next if a == "position"
|
|
||||||
val = get_value( ob , a)
|
|
||||||
if( @view_objects[val.object_id])
|
|
||||||
val = @view_objects[val.object_id]
|
|
||||||
end
|
|
||||||
#puts "set #{a}"
|
|
||||||
view.set(a , val )
|
|
||||||
end
|
|
||||||
superclasses = [ob.class.superclass.name]
|
|
||||||
if superclasses.include?( "Array") or superclasses.include?( "Parfait::List")
|
|
||||||
fill_array view
|
|
||||||
end
|
|
||||||
if superclasses.include?( "Hash") or superclasses.include?( "Parfait::Dictionary")
|
|
||||||
fill_hash view
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# and hash keys/values
|
|
||||||
def fill_hash hash
|
|
||||||
return
|
|
||||||
hash.each do |a,b|
|
|
||||||
next_level << a
|
|
||||||
next_level << b
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# and array values
|
|
||||||
def fill_array array
|
|
||||||
return
|
|
||||||
array.each do |a|
|
|
||||||
next_level << a
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
@ -1,12 +0,0 @@
|
|||||||
# By default Volt generates this User model which inherits from Volt::User,
|
|
||||||
# you can rename this if you want.
|
|
||||||
class User < Volt::User
|
|
||||||
# login_field is set to :email by default and can be changed to :username
|
|
||||||
# in config/app.rb
|
|
||||||
field login_field
|
|
||||||
field :name
|
|
||||||
|
|
||||||
validate login_field, unique: true, length: 8
|
|
||||||
validate :email, email: true
|
|
||||||
|
|
||||||
end
|
|
@ -1,7 +0,0 @@
|
|||||||
<:Title>
|
|
||||||
About
|
|
||||||
|
|
||||||
<:Body>
|
|
||||||
<h1>About</h1>
|
|
||||||
|
|
||||||
<p>About page...</p>
|
|
@ -1,4 +0,0 @@
|
|||||||
<:Title>
|
|
||||||
Home
|
|
||||||
|
|
||||||
<:Body>
|
|
@ -1,27 +0,0 @@
|
|||||||
<:Title>
|
|
||||||
{{ view main_path, "title", {controller_group: 'main'} }}
|
|
||||||
|
|
||||||
<:Body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="header">
|
|
||||||
<ul class="nav nav-pills pull-right">
|
|
||||||
<:nav href="/">Home</:nav>
|
|
||||||
<:nav href="/about">About</:nav>
|
|
||||||
</ul>
|
|
||||||
<h3 class="text-muted">Salama Debugger</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<:volt:notices />
|
|
||||||
|
|
||||||
{{ view main_path, 'body', {controller_group: 'main'} }}
|
|
||||||
|
|
||||||
<div class="footer">
|
|
||||||
<p> <a href="http://salama-vm.org/" >Salama</a> {{ Time.now.year }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<:Nav>
|
|
||||||
<li class="{{ if active_tab? }}active{{ end }}">
|
|
||||||
<a href="{{ attrs.href }}">{{ yield }}</a>
|
|
||||||
</li>
|
|
71
assets/css/app.css.scss
Normal file
71
assets/css/app.css.scss
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Place your apps css here
|
||||||
|
@import "susy";
|
||||||
|
|
||||||
|
|
||||||
|
$susy: (
|
||||||
|
columns: 24 ,
|
||||||
|
gutter-position: split ,
|
||||||
|
);
|
||||||
|
|
||||||
|
.debugger_view { @include container(90%); }
|
||||||
|
|
||||||
|
.classes {
|
||||||
|
@include span(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.one_class {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
.file_view {
|
||||||
|
@include span(4);
|
||||||
|
margin-left: span(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.source_view { @include span(6); }
|
||||||
|
|
||||||
|
.block_view {
|
||||||
|
@include span(4);
|
||||||
|
margin-right: span(2);
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status_view {
|
||||||
|
@include span(2 at 22);
|
||||||
|
line-height : 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.registers_view {
|
||||||
|
@include span(20 at 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.register_view {
|
||||||
|
@include gallery(4);
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
@include span(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
@include span(18)
|
||||||
|
}
|
||||||
|
|
||||||
|
.value_head {
|
||||||
|
background-color: #C5FFD9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.act{
|
||||||
|
background-color: #00B3FF;
|
||||||
|
-moz-border-radius: 7px;
|
||||||
|
-webkit-border-radius: 7px;
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bright {
|
||||||
|
padding-right: 6px;
|
||||||
|
padding-left: 6px;
|
||||||
|
background-color: #00E3FF ;
|
||||||
|
-moz-border-radius: 7px;
|
||||||
|
-webkit-border-radius: 7px;
|
||||||
|
}
|
60
assets/css/menu.css.scss
Normal file
60
assets/css/menu.css.scss
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
body {
|
||||||
|
font-family: arial, helvetica, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav, #nav ul { /* all lists */
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
float : left;
|
||||||
|
width : 10em;
|
||||||
|
/*border around submenu goes here*/
|
||||||
|
-moz-border-radius: 8px;
|
||||||
|
-webkit-border-radius: 8px;
|
||||||
|
background:#fff;
|
||||||
|
border:1px solid #C3D46A
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav li { /* all list items */
|
||||||
|
position : relative;
|
||||||
|
float : left;
|
||||||
|
line-height : 1.25em;
|
||||||
|
width: 9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav li ul { /* second-level lists */
|
||||||
|
position : absolute;
|
||||||
|
left: -999em;
|
||||||
|
margin-left : 10.0em;
|
||||||
|
margin-top : -2.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav li ul ul { /* third-and-above-level lists */
|
||||||
|
left: -999em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav li a , li span {
|
||||||
|
padding-left: 0.5em;
|
||||||
|
width : 9.5em;
|
||||||
|
display : block;
|
||||||
|
color : black;
|
||||||
|
font-weight : bold;
|
||||||
|
text-decoration : none;
|
||||||
|
background-color : white;
|
||||||
|
-moz-border-radius: 7px;
|
||||||
|
-webkit-border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav li a:hover {
|
||||||
|
color : white;
|
||||||
|
background-color : #98CC1F;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav li:hover ul ul, #nav li:hover ul ul ul , #nav li:hover ul ul ul ul , #nav li:hover ul ul ul ul ul{
|
||||||
|
left: -999em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lists nested under hovered list items */
|
||||||
|
#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li li li li:hover ul , #nav li li li li li:hover ul {
|
||||||
|
left: auto;
|
||||||
|
}
|
35
config.ru
35
config.ru
@ -1,4 +1,31 @@
|
|||||||
# Run via rack server
|
require 'bundler'
|
||||||
require 'bundler/setup'
|
Bundler.require
|
||||||
require 'volt/server'
|
require 'tilt/erb'
|
||||||
run Volt::Server.new.app
|
|
||||||
|
require_relative "lib/parse_task"
|
||||||
|
|
||||||
|
require "opal"
|
||||||
|
require 'opal-browser'
|
||||||
|
|
||||||
|
Opal.use_gem("salama")
|
||||||
|
Opal.use_gem("salama-arm")
|
||||||
|
|
||||||
|
class DebugServer < Opal::Server
|
||||||
|
def call(env)
|
||||||
|
if( env["REQUEST_PATH"] == "/tasks.json")
|
||||||
|
[200, { 'Content-Type' => 'text/json' }, [ParseTask.new.parse(1).to_json]]
|
||||||
|
else
|
||||||
|
super(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
run DebugServer.new { |s|
|
||||||
|
s.main = 'debugger'
|
||||||
|
s.append_path 'lib'
|
||||||
|
s.append_path 'assets'
|
||||||
|
# s.source_map = true
|
||||||
|
s.debug = !ENV["DEBUG"].nil?
|
||||||
|
|
||||||
|
s.index_path = "index.html.erb"
|
||||||
|
s.sprockets.cache = Sprockets::Cache::MemoryStore.new(5000)
|
||||||
|
}
|
||||||
|
132
config/app.rb
132
config/app.rb
@ -1,132 +0,0 @@
|
|||||||
# app.rb is used to configure your app. This code is only run on the server,
|
|
||||||
# then any config options in config.public are passed to the client as well.
|
|
||||||
|
|
||||||
Volt.configure do |config|
|
|
||||||
# Setup your global app config here.
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Basic App Info (stuff you should set)
|
|
||||||
#######################################
|
|
||||||
config.domain = 'salama-vm.org'
|
|
||||||
config.app_name = 'Salama-debugger'
|
|
||||||
config.mailer.from = 'Salama-debugger <no-reply@salama-debugger.com>'
|
|
||||||
|
|
||||||
############
|
|
||||||
# App Secret
|
|
||||||
############
|
|
||||||
# Your app secret is used for signing things like the user cookie so it can't
|
|
||||||
# be tampered with. A random value is generated on new projects that will work
|
|
||||||
# without the need to customize. Make sure this value doesn't leave your server.
|
|
||||||
#
|
|
||||||
# For added security we recommend moving the app secret into an environment. You can
|
|
||||||
# setup that like so:
|
|
||||||
#
|
|
||||||
# config.app_secret = ENV['APP_SECRET']
|
|
||||||
#
|
|
||||||
config.app_secret = 'pKDKhKInTaI5EVH9WmyN-cJSYnJt8PmDogwW63Zqr_ieUNqYvh1KybeWJoslylzFgsU'
|
|
||||||
|
|
||||||
###############
|
|
||||||
# Log Filtering
|
|
||||||
###############
|
|
||||||
# Data updates from the client come in via Tasks. The task dispatcher logs all calls to tasks.
|
|
||||||
# By default hashes in the arguments can be filtered based on keys. So any hash with a key of
|
|
||||||
# password will be filtered. You can add more fields to filter below:
|
|
||||||
config.filter_keys = [:password]
|
|
||||||
|
|
||||||
##########
|
|
||||||
# Database
|
|
||||||
##########
|
|
||||||
# Database config all start with db_ and can be set either in the config
|
|
||||||
# file or with an environment variable (DB_NAME for example).
|
|
||||||
|
|
||||||
# config.db_driver = 'mongo'
|
|
||||||
# config.db_name = (config.app_name + '_' + Volt.env.to_s)
|
|
||||||
# config.db_host = 'localhost'
|
|
||||||
# config.db_port = 27017
|
|
||||||
|
|
||||||
#####################
|
|
||||||
# Compression options
|
|
||||||
#####################
|
|
||||||
# If you are not running behind something like nginx in production, you can
|
|
||||||
# have rack deflate all files.
|
|
||||||
# config.deflate = true
|
|
||||||
|
|
||||||
#######################
|
|
||||||
# Public configurations
|
|
||||||
#######################
|
|
||||||
# Anything under config.public will be sent to the client as well as the server,
|
|
||||||
# so be sure no private data ends up under public
|
|
||||||
|
|
||||||
# Use username instead of email as the login
|
|
||||||
# config.public.auth.use_username = true
|
|
||||||
|
|
||||||
#####################
|
|
||||||
# Compression Options
|
|
||||||
#####################
|
|
||||||
# Disable or enable css/js compression. Default is to only run in production.
|
|
||||||
# if Volt.env.production?
|
|
||||||
# config.compress_javascript = true
|
|
||||||
# config.compress_css = true
|
|
||||||
# end
|
|
||||||
|
|
||||||
################
|
|
||||||
# Mailer options
|
|
||||||
################
|
|
||||||
# The volt-mailer gem uses pony (https://github.com/benprew/pony) to deliver e-mail. Any
|
|
||||||
# options you would pass to pony can be setup below.
|
|
||||||
# NOTE: The from address is setup at the top
|
|
||||||
|
|
||||||
# Normally pony uses /usr/sbin/sendmail if one is installed. You can specify smtp below:
|
|
||||||
# config.mailer.via = :smtp
|
|
||||||
# config.mailer.via_options = {
|
|
||||||
# :address => 'smtp.yourserver.com',
|
|
||||||
# :port => '25',
|
|
||||||
# :user_name => 'user',
|
|
||||||
# :password => 'password',
|
|
||||||
# :authentication => :plain, # :plain, :login, :cram_md5, no auth by default
|
|
||||||
# :domain => "localhost.localdomain" # the HELO domain provided by the client to the server
|
|
||||||
# }
|
|
||||||
|
|
||||||
#############
|
|
||||||
# Message Bus
|
|
||||||
#############
|
|
||||||
# Volt provides a "Message Bus" out of the box. The message bus provides
|
|
||||||
# a pub/sub service between any volt instance (server, client, runner, etc..)
|
|
||||||
# that share the same database. The message bus can be used by app code. It
|
|
||||||
# is also used internally to push data to any listening clients.
|
|
||||||
#
|
|
||||||
# The default message bus (called "peer_to_peer") uses the database to sync
|
|
||||||
# socket ip's/ports.
|
|
||||||
# config.message_bus.bus_name = 'peer_to_peer'
|
|
||||||
#
|
|
||||||
# Encrypt message bus - messages on the message bus are encrypted by default
|
|
||||||
# but this is meant to be used locally by a developer
|
|
||||||
config.message_bus.disable_encryption = true
|
|
||||||
#
|
|
||||||
# ## MessageBus Server -- the message bus binds to a port and ip which the
|
|
||||||
# other volt instances need to be able to connect to. You can customize
|
|
||||||
# the server below:
|
|
||||||
#
|
|
||||||
# Port range - you can specify a range of ports that an instance can bind the
|
|
||||||
# message bus on. You can specify a range, an array of Integers, or an array
|
|
||||||
# of ranges.
|
|
||||||
# config.message_bus.bind_port_ranges = (58000..61000)
|
|
||||||
#
|
|
||||||
# Bind Ip - specifies the ip address the message bus server should bind on.
|
|
||||||
# config.message_bus.bind_ip = '127.0.0.1'
|
|
||||||
|
|
||||||
#############
|
|
||||||
# Concurrency
|
|
||||||
#############
|
|
||||||
# Volt provides a thread worker pool for incoming task requests (and all
|
|
||||||
# database requests, since those use tasks to do their work.) The following
|
|
||||||
# lets you control the size of the worker pool. Threads are only created as
|
|
||||||
# needed, and are removed after a certain amount of inactivity.
|
|
||||||
# config.min_worker_threads = 1
|
|
||||||
# config.max_worker_threads = 10
|
|
||||||
#
|
|
||||||
# You can also specify the amount of time a Task should run for before it
|
|
||||||
# timeout's. Setting this to short can cause unexpected results, currently
|
|
||||||
# we recomend it be at least 10 seconds.
|
|
||||||
# config.worker_timeout = 60
|
|
||||||
end
|
|
@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<%# IMPORTANT: Please read before changing! %>
|
|
||||||
<%# This file is rendered on the server using ERB, so it does NOT use Volt's %>
|
|
||||||
<%# normal template system. You can add to it, but keep in mind the template %>
|
|
||||||
<%# language difference. This file handles auto-loading all JS/Opal and CSS. %>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<% javascript_files.each do |javascript_file| %>
|
|
||||||
<script src="<%= javascript_file %>"></script>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% css_files.each do |css_file| %>
|
|
||||||
<link href="<%= css_file %>" media="all" rel="stylesheet" type="text/css" />
|
|
||||||
<% end %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,3 +0,0 @@
|
|||||||
#require "salama"
|
|
||||||
|
|
||||||
Virtual::Machine.boot
|
|
11
index.html.erb
Normal file
11
index.html.erb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Debugger</title>
|
||||||
|
<link rel="stylesheet" href="/assets/css/menu.css" type="text/css" charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="/assets/css/app.css" type="text/css" charset="utf-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%= javascript_include_tag "debugger" %>
|
||||||
|
</body>
|
||||||
|
</html>
|
14
lib/base/constant_view.rb
Normal file
14
lib/base/constant_view.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
require_relative "element_view"
|
||||||
|
|
||||||
|
class ConstantView < ElementView
|
||||||
|
|
||||||
|
def initialize class_or_id , text = nil
|
||||||
|
@class_or_id = class_or_id
|
||||||
|
@text = text
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@element = div(@class_or_id , @text)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
81
lib/base/element_view.rb
Normal file
81
lib/base/element_view.rb
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
class ElementView
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@element = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
#abstract function that should return the single element that is being represented
|
||||||
|
# the element is also stored in @element
|
||||||
|
def draw
|
||||||
|
raise "implement me to return an Element"
|
||||||
|
end
|
||||||
|
|
||||||
|
# helper function to create an element with possible classes, id and text
|
||||||
|
# The first argument is a bit haml inspired, so "tagname.classname" is the format
|
||||||
|
# but if tagname is ommited it will default to div
|
||||||
|
# also several classnames may be given
|
||||||
|
# if one of the names ends in a ! (bang) it will be assigned as the id
|
||||||
|
# second argument is optional, but if given will be added as text (content) to the newly
|
||||||
|
# created Element
|
||||||
|
# return the new Element, which is not linked into the dom at that point (see << and add*)
|
||||||
|
def div name_class = "div" , text = nil
|
||||||
|
name , clazz = name_class.split(".")
|
||||||
|
name = "div" if name.empty?
|
||||||
|
element = $document.create_element(name)
|
||||||
|
element.text = text if text
|
||||||
|
return element unless clazz
|
||||||
|
if( clazz.is_a? Array )
|
||||||
|
clazz.each { |c| add_class_or_id( element , cl )}
|
||||||
|
else
|
||||||
|
add_class_or_id element , clazz
|
||||||
|
end
|
||||||
|
element
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_class_or_id element , class_or_id
|
||||||
|
return element unless class_or_id
|
||||||
|
if class_or_id[-1] == "!"
|
||||||
|
element.id = class_or_id[0 ... -1]
|
||||||
|
else
|
||||||
|
element.add_class class_or_id
|
||||||
|
end
|
||||||
|
element
|
||||||
|
end
|
||||||
|
|
||||||
|
# wrap the @element variable with the given element
|
||||||
|
# so if wrapper == <h4/> the new @element will be <h4> old @element </h4>
|
||||||
|
# return the new @element, which is wrapper
|
||||||
|
def wrap_element wrapper
|
||||||
|
@element = wrap_node_with @element , wrapper
|
||||||
|
end
|
||||||
|
|
||||||
|
#wrap the given node with the wappper, so for a div wrapper and a button node
|
||||||
|
# the result will be <div> <button>hwatever was in there</button> <div>
|
||||||
|
def wrap_node_with node , wrapper
|
||||||
|
node.replace_with(wrapper) if node.parent
|
||||||
|
wrapper << node
|
||||||
|
end
|
||||||
|
|
||||||
|
# add the given element to the @element, at the end
|
||||||
|
# return the div that was passed in (use << to return the @element)
|
||||||
|
def append_element div
|
||||||
|
@element << div
|
||||||
|
div
|
||||||
|
end
|
||||||
|
|
||||||
|
# add the given element to the @element , at the front
|
||||||
|
# return the div that was passed in (use >> to return the @element)
|
||||||
|
def prepend_element div
|
||||||
|
@element >> div
|
||||||
|
div
|
||||||
|
end
|
||||||
|
|
||||||
|
# create a new element with class and possibly text
|
||||||
|
# add that new element to the @element
|
||||||
|
# return the newly created element
|
||||||
|
def add class_or_id , tex = nil
|
||||||
|
append_element div( class_or_id , tex)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
56
lib/base/list_view.rb
Normal file
56
lib/base/list_view.rb
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
require_relative "element_view"
|
||||||
|
|
||||||
|
class ListView < ElementView
|
||||||
|
|
||||||
|
def initialize children
|
||||||
|
@children = children
|
||||||
|
@elements = []
|
||||||
|
end
|
||||||
|
|
||||||
|
# create a root node acording to the tag given (default div)
|
||||||
|
# The tag name will be passed to the div function, so class and id may be set as well (see there)
|
||||||
|
# draw all children and keep the elements as @elements
|
||||||
|
# return (as per base class) the single root of the collection
|
||||||
|
def draw root = "div"
|
||||||
|
@element = div(root)
|
||||||
|
@elements = @children.collect do | c |
|
||||||
|
append_element c.draw
|
||||||
|
end
|
||||||
|
@element
|
||||||
|
end
|
||||||
|
|
||||||
|
# replace the child at index with the given one (second arg)
|
||||||
|
# The child must be an ElementView , which will be rendered and
|
||||||
|
# the old node will be replaces in the live dom
|
||||||
|
def replace_at index , with
|
||||||
|
old = @elements[index]
|
||||||
|
@children[index] = with
|
||||||
|
rendered = with.draw
|
||||||
|
@elements[index] = rendered
|
||||||
|
old.replace_with rendered
|
||||||
|
end
|
||||||
|
|
||||||
|
# remove the first child and element (from view)
|
||||||
|
def remove_first
|
||||||
|
remove_at 0
|
||||||
|
end
|
||||||
|
|
||||||
|
# remove both child and element at given position
|
||||||
|
def remove_at index
|
||||||
|
raise "insex out of bounds #{index} => #{@children.length}" if(index >= @children.length or index < 0)
|
||||||
|
@children.delete_at( index )
|
||||||
|
element = @elements.delete_at(index)
|
||||||
|
element.remove
|
||||||
|
end
|
||||||
|
|
||||||
|
# append a View instnace to the children array
|
||||||
|
# render it and append it to the html element
|
||||||
|
# and keep a copy in @elements
|
||||||
|
def append_view view
|
||||||
|
@children << view
|
||||||
|
rendered = view.draw
|
||||||
|
@elements << rendered # add to internal array
|
||||||
|
@element << rendered # add to html children
|
||||||
|
rendered
|
||||||
|
end
|
||||||
|
end
|
58
lib/blocks_view.rb
Normal file
58
lib/blocks_view.rb
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
class BlocksView < ListView
|
||||||
|
|
||||||
|
def initialize interpreter
|
||||||
|
@interpreter = interpreter
|
||||||
|
@interpreter.register_event(:instruction_changed, self)
|
||||||
|
super([BlockView.new(@interpreter.block)])
|
||||||
|
@method_name = method_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
super()
|
||||||
|
wrap_element div("div.block_view") << div("h4" , "Method + Block " ) << div("h4.method" , @method_name)
|
||||||
|
return @element
|
||||||
|
end
|
||||||
|
|
||||||
|
def instruction_changed
|
||||||
|
new_name = method_name
|
||||||
|
unless new_name == @method_name
|
||||||
|
@method_name = new_name
|
||||||
|
@element.at_css(".method").text = method_name
|
||||||
|
end
|
||||||
|
return if @interpreter.block.object_id == @children.last.block.object_id
|
||||||
|
@elements.last.at_css(".bright").remove_class("bright")
|
||||||
|
append_view( BlockView.new(@interpreter.block) )
|
||||||
|
remove_first if( @elements.length > 6)
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_name
|
||||||
|
bl = @interpreter.block
|
||||||
|
return "" unless bl
|
||||||
|
return bl.method if bl.method.is_a? String
|
||||||
|
"#{bl.method.for_class.name}.#{bl.method.name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class BlockView < ElementView
|
||||||
|
|
||||||
|
def initialize block
|
||||||
|
@block = block
|
||||||
|
end
|
||||||
|
attr_reader :block
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@element = div("div") << div("span.bright" , block_name )
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_name
|
||||||
|
return @block.method if @block.method.is_a? String
|
||||||
|
@block.method.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def block_name
|
||||||
|
return @block if @block.is_a? String
|
||||||
|
"#{method_name}.#{@block.name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
37
lib/classes_view.rb
Normal file
37
lib/classes_view.rb
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
class ClassesView < ListView
|
||||||
|
|
||||||
|
def initialize interpreter
|
||||||
|
@interpreter = interpreter
|
||||||
|
classes = []
|
||||||
|
Virtual.machine.space.classes.each do |name , claz|
|
||||||
|
next if [:Kernel,:Module,:MetaClass,:BinaryCode].index name
|
||||||
|
classes << claz
|
||||||
|
end
|
||||||
|
classes.sort! {|a,b| a.name <=> b.name }
|
||||||
|
super( classes.collect{|c| ClassView.new(c)})
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
super()
|
||||||
|
wrap_element div("ul.nav!")
|
||||||
|
wrap_element( div(".classes") << div("h4" , "Classes") )
|
||||||
|
return @element
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
class ClassView < ElementView
|
||||||
|
def initialize clazz
|
||||||
|
@clazz = clazz
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@element = div("li") << div( "a" , @clazz.name ) << (ul = div("ul"))
|
||||||
|
@clazz.object_layout.object_instance_names.each do |name|
|
||||||
|
ul << (div("li") << div("a", name ))
|
||||||
|
end
|
||||||
|
@element.style["z-index"] = 20
|
||||||
|
@element
|
||||||
|
end
|
||||||
|
end
|
47
lib/debugger.rb
Normal file
47
lib/debugger.rb
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
require "opal"
|
||||||
|
require "opal-parser"
|
||||||
|
|
||||||
|
|
||||||
|
require 'browser'
|
||||||
|
require 'native'
|
||||||
|
require "salama"
|
||||||
|
require "interpreter/interpreter"
|
||||||
|
require "base/list_view"
|
||||||
|
require_relative "classes_view"
|
||||||
|
require_relative "status_view"
|
||||||
|
require_relative "file_view"
|
||||||
|
require_relative "blocks_view"
|
||||||
|
require_relative "instruction_view"
|
||||||
|
require_relative "registers_view"
|
||||||
|
|
||||||
|
class MainView < ListView
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
machine = Virtual.machine.boot
|
||||||
|
|
||||||
|
# compile_main includes the parse
|
||||||
|
# parsing generates an ast as seen below and then compiles it.
|
||||||
|
# machine.compile_main "2 + 5"
|
||||||
|
|
||||||
|
# so the code above is functionally equivalent to the one below, minus the parse
|
||||||
|
# When the ast expression is given all works, so pretty sure it is the parse that fails
|
||||||
|
|
||||||
|
code = Ast::OperatorExpression.new("+", Ast::IntegerExpression.new(2),Ast::IntegerExpression.new(5))
|
||||||
|
Virtual::Compiler.compile( code , machine.space.get_main )
|
||||||
|
|
||||||
|
machine.run_before "Register::CallImplementation"
|
||||||
|
@interpreter = Interpreter::Interpreter.new
|
||||||
|
@interpreter.start machine.init
|
||||||
|
super( [ClassesView.new(@interpreter) ,
|
||||||
|
FileView.new ,
|
||||||
|
BlocksView.new(@interpreter) ,
|
||||||
|
InstructionView.new(@interpreter) ,
|
||||||
|
StatusView.new(@interpreter) ,
|
||||||
|
RegistersView.new(@interpreter) ] )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
view = MainView.new()
|
||||||
|
view.draw.append_to($document.body)
|
8
lib/file_view.rb
Normal file
8
lib/file_view.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
class FileView < ElementView
|
||||||
|
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@element = div(".file_view") << div("h4" ,"Future")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
30
lib/instruction_view.rb
Normal file
30
lib/instruction_view.rb
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
require "base/constant_view"
|
||||||
|
require "base/list_view"
|
||||||
|
|
||||||
|
class InstructionView < ListView
|
||||||
|
|
||||||
|
def initialize interpreter
|
||||||
|
@interpreter = interpreter
|
||||||
|
super([ConstantView.new( "span.bright" , "starting" )])
|
||||||
|
@interpreter.register_event(:instruction_changed, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def instruction_changed
|
||||||
|
@element.at_css(".bright").remove_class("bright")
|
||||||
|
instruction = append_view( ConstantView.new( "span.bright" , instruction_text ) )
|
||||||
|
wrap_node_with instruction , div
|
||||||
|
remove_first if( @elements.length > 6)
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
super()
|
||||||
|
wrap_node_with @elements.first , div
|
||||||
|
wrap_element div(".source_view") << div("h4" ,"Virtual Machine Instruction")
|
||||||
|
@element
|
||||||
|
end
|
||||||
|
|
||||||
|
def instruction_text
|
||||||
|
return "" unless @interpreter.instruction
|
||||||
|
@interpreter.instruction.to_s
|
||||||
|
end
|
||||||
|
end
|
54
lib/object_view.rb
Normal file
54
lib/object_view.rb
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
require_relative "ref_view"
|
||||||
|
|
||||||
|
class ObjectView < ListView
|
||||||
|
|
||||||
|
def initialize object_id , interpreter = nil , z = nil
|
||||||
|
@object_id = object_id
|
||||||
|
@z = z
|
||||||
|
@interpreter = interpreter
|
||||||
|
@interpreter.register_event(:object_changed, self) if interpreter
|
||||||
|
super( content_elements )
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@element = super(@interpreter ? "ul.nav!" : "ul")
|
||||||
|
prepend_element div("li" , "-------------------------")
|
||||||
|
prepend_element div( "li" ) << div("span" , class_header(@object_id) )
|
||||||
|
return @element
|
||||||
|
end
|
||||||
|
|
||||||
|
def object_changed reg , at
|
||||||
|
puts "Object changed in #{reg}"
|
||||||
|
for_object = @interpreter.get_register( reg )
|
||||||
|
return unless for_object == @object_id
|
||||||
|
puts "Object changed #{for_object} , at #{at}"
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def class_header(id)
|
||||||
|
object = Virtual.machine.objects[id]
|
||||||
|
clazz = object.class.name.split("::").last
|
||||||
|
[clazz, id].join " : "
|
||||||
|
end
|
||||||
|
|
||||||
|
def content_elements
|
||||||
|
object = Virtual.machine.objects[@object_id]
|
||||||
|
fields = []
|
||||||
|
if object and ! object.is_a?(String)
|
||||||
|
fields << RefView.new( "layout" , object.get_layout.object_id , @z )
|
||||||
|
object.get_instance_variables.each do |variable|
|
||||||
|
f = object.get_instance_variable(variable)
|
||||||
|
fields << RefView.new( variable , f.object_id , @z )
|
||||||
|
end
|
||||||
|
if( object.is_a?(Parfait::List) )
|
||||||
|
index = 1
|
||||||
|
object.each do | o , i|
|
||||||
|
fields << RefView.new( index.to_s , o.object_id , @z )
|
||||||
|
index += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fields
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -1,6 +1,6 @@
|
|||||||
require "salama-reader"
|
require "salama-reader"
|
||||||
|
|
||||||
class ParseTask < Volt::Task
|
class ParseTask
|
||||||
def parse(num)
|
def parse(num)
|
||||||
string_input = '"Hello again".putstring()'
|
string_input = '"Hello again".putstring()'
|
||||||
parser = Parser::Salama.new
|
parser = Parser::Salama.new
|
59
lib/ref_view.rb
Normal file
59
lib/ref_view.rb
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
class RefView < ListView
|
||||||
|
|
||||||
|
def initialize name , value , z = nil
|
||||||
|
@name = name
|
||||||
|
@value = value
|
||||||
|
@z = z
|
||||||
|
super []
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :value
|
||||||
|
|
||||||
|
def value= val
|
||||||
|
@value = val
|
||||||
|
add_hover
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@element = div("li") << div("a" , "#{@name} : #{marker(@value)}" )
|
||||||
|
add_hover
|
||||||
|
@element.style["z-index"] = @z if @z
|
||||||
|
@element
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_hover
|
||||||
|
return if is_string?
|
||||||
|
@element.on("hover"){ hover } if is_object?(@value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_object?( )
|
||||||
|
Virtual.machine.objects[@value] != nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_string?()
|
||||||
|
Virtual.machine.objects[@value].is_a? String
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_nil?()
|
||||||
|
Virtual.machine.objects[@value].nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def hover
|
||||||
|
puts "hovering #{@name}"
|
||||||
|
append_view ObjectView.new(@value)
|
||||||
|
@element.off("hover")
|
||||||
|
end
|
||||||
|
|
||||||
|
def marker id
|
||||||
|
if is_string?
|
||||||
|
str = @value
|
||||||
|
elsif is_nil?
|
||||||
|
str = "nil"
|
||||||
|
else
|
||||||
|
var = Virtual.machine.objects[id]
|
||||||
|
str = var.class.name.split("::").last[0,2]
|
||||||
|
str + " : #{id.to_s}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
51
lib/registers_view.rb
Normal file
51
lib/registers_view.rb
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
require_relative "object_view"
|
||||||
|
|
||||||
|
class RegistersView < ListView
|
||||||
|
|
||||||
|
def initialize interpreter
|
||||||
|
@interpreter = interpreter
|
||||||
|
@interpreter.register_event(:register_changed, self)
|
||||||
|
kids = []
|
||||||
|
@interpreter.registers.each do |reg , val|
|
||||||
|
kids << ValueView.new( val )
|
||||||
|
end
|
||||||
|
super(kids)
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
super( "div.registers_view" )
|
||||||
|
@element.children.each_with_index do |reg, index|
|
||||||
|
elem = div("div.register_view")
|
||||||
|
wrap_node_with reg , elem
|
||||||
|
end
|
||||||
|
@element
|
||||||
|
end
|
||||||
|
|
||||||
|
def register_changed reg , old , value
|
||||||
|
reg = reg.symbol unless reg.is_a? Symbol
|
||||||
|
index = reg.to_s[1 .. -1 ].to_i
|
||||||
|
if( is_object? value )
|
||||||
|
swap = ObjectView.new( value , @interpreter , 16 - index )
|
||||||
|
else
|
||||||
|
swap = ValueView.new value
|
||||||
|
end
|
||||||
|
replace_at index , swap
|
||||||
|
# @elements[index].style["z-index"] = -index
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_object?( id )
|
||||||
|
Virtual.machine.objects[id] != nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
class ValueView < ElementView
|
||||||
|
|
||||||
|
def initialize value
|
||||||
|
@value = value
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@element = div("ul.nav!") << div("li") << div("span", @value)
|
||||||
|
end
|
||||||
|
end
|
42
lib/status_view.rb
Normal file
42
lib/status_view.rb
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
class StatusView < ElementView
|
||||||
|
|
||||||
|
def initialize interpreter
|
||||||
|
@interpreter = interpreter
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@element = div(".status_view") <<
|
||||||
|
div("h4" , "Interpreter" ) <<
|
||||||
|
div("button.act" , "Next") <<
|
||||||
|
div( "br") <<
|
||||||
|
div("span.clock" , clock_text) <<
|
||||||
|
div( "br") <<
|
||||||
|
div("span.state" , state_text) <<
|
||||||
|
div( "br") <<
|
||||||
|
div( "span.link" , link_text) <<
|
||||||
|
div( "br" , "Stdout") <<
|
||||||
|
div("span.stdout")
|
||||||
|
# set up event handler
|
||||||
|
@element.at_css(".act").on("click") { self.update }
|
||||||
|
return @element
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@interpreter.tick
|
||||||
|
@element.at_css(".clock").text = clock_text
|
||||||
|
@element.at_css(".link").text = link_text
|
||||||
|
@element.at_css(".stdout").text = @interpreter.stdout
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_text
|
||||||
|
"Link #{@interpreter.link}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def state_text
|
||||||
|
"State #{@interpreter.state}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def clock_text
|
||||||
|
"Instruction #{@interpreter.clock}"
|
||||||
|
end
|
||||||
|
end
|
Reference in New Issue
Block a user