Skip to content

Commit c92d384

Browse files
authored
Feature/import js to service (#3)
* Setup rpg dice roller imports to ruby * Add debug file for better dev * Use DiceRoller logs
1 parent 3329440 commit c92d384

File tree

17 files changed

+249
-15
lines changed

17 files changed

+249
-15
lines changed

config/settings.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
TODO_plugin_name:
2-
plugin_name_enabled:
1+
plugins:
2+
rollmaster_enabled:
33
default: false
44
client: true

lib/rollmaster/dice_engine.rb

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# frozen_string_literal: true
2+
3+
require "mini_racer"
4+
5+
module Rollmaster
6+
class DiceEngine
7+
@mutex = Mutex.new
8+
@ctx_init = Mutex.new
9+
@ctx = nil
10+
11+
def self.protect
12+
rval = nil
13+
@mutex.synchronize { rval = yield }
14+
rval
15+
end
16+
17+
def self.roll(*diceRolls)
18+
result = nil
19+
protect do
20+
context = v8
21+
result = context.call("roll", *diceRolls)
22+
end
23+
result
24+
end
25+
26+
def self.attach_function(ctx)
27+
ctx.eval <<~JS
28+
function roll(...diceRolls) {
29+
const roller = new rpgDiceRoller.DiceRoller;
30+
roller.roll(...diceRolls);
31+
return JSON.parse(JSON.stringify(roller.log))
32+
}
33+
JS
34+
end
35+
36+
def self.create_context
37+
# Create a new v8 context. Not exactly happy with starting a new v8 context, but we don't
38+
# want to share the context between threads. Similarly, no auto disposal mechanism, so we
39+
# just need to hope the improved user experience is worth the memory usage.
40+
ctx = MiniRacer::Context.new(timeout: 25_000, ensure_gc_after_idle: 2000)
41+
42+
ctx.eval("window = globalThis; window.devicePixelRatio = 2;") # hack to make code think stuff is retina
43+
44+
ctx.attach("rails.logger.info", proc { |err| Rails.logger.info(err.to_s) })
45+
ctx.attach("rails.logger.warn", proc { |err| Rails.logger.warn(err.to_s) })
46+
ctx.attach("rails.logger.error", proc { |err| Rails.logger.error(err.to_s) })
47+
ctx.eval <<~JS
48+
console = {
49+
prefix: "[Rollmaster] ",
50+
log: function(...args){ rails.logger.info(console.prefix + args.join(" ")); },
51+
warn: function(...args){ rails.logger.warn(console.prefix + args.join(" ")); },
52+
error: function(...args){ rails.logger.error(console.prefix + args.join(" ")); }
53+
}
54+
JS
55+
56+
# skip transpiler. pre-compiled to UMD, which should cover modern browsers.
57+
# See https://github.com/dice-roller/rpg-dice-roller/blob/develop/.babelrc
58+
ctx.load("#{Rails.root}/plugins/rollmaster/public/vendors/math.js")
59+
ctx.load("#{Rails.root}/plugins/rollmaster/public/vendors/random-js.min.js")
60+
ctx.load("#{Rails.root}/plugins/rollmaster/public/vendors/rpg-dice-roller.min.js")
61+
62+
attach_function(ctx)
63+
64+
ctx
65+
end
66+
67+
def self.v8
68+
return @ctx if @ctx
69+
70+
@ctx_init.synchronize do
71+
return @ctx if @ctx
72+
@ctx = create_context
73+
end
74+
@ctx
75+
end
76+
77+
def self.reset_context
78+
@ctx_init.synchronize do
79+
@ctx&.dispose
80+
@ctx = nil
81+
end
82+
end
83+
84+
def self.execute_in_context(context, script)
85+
context.eval(script)
86+
rescue MiniRacer::RuntimeError => e
87+
raise "Error executing script: #{e.message}"
88+
end
89+
end
90+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
module ::Rollmaster
4+
class HandleCookedPostProcess
5+
def self.process(doc, post)
6+
# Add your processing logic here
7+
end
8+
end
9+
end

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"private": true,
33
"scripts": {
4-
"copy-vendor": "node -e \"require('fs').copyFileSync('node_modules/@dice-roller/rpg-dice-roller/lib/esm/bundle.min.js', 'public/rpg-dice-roller/bundle.min.js')\""
4+
"vendors": "node scripts/copy-engines-to-public.js"
55
},
66
"devDependencies": {
77
"@discourse/lint-configs": "2.12.0",
@@ -18,6 +18,8 @@
1818
},
1919
"packageManager": "pnpm@9.15.5",
2020
"dependencies": {
21-
"@dice-roller/rpg-dice-roller": "^5.5.1"
21+
"@dice-roller/rpg-dice-roller": "^5.5.1",
22+
"mathjs": "^14.2.0",
23+
"random-js": "^2.1.0"
2224
}
2325
}

plugin.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@
1111
enabled_site_setting :rollmaster_enabled
1212

1313
module ::Rollmaster
14-
PLUGIN_NAME = "discourse-rollmaster"
14+
PLUGIN_NAME = "rollmaster"
1515
end
1616

1717
require_relative "lib/rollmaster/engine"
1818

1919
after_initialize do
2020
# Code which should run after Rails has finished booting
21+
# # I don't think this is needed, but it doesn't hurt to be safe
22+
# PrettyText.reset_context()
23+
24+
on(:post_process_cooked) { |doc, post| ::Rollmaster::HandleCookedPostProcess.process(doc, post) }
25+
# TODO: consider :chat_message_processed as well
2126
end

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/rpg-dice-roller/.gitkeep

Whitespace-only changes.

public/rpg-dice-roller/bundle.min.js

Lines changed: 0 additions & 10 deletions
This file was deleted.

public/vendors/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Vendors
2+
3+
These are node_module files that are copied over to the public folder. These are loaded into the server side.
4+
5+
To add files, edit [/scripts/copy-engines-to-public.js](/scripts/copy-engines-to-public.js) and run `pnpm run vendors`

public/vendors/math.js

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)