Commit 1404df14 by jasl

update dummy, use latest script_core

parent 34acb70e
......@@ -22,6 +22,9 @@ test/dummy/tmp/
test/dummy/storage/*
!test/dummy/storage/.keep
# Ignore compiled mruby in dummy app
/test/dummy/mruby/bin
pkg/
.byebug_history
......
......@@ -5,7 +5,8 @@ inherit_gem:
AllCops:
TargetRubyVersion: 2.4
Exclude:
- 'test/dummy/db/schema.rb'
- test/dummy/db/schema.rb
- test/dummy/mruby/**/*
# frozen_string_literal: true
Style/FrozenStringLiteralComment:
......
......@@ -104,7 +104,7 @@ GEM
mini_mime (>= 0.1.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.1)
method_source (0.9.2)
mimemagic (0.3.2)
mini_mime (1.0.1)
mini_portile2 (2.3.0)
......@@ -120,7 +120,7 @@ GEM
process-group (1.1.0)
process-pipeline (1.0.1)
process-group
pry (0.12.0)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-byebug (3.6.0)
......@@ -176,7 +176,7 @@ GEM
rubocop (~> 0.56)
ruby-progressbar (1.10.0)
ruby_dep (1.5.0)
sass (3.7.1)
sass (3.7.2)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
......@@ -190,7 +190,7 @@ GEM
sprockets (> 3.0)
sprockets-rails
tilt
script_core (0.0.4)
script_core (0.0.6)
msgpack (~> 1.0)
rake-compiler (~> 1.0)
selectize-rails (0.12.6)
......@@ -202,7 +202,7 @@ GEM
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.13)
thor (0.20.0)
thor (0.20.3)
thread_safe (0.3.6)
tilt (2.0.8)
turbolinks (5.2.0)
......
......@@ -113,7 +113,7 @@ The dummy app integrates with [Form Core](https://github.com/rails-engine/form_c
![](_assets/dummy_overview.png)
**You need install Graphviz first**
**You need to install Graphviz first**
Clone the repository.
......@@ -133,6 +133,13 @@ Run bundler
$ bundle install
```
Build mruby engine & engine lib
```sh
$ bin/rails app:script_core:engine:build
$ bin/rails app:script_core:engine:compile_lib
```
Preparing database
```sh
......@@ -175,7 +182,9 @@ In transition's options, you can configure field's accessibility
Exclusive choice is a special transition that needs to configure conditions that determine how to transit to a branch.
The condition is a Ruby expression, and running in a mRuby sandbox (powered by ScriptCore but it's also undone yet), and you can access form data through `@input[:payload]`, for example, there is a field named `approved`, we can check the field checked by `@input[:payload]["approved"]`
The condition is a Ruby expression, and running in a mRuby sandbox (powered by [ScriptCore](https://github.com/rails-engine/script_core)),
and you can access form data through `Input`, for example, there is a field named `approved`,
we can check the field checked by `Input["approved"]`
#### Run a workflow
......
_assets/defining_form.png

95.9 KB | W: | H:

_assets/defining_form.png

62.5 KB | W: | H:

_assets/defining_form.png
_assets/defining_form.png
_assets/defining_form.png
_assets/defining_form.png
  • 2-up
  • Swipe
  • Onion skin
_assets/dummy_overview.png

111 KB | W: | H:

_assets/dummy_overview.png

64.4 KB | W: | H:

_assets/dummy_overview.png
_assets/dummy_overview.png
_assets/dummy_overview.png
_assets/dummy_overview.png
  • 2-up
  • Swipe
  • Onion skin
_assets/editing_transition.png

154 KB | W: | H:

_assets/editing_transition.png

94.6 KB | W: | H:

_assets/editing_transition.png
_assets/editing_transition.png
_assets/editing_transition.png
_assets/editing_transition.png
  • 2-up
  • Swipe
  • Onion skin
# frozen_string_literal: true
module ScriptEngine
class << self
def engine
@engine ||= ScriptCore::Engine.new Rails.root.join("mruby/bin")
end
def eval(string, input: nil, instruction_quota_start: nil, environment_variables: {})
environment_variables.reverse_merge!("TZ" => Time.zone.name)
sources = [
%w[prepare_input prepare_input],
["user", string],
%w[prepare_output prepare_output]
]
engine.eval sources, input: input,
instruction_quota_start: instruction_quota_start,
environment_variables: environment_variables
end
def eval2(string, input: nil, instruction_quota_start: nil, environment_variables: {})
environment_variables.reverse_merge!("TZ" => Time.zone.name)
wrapped_string = "Output.value = module Main\n#{string}\nend"
sources = [
%w[prepare_input prepare_input],
["user", wrapped_string],
%w[prepare_output prepare_output]
]
engine.eval sources, input: input,
instruction_quota_start: instruction_quota_start,
environment_variables: environment_variables
end
end
end
......@@ -7,8 +7,7 @@ class Transitions::ExclusiveChoice < Transition
instance = token.instance
next_place_id = self.options.conditions.select do |condition|
r = ScriptCore.run input: {payload: instance.payload},
sources: [["expression", "@output = #{condition.condition_expression}"]]
r = ScriptEngine.eval2 condition.condition_expression, input: instance.payload
if r.errors.any?
raise r.errors.map(&:message).join("; ")
end
......
MRuby::GemBox.new do |conf|
conf.gem(github: "jasl-lab/mruby-mpdecimal", branch: "master")
conf.gem(core: "mruby-math")
conf.gem(core: "mruby-time")
conf.gem(core: "mruby-struct")
conf.gem(core: "mruby-enum-ext")
conf.gem(core: "mruby-string-ext")
conf.gem(core: "mruby-numeric-ext")
conf.gem(core: "mruby-array-ext")
conf.gem(core: "mruby-hash-ext")
conf.gem(core: "mruby-range-ext")
conf.gem(core: "mruby-proc-ext")
conf.gem(core: "mruby-symbol-ext")
conf.gem(core: "mruby-object-ext")
conf.gem(core: "mruby-toplevel-ext")
conf.gem(core: "mruby-kernel-ext")
conf.gem(core: "mruby-compiler")
end
class FalseClass
def dup
self
end
end
class TrueClass
def dup
self
end
end
class Method
def dup
self
end
end
class NilClass
def dup
self
end
end
class Numeric
def dup
self
end
end
class Decimal
def dup
self
end
end
class Symbol
def dup
self
end
end
class Object
def deep_dup
dup
end
end
class Hash
def deep_dup
# Different with Shopify's
each_with_object(dup) do |(key, value), hash|
hash[key.deep_dup] = value.deep_dup
end
end
end
class Array
def deep_dup
map { |it| it.deep_dup }
end
end
\ No newline at end of file
Kernel.remove_method :object_id
module Input
class << self
def load(input)
@input = input || {}
@input.freeze
end
def [](key)
@input[key]
end
def to_s
@input.to_s
end
def value
@input
end
end
end
class << self
attr_accessor :stdout_buffer
end
SCRIPT__TOP = self
SCRIPT__TOP.stdout_buffer = ""
module Kernel
def puts(*args)
unless args.empty?
args.each do |arg|
SCRIPT__TOP.stdout_buffer << arg.to_s
SCRIPT__TOP.stdout_buffer << "\n"
end
else
SCRIPT__TOP.stdout_buffer << "\n"
end
end
end
module Output
class << self
SUPPORTED_CLASSES = [Symbol, FalseClass, TrueClass, Float, Integer, String]
attr_accessor :value
def dump
return nil if value.nil?
unless value_type_supported?(value)
raise "Output can't pass to host Ruby."
end
value
end
private
def value_type_supported?(value)
return true if value.nil?
if value.is_a? Hash
return false if value.keys.map { |i| value_type_supported?(i) }.any? { |i| !i }
return false if value.values.map { |i| value_type_supported?(i) }.any? { |i| !i }
elsif value.is_a? Array
return false if value.map { |i| value_type_supported?(i) }.any? { |i| !i }
end
for klass in SUPPORTED_CLASSES
return true if value.is_a? klass
end
false
end
end
end
def prepare_input
Input.load @input
remove_instance_variable "@input"
end
def prepare_output
instance_variable_set :@output, Output.dump
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment