Skip to content

Commit

Permalink
Changed to use jmotion for both siteswap analysis and juggling animat…
Browse files Browse the repository at this point in the history
…ion.
  • Loading branch information
7131 committed Jun 20, 2023
1 parent 287c304 commit 76bd2bf
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 1,055 deletions.
33 changes: 1 addition & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

You can analyze siteswaps.
If the siteswap is valid, the number of balls, the period, and the state are displayed respectively.
You can also demonstrate using JuggleMaster JavaScript.
You can also demonstrate using juggling simulator.

# File list

Expand All @@ -11,38 +11,7 @@ You can also demonstrate using JuggleMaster JavaScript.
<dd>This is the main page for the Siteswap Analyzer.</dd>
<dt>default.css</dt>
<dd>The style sheet for the main page.</dd>
<dt>grammar.js</dt>
<dd>The grammar object and the syntax converter.</dd>
<dt>parser.js</dt>
<dd>Classes for parser, token, syntax tree, and state stack.</dd>
<dt>validator.js</dt>
<dd>A siteswap validation class.</dd>
<dt>controller.js</dt>
<dd>This is a controller that receives the input of the main page and outputs the analysis result.</dd>
<dt>test.html</dt>
<dd>This is a page for testing the Siteswap Analyzer.</dd>
<dt>test.css</dt>
<dd>The style sheet for the test page.</dd>
<dt>test.js</dt>
<dd>This is a controller that receives the input of the test page and outputs the test result to the table.</dd>
</dl>

# Siteswap specifications by ABNF

The followings are the specifications of the pattern of the siteswap to be accepted.

```ABNF
Pattern = Async / Synch
Async = 1*EachHand
EachHand = AsyncSimple / AsyncMulti
AsyncSimple = Even / Odd
Even = "0" / "2" / "4" / "6" / "8" / "a" / "c" / "e" / "g" / "i" / "k" / "m" / "o" / "q" / "s" / "u" / "w" / "y"
Odd = "1" / "3" / "5" / "7" / "9" / "b" / "d" / "f" / "h" / "j" / "l" / "n" / "p" / "r" / "t" / "v" / "x" / "z"
AsyncMulti = "[" 2*AsyncSimple "]"
Synch = 1*BothHand ["*"]
BothHand = "(" OneHand "," OneHand ")"
OneHand = SynchSimple / SynchMulti
SynchSimple = Even ["x"]
SynchMulti = "[" 2*SynchSimple "]"
```

119 changes: 35 additions & 84 deletions controller.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,36 @@
// Controller class
const Controller = function() {
// fields
this._prev = "";
this._parser = new Parser(Grammar, Converter);
this._validator = new Validator();

// events
window.addEventListener("load", this._initialize.bind(this), false);
}

// Controller prototype
Controller.prototype = {

// initialize the private fields
"_initialize": function() {
"_initialize": function(e) {
// DOM elements
this._facade = new jmotion.Facade(document.getElementById("board"));
this._patternText = document.getElementById("pattern");
this._analyzeButton = document.getElementById("analyze");
this._startButton = document.getElementById("start");
this._stopButton = document.getElementById("stop");
this._resultArea = document.getElementById("result");
this._messageArea = document.getElementById("message");
const analyze = document.getElementById("analyze");
const start = document.getElementById("start");
const stop = document.getElementById("stop");

// button events
this._analyzeButton.addEventListener("click", this._analyze.bind(this), false);
this._startButton.addEventListener("click", this._start.bind(this), false);
this._stopButton.addEventListener("click", this._stop.bind(this), false);

// JuggleMaster
const board = document.getElementById("board");
board.width = board.clientWidth;
board.height = board.width;
this._jmj = new Jmj({ "canvas": board });
analyze.addEventListener("click", this._analyze.bind(this), false);
start.addEventListener("click", this._start.bind(this), false);
stop.addEventListener("click", this._stop.bind(this), false);

// analyze the query string
this._prev = "";
const pattern = this._getParam("pattern");
if (pattern != "") {
this._patternText.value = pattern;
const run = this._getParam("run");
if (run == "yes" || run == "true") {
this._start({});
this._start(e);
} else {
this._analyze({});
this._analyze(e);
}
}
},
Expand All @@ -60,95 +49,57 @@ Controller.prototype = {
"_analyze": function(e) {
// initialize
this._stop(e);
this._validator.reset();
this._prev = this._validator.toSmall(this._patternText.value);
this._resultArea.innerHTML = "";

// lexical and syntax analyze
const lex = this._parser.tokenize(this._prev);
if (lex.tokens == null) {
this._setError("unknown character(s)", lex.valid, lex.invalid);
return;
this._resultArea.className = "";
this._prev = this._patternText.value;

// siteswap analysis
const result = jmotion.Siteswap.analyze(this._prev);
if (result.valid) {
this._setResult(result);
} else {
this._resultArea.innerHTML = result.message;
this._resultArea.className = "error";
}
const syntax = this._parser.parse(lex.tokens);
if (syntax.tree == null) {
this._setError("syntax error", syntax.valid, syntax.invalid);
return;
}
this._setResult(syntax.tree);
},

// "Start" button process
"_start": function(e) {
// validate input text
this._messageArea.innerHTML = "";
if (this._patternText.value != this._prev) {
this._analyze(e);
}
if (this._validator.pattern == "") {
return;
}

// start
const obj = { "siteswap": this._validator.pattern, "showSiteswap": false };
if (!this._jmj.startJuggling(obj)) {
this._messageArea.innerHTML = "JuggleMaster error";
this._messageArea.className = "error";
const message = this._facade.startJuggling(this._patternText.value);
if (message != "") {
this._resultArea.innerHTML = message;
this._resultArea.className = "error";
}
},

// "Stop" button process
"_stop": function(e) {
this._jmj.stopJuggling();
},

// write the error string
"_setError": function(title, valid, invalid) {
// does the valid text exist?
if (0 < valid.length) {
valid = "OK: " + valid;
invalid = "NG: " + invalid;
}

// write to the DOM elements
const head = document.createElement("div");
const ok = document.createElement("div");
const ng = document.createElement("div");
head.innerHTML = title;
head.className = "error";
ok.innerHTML = valid;
ng.innerHTML = invalid;
ng.className = "error";
this._resultArea.appendChild(head);
this._resultArea.appendChild(ok);
this._resultArea.appendChild(ng);
this._facade.stopJuggling();
},

// write the result string
"_setResult": function(tree) {
"_setResult": function(result) {
// create DOM elements
const head = document.createElement("div");
this._resultArea.appendChild(head);

// get the result
this._validator.validate(tree);
if (!this._validator.valid) {
// not a siteswap
head.innerHTML = "Invalid";
head.className = "error";
return;
}

// siteswap
head.innerHTML = "Valid";
const balls = document.createElement("div");
const period = document.createElement("div");
const state = document.createElement("div");
balls.innerHTML = "balls: " + this._validator.balls;
period.innerHTML = "period: " + this._validator.period;
state.innerHTML = "state: " + this._validator.state.join(" ");
this._resultArea.appendChild(head);
this._resultArea.appendChild(balls);
this._resultArea.appendChild(period);
this._resultArea.appendChild(state);

// display the results
head.innerHTML = "Valid";
balls.innerHTML = "balls: " + result.count;
period.innerHTML = "period: " + result.period;
state.innerHTML = "state: " + result.state.join(" ");
},

}
Expand Down
6 changes: 4 additions & 2 deletions default.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ input[type="button"] {
margin-top: 2ex;
}

canvas {
svg {
border: 1px solid gray;
width: 90%;
height: 90%;
}

.table .row {
Expand All @@ -41,8 +42,9 @@ canvas {
width: auto;
}

canvas {
svg {
width: 300px;
height: 300px;
}

.table {
Expand Down
Loading

0 comments on commit 76bd2bf

Please sign in to comment.