initial commit
342
gulpfile.js
|
@ -1,342 +0,0 @@
|
|||
|
||||
const path = require('path');
|
||||
|
||||
const gulp = require('gulp');
|
||||
const debug = require('gulp-debug');
|
||||
const del = require("del");
|
||||
const through = require('through2');
|
||||
const Vinyl = require("vinyl");
|
||||
const merge = require('merge-stream');
|
||||
const rename = require("gulp-rename");
|
||||
const concat = require('gulp-concat');
|
||||
const add = require('gulp-add');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const runSequence = require('run-sequence');
|
||||
const uglify = require('gulp-uglify');
|
||||
const babel = require('gulp-babel');
|
||||
const browserify = require('browserify');
|
||||
const buffer = require("vinyl-buffer");
|
||||
const source = require('vinyl-source-stream');
|
||||
const argv = require('yargs').argv;
|
||||
const gulpif = require('gulp-if');
|
||||
const gutil = require('gulp-util');
|
||||
|
||||
const modulifyHeaders = {
|
||||
model:
|
||||
`exports.model = Model = {
|
||||
Game: {},
|
||||
Board: {},
|
||||
Move: {}
|
||||
};
|
||||
`
|
||||
,
|
||||
view:
|
||||
`exports.view = View = {
|
||||
Game: {},
|
||||
Board: {},
|
||||
Move: {}
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
const allGames = {};
|
||||
|
||||
function HandleModuleGames(modelOnly) {
|
||||
|
||||
return through.obj(function(file,enc,next) {
|
||||
// this is executed for every game module
|
||||
var push = this.push.bind(this);
|
||||
var moduleName = path.basename(file.path);
|
||||
var moduleManifest = require(file.path);
|
||||
var streams = [];
|
||||
moduleManifest.games.forEach((game) => {
|
||||
// this is executed for every game in the game module
|
||||
|
||||
// same some game data so we can list all games later
|
||||
allGames[game.name] = {
|
||||
title: game.config.model["title-en"],
|
||||
summary: game.config.model.summary,
|
||||
thumbnail: game.config.model.thumbnail,
|
||||
module: moduleName
|
||||
};
|
||||
|
||||
// create the game config file
|
||||
push(new Vinyl({
|
||||
path: moduleName+"/"+game.name+"-config.js",
|
||||
contents: new Buffer('exports.config = '+JSON.stringify(game.config))
|
||||
}));
|
||||
|
||||
// create some specified resources
|
||||
if(!modelOnly)
|
||||
["thumbnail","rules","description","credits"].forEach((field)=>{
|
||||
var files = [];
|
||||
switch(typeof game.config.model[field]) {
|
||||
case "string":
|
||||
files.push(game.config.model[field]);
|
||||
break;
|
||||
case "object":
|
||||
for(var f in game.config.model[field])
|
||||
files.push(game.config.model[field][f]);
|
||||
break;
|
||||
}
|
||||
files = files.map((file)=>{
|
||||
return "src/games/"+moduleName+"/"+file;
|
||||
});
|
||||
var stream = gulp.src(files)
|
||||
.pipe(rename(function(path) {
|
||||
path.dirname = moduleName;
|
||||
}))
|
||||
.pipe(through.obj(function(file,enc,next) {
|
||||
push(file);
|
||||
next();
|
||||
}))
|
||||
;
|
||||
streams.push(stream);
|
||||
});
|
||||
|
||||
// create model and view script files
|
||||
function Scripts(which) {
|
||||
var scripts = game[which+"Scripts"].map((script) => {
|
||||
return "src/games/"+moduleName+"/"+script;
|
||||
});
|
||||
var fileName = moduleName+"/"+game.name+"-"+which+".js";
|
||||
var stream = gulp.src(scripts)
|
||||
.pipe(gulpif(!argv.prod,sourcemaps.init()))
|
||||
.pipe(add('_',modulifyHeaders[which],true))
|
||||
.pipe(concat(fileName))
|
||||
.pipe(gulpif(argv.prod,uglify()))
|
||||
.pipe(gulpif(!argv.prod,sourcemaps.write('.')))
|
||||
.pipe(through.obj(function(file,enc,next) {
|
||||
push(file);
|
||||
next();
|
||||
}))
|
||||
streams.push(stream);
|
||||
}
|
||||
if(modelOnly)
|
||||
Scripts("model");
|
||||
else
|
||||
["model","view"].forEach(Scripts);
|
||||
});
|
||||
|
||||
// create module common resources
|
||||
if(!modelOnly) {
|
||||
var stream = gulp.src("src/games/"+moduleName+"/res/**/*")
|
||||
.pipe(rename(function(path) {
|
||||
path.dirname = moduleName + "/res/" +path.dirname;
|
||||
}))
|
||||
.pipe(through.obj(function(file,enc,next) {
|
||||
push(file);
|
||||
next();
|
||||
}))
|
||||
;
|
||||
streams.push(stream);
|
||||
}
|
||||
|
||||
merge(streams)
|
||||
.on("finish",function() {
|
||||
next();
|
||||
})
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
gulp.task("build-node-games",function() {
|
||||
return gulp.src("src/games/*")
|
||||
.pipe(HandleModuleGames(true))
|
||||
.pipe(gulp.dest("dist/node/games"));
|
||||
});
|
||||
|
||||
function ProcessJS(stream,concatName,skipBabel) {
|
||||
if(!argv.prod)
|
||||
stream = stream.pipe(sourcemaps.init());
|
||||
if(!skipBabel)
|
||||
stream = stream.pipe(babel({
|
||||
presets: ['es2015']
|
||||
}));
|
||||
if(argv.prod)
|
||||
stream = stream.pipe(uglify())
|
||||
.on('error', function(err) {
|
||||
gutil.log(gutil.colors.red('[Error]'), err.toString());
|
||||
this.emit('end');
|
||||
})
|
||||
if(concatName)
|
||||
stream = stream.pipe(concat(concatName));
|
||||
if(!argv.prod)
|
||||
stream = stream.pipe(sourcemaps.write("."));
|
||||
return stream;
|
||||
}
|
||||
|
||||
gulp.task("build-node-core",function() {
|
||||
|
||||
var joclyCoreStream =
|
||||
ProcessJS(gulp.src([
|
||||
"src/core/jocly.core.js",
|
||||
]));
|
||||
|
||||
var joclyBaseStream =
|
||||
ProcessJS(gulp.src([
|
||||
"src/core/jocly.util.js",
|
||||
"src/core/jocly.uct.js",
|
||||
"src/core/jocly.game.js"
|
||||
]));
|
||||
|
||||
var joclyExtraStream = gulp.src([
|
||||
"src/node/package.json",
|
||||
]);
|
||||
|
||||
var joclyExtraScriptStream =
|
||||
ProcessJS(gulp.src([
|
||||
"src/node/jocly.proxy.js"
|
||||
]));
|
||||
|
||||
var allGamesStream = source('jocly-allgames.js');
|
||||
allGamesStream.end('exports.games = '+JSON.stringify(allGames));
|
||||
allGamesStream = ProcessJS(allGamesStream.pipe(buffer()));
|
||||
|
||||
return merge(joclyCoreStream,allGamesStream,joclyBaseStream,
|
||||
joclyExtraStream,joclyExtraScriptStream)
|
||||
.pipe(gulp.dest("dist/node"));
|
||||
|
||||
})
|
||||
|
||||
function CopyLicense(target) {
|
||||
return gulp.src(["COPYING.md","CONTRIBUTING.md","AGPL-3.0.txt"])
|
||||
.pipe(gulp.dest(target));
|
||||
}
|
||||
|
||||
gulp.task("copy-browser-license",function() {
|
||||
return CopyLicense("dist/browser");
|
||||
});
|
||||
|
||||
gulp.task("copy-node-license",function() {
|
||||
return CopyLicense("dist/node");
|
||||
});
|
||||
|
||||
gulp.task("build-node",function(callback) {
|
||||
runSequence("build-node-games",["build-node-core","copy-node-license"],callback);
|
||||
});
|
||||
|
||||
gulp.task("build-browser-games",function() {
|
||||
return gulp.src("src/games/*")
|
||||
.pipe(HandleModuleGames(false))
|
||||
.pipe(gulp.dest("dist/browser/games"));
|
||||
});
|
||||
|
||||
gulp.task("build-browser-core",function() {
|
||||
|
||||
var _ProcessJS = function(s) { return s; }
|
||||
|
||||
var b = browserify({
|
||||
entries: "src/browser/jocly.js",
|
||||
debug: true,
|
||||
standalone: "Jocly"
|
||||
});
|
||||
|
||||
var joclyBrowserStream = b.bundle()
|
||||
.pipe(source('jocly.js'))
|
||||
.pipe(buffer());
|
||||
|
||||
var joclyCoreStream = ProcessJS(gulp.src([
|
||||
"src/core/jocly.core.js",
|
||||
]));
|
||||
|
||||
var joclyBaseStream = ProcessJS(gulp.src([
|
||||
"src/core/jocly.util.js",
|
||||
"src/core/jocly.uct.js",
|
||||
"src/core/jocly.game.js"
|
||||
]),"jocly.game.js",true);
|
||||
|
||||
var joclyExtraScriptsStream = ProcessJS(gulp.src([
|
||||
"src/browser/jocly.aiworker.js",
|
||||
"src/browser/jocly.proxy.js",
|
||||
"src/browser/jocly.embed.js"
|
||||
]));
|
||||
|
||||
var joclyExtraStream = gulp.src([
|
||||
"src/browser/jocly.embed.html"
|
||||
]);
|
||||
|
||||
var joclyResStream = gulp.src("src/browser/res/**/*")
|
||||
.pipe(rename(function(path) {
|
||||
path.dirname = "res/"+path.dirname;
|
||||
}));
|
||||
|
||||
var allGamesStream = source('jocly-allgames.js');
|
||||
allGamesStream.end('exports.games = '+JSON.stringify(allGames));
|
||||
allGamesStream = ProcessJS(allGamesStream.pipe(buffer()));
|
||||
|
||||
return merge(joclyBrowserStream,joclyCoreStream,allGamesStream,joclyBaseStream,
|
||||
joclyExtraStream,joclyExtraScriptsStream,joclyResStream)
|
||||
.pipe(gulp.dest("dist/browser"));
|
||||
|
||||
});
|
||||
|
||||
gulp.task("build-browser-xdview",function() {
|
||||
const lib = "third-party/";
|
||||
const src = "src/";
|
||||
const srcLib = "src/lib/";
|
||||
const nmLib = "node_modules/";
|
||||
|
||||
var libs = ProcessJS(gulp.src([
|
||||
lib+"three.js",
|
||||
nmLib+"jquery/dist/jquery.js"
|
||||
]));
|
||||
|
||||
var packedLibs = ProcessJS(gulp.src([
|
||||
lib+"SubdivisionModifier.js",
|
||||
lib+"tween.js",
|
||||
lib+"tween.fix.js",
|
||||
srcLib+"JoclyOrbitControls.js",
|
||||
lib+"DeviceOrientationControls.js",
|
||||
lib+"Projector.js",
|
||||
lib+"threex.domevent.js",
|
||||
lib+"threex.domevent.object3d.js",
|
||||
lib+"StereoEffect.js",
|
||||
srcLib+"VRGamepad.js",
|
||||
lib+"VRControls.js",
|
||||
lib+"VREffect.js",
|
||||
src+"browser/jocly.ar.js",
|
||||
src+"browser/jocly.state-machine.js",
|
||||
src+"browser/jocly.xd-view.js"
|
||||
]),"jocly-xdview.js",true);
|
||||
|
||||
return merge(libs,packedLibs)
|
||||
.pipe(gulp.dest("dist/browser"))
|
||||
;
|
||||
|
||||
});
|
||||
|
||||
gulp.task("build-browser",function(callback) {
|
||||
runSequence("build-browser-games",["build-browser-core",
|
||||
"build-browser-xdview","copy-browser-license"],callback);
|
||||
});
|
||||
|
||||
|
||||
gulp.task("build",function(callback) {
|
||||
runSequence("clean",["build-browser","build-node"],callback);
|
||||
});
|
||||
|
||||
gulp.task("clean",function() {
|
||||
return del(["dist/*"],{force:true});
|
||||
});
|
||||
|
||||
gulp.task("watch",function() {
|
||||
gulp.watch("src/games/**/*",["build-node-games","build-browser-games"]);
|
||||
gulp.watch("src/{browser,core,lib}",["build-browser-core","build-browser-xdview"]);
|
||||
gulp.watch("src/{node,core}",["build-node-core"]);
|
||||
});
|
||||
|
||||
gulp.task("help", function() {
|
||||
var help = `
|
||||
usage: gulp [<commands>] [<options>]
|
||||
|
||||
commands:
|
||||
build: generate clean project build
|
||||
watch: watch project and build dynamically on changes
|
||||
|
||||
options:
|
||||
--prod: generate for production
|
||||
`;
|
||||
console.log(help);
|
||||
process.exit(0);
|
||||
});
|
35
package.json
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
"name": "jocly",
|
||||
"version": "0.0.1",
|
||||
"author": {
|
||||
"email": "mig@jocly.com",
|
||||
"name": "Michel Gutierrez",
|
||||
"url": "https://github.com/mi-g"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-es2015": "^6.24.0",
|
||||
"browserify": "^14.1.0",
|
||||
"del": "^2.2.2",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-add": "0.0.2",
|
||||
"gulp-babel": "^6.1.2",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-debug": "^3.1.0",
|
||||
"gulp-if": "^2.0.2",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-sourcemaps": "^2.4.1",
|
||||
"gulp-uglify": "^2.1.2",
|
||||
"jquery": "^3.2.1",
|
||||
"merge-stream": "^1.0.1",
|
||||
"run-sequence": "^1.2.2",
|
||||
"through2": "^2.0.3",
|
||||
"vinyl-buffer": "^1.0.0",
|
||||
"vinyl-source-stream": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"systemjs": "^0.20.10"
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/* Copyright 2017 Jocly
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the GNU Affero General Public License in all respects
|
||||
* for all of the code used other than as permitted herein. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you do not
|
||||
* wish to do so, delete this exception statement from your version. If you
|
||||
* delete this exception statement from all source files in the program,
|
||||
* then also delete it in the license file.
|
||||
*/
|
||||
|
||||
window = self;
|
||||
|
||||
var Jocly;
|
||||
|
||||
onmessage = function(e) {
|
||||
var t0 = Date.now();
|
||||
var message = e.data;
|
||||
var options = message.options;
|
||||
var importTime = 0;
|
||||
switch(message.type) {
|
||||
case "Init":
|
||||
var scripts = [
|
||||
message.baseURL+"jocly.core.js",
|
||||
];
|
||||
Jocly = self.exports = {};
|
||||
importScripts.apply(null,scripts);
|
||||
importTime = Date.now() - t0;
|
||||
break;
|
||||
case "Play":
|
||||
Jocly.createInternalGame(message.gameName,options).then((game)=>{
|
||||
game.mBoard.mMoves = [];
|
||||
game.Load({
|
||||
playedMoves: message.playedMoves
|
||||
});
|
||||
game.mDoneCallback = function(doneData) {
|
||||
postMessage({
|
||||
type: "Done",
|
||||
data: doneData
|
||||
});
|
||||
}
|
||||
game.mProgressCallback = function(percent) {
|
||||
postMessage({
|
||||
type: "Progress",
|
||||
percent: percent
|
||||
});
|
||||
}
|
||||
if(typeof(options.level)!="undefined")
|
||||
game.mTopLevel=options.level;
|
||||
if(typeof(options.maxDepth)!="undefined")
|
||||
game.mTopLevel=options.maxDepth;
|
||||
game.mStartTime = new Date().getTime();
|
||||
game.mExploredCount = 0;
|
||||
game.mPickedMoveIndex = 0;
|
||||
game.mBestMoves = [];
|
||||
game.mContexts = [];
|
||||
game.mDuration = 0;
|
||||
game.mAborted = false;
|
||||
game.mRandomSeed = 0;
|
||||
if(options.randomSeed && !isNaN(parseInt(options.randomSeed)))
|
||||
game.mRandomSeed = parseInt(options.randomSeed);
|
||||
if(game.mOptions.levelOptions) {
|
||||
game.mOptions.levelOptionsSaved=JSON.parse(JSON.stringify(game.mOptions.levelOptions));
|
||||
if(options.level)
|
||||
JocUtil.extend(game.mOptions.levelOptions,options.level);
|
||||
}
|
||||
switch(e.data.algo) {
|
||||
case "uct":
|
||||
JoclyUCT.startMachine(game,options);
|
||||
break;
|
||||
case "alpha-beta":
|
||||
game.Engine(game.mBoard, game.mTopLevel, false, 0, options.potential); // start algo
|
||||
game.Run();
|
||||
break;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
//console.info("initTime",Date.now()-e.data.t0);
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
/* Copyright 2017 Jocly
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the GNU Affero General Public License in all respects
|
||||
* for all of the code used other than as permitted herein. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you do not
|
||||
* wish to do so, delete this exception statement from your version. If you
|
||||
* delete this exception statement from all source files in the program,
|
||||
* then also delete it in the license file.
|
||||
*/
|
||||
|
||||
JoclyAR = (function($) {
|
||||
|
||||
var running = false;
|
||||
var videoElement = null;
|
||||
var canvas, context;
|
||||
var width = 320, height = 240;
|
||||
var modelSize = 5;
|
||||
var scale = .2;
|
||||
var threeCtx = null;
|
||||
var processing = false;
|
||||
var arWorker = null;
|
||||
var oposition = new THREE.Vector3();
|
||||
var oeuler = new THREE.Euler();
|
||||
|
||||
function AnimationFrame() {
|
||||
if(!running)
|
||||
return;
|
||||
if(!processing && videoElement.readyState === videoElement.HAVE_ENOUGH_DATA) {
|
||||
processing = true;
|
||||
context.drawImage(videoElement,0,0,width,height);
|
||||
var imageData = context.getImageData(0, 0, width, height);
|
||||
arWorker.postMessage({
|
||||
type: "Detect",
|
||||
imageData: imageData,
|
||||
vwidth: videoElement.clientWidth,
|
||||
vheight: videoElement.clientHeight
|
||||
});
|
||||
} else
|
||||
requestAnimationFrame(AnimationFrame);
|
||||
}
|
||||
|
||||
var mouseDownY = null, scale0 = scale;
|
||||
function MouseMove(event) {
|
||||
var y = event.clientY;
|
||||
var ratio = (y-mouseDownY) / event.target.clientHeight;
|
||||
scale = scale0 * (1 - ratio);
|
||||
threeCtx.animControl.trigger();
|
||||
}
|
||||
function Mouse(event) {
|
||||
switch(event.type) {
|
||||
case 'mousedown':
|
||||
if(event.button==1 || event.button==2) {
|
||||
mouseDownY = event.clientY;
|
||||
scale0 = scale;
|
||||
event.target.addEventListener('mousemove',MouseMove);
|
||||
}
|
||||
break;
|
||||
case 'mouseup':
|
||||
case 'mouseout':
|
||||
event.target.removeEventListener('mousemove',MouseMove);
|
||||
}
|
||||
}
|
||||
|
||||
var exports = {
|
||||
start: function() {
|
||||
JoclyPlazza.webrtc.startLocal(true,{
|
||||
video: {
|
||||
width: { ideal: width },
|
||||
height: { ideal: height },
|
||||
facingMode: "environment",
|
||||
frameRate: {ideal: 24 }
|
||||
}
|
||||
});
|
||||
},
|
||||
stop: function() {
|
||||
JoclyPlazza.webrtc.setChannel(null);
|
||||
},
|
||||
attach: function(data) {
|
||||
videoElement = data.element;
|
||||
JoclyPlazza.webrtc.attachMediaStream(data.element,data.stream);
|
||||
canvas = document.createElement("canvas");
|
||||
canvas.setAttribute("width",width);
|
||||
canvas.setAttribute("height",height);
|
||||
Object.assign(canvas.style,{
|
||||
width: width,
|
||||
height: height,
|
||||
visibility : "hidden",
|
||||
position: "absolute",
|
||||
"z-index": -2,
|
||||
top: 0,
|
||||
});
|
||||
document.body.appendChild(canvas);
|
||||
/*
|
||||
$("<canvas/>")
|
||||
.attr("width", width).attr("height",height)
|
||||
.width(width).height(height)
|
||||
.css({
|
||||
visibility : "hidden",
|
||||
position: "absolute",
|
||||
"z-index": -2,
|
||||
top: 0,
|
||||
}).appendTo("body");
|
||||
*/
|
||||
context = canvas.getContext("2d");
|
||||
threeCtx = data.threeCtx;
|
||||
running = true;
|
||||
processing = false;
|
||||
threeCtx.renderer.domElement.addEventListener("mousedown",Mouse);
|
||||
threeCtx.renderer.domElement.addEventListener("mouseup",Mouse);
|
||||
threeCtx.renderer.domElement.addEventListener("mouseout",Mouse);
|
||||
|
||||
arWorker = new Worker(JoclyPlazza.config.baseURL+JoclyPlazza.config.joclyPath+'/jocly.arworker.js');
|
||||
arWorker.onmessage = function(e) {
|
||||
processing = false;
|
||||
var message = e.data;
|
||||
switch(message.type) {
|
||||
case "Pose":
|
||||
var rotation = message.rotation;
|
||||
var translation = message.translation;
|
||||
|
||||
threeCtx.body.position.set(0,0,0);
|
||||
threeCtx.camera.lookAt(new THREE.Vector3(0,-1,0));
|
||||
|
||||
threeCtx.harbor.scale.set(modelSize*scale,modelSize*scale,modelSize*scale);
|
||||
|
||||
threeCtx.harbor.rotation.set(
|
||||
-Math.asin(-rotation[1][2]),
|
||||
Math.atan2(rotation[1][0], rotation[1][1]),
|
||||
-Math.atan2(rotation[0][2], rotation[2][2])
|
||||
);
|
||||
threeCtx.harbor.position.set(
|
||||
translation[0],
|
||||
-translation[2],
|
||||
-translation[1]
|
||||
);
|
||||
if(!threeCtx.harbor.position.equals(oposition) ||
|
||||
!threeCtx.harbor.rotation.equals(oeuler))
|
||||
threeCtx.animControl.trigger();
|
||||
oposition.copy(threeCtx.harbor.position);
|
||||
oeuler.copy(threeCtx.harbor.rotation);
|
||||
break;
|
||||
case "NoPose":
|
||||
break;
|
||||
}
|
||||
setTimeout(AnimationFrame,20);
|
||||
}
|
||||
arWorker.postMessage({
|
||||
type: "Init",
|
||||
baseUrl: JoclyPlazza.config.baseURL+JoclyPlazza.config.joclyPath,
|
||||
modelSize: modelSize,
|
||||
width: width,
|
||||
height: height
|
||||
});
|
||||
requestAnimationFrame(AnimationFrame);
|
||||
},
|
||||
detach: function(data) {
|
||||
threeCtx.renderer.domElement.removeEventListener("mousedown",Mouse);
|
||||
threeCtx.renderer.domElement.removeEventListener("mouseup",Mouse);
|
||||
threeCtx.renderer.domElement.removeEventListener("mouseout",Mouse);
|
||||
JoclyPlazza.webrtc.detachMediaStream(data.element);
|
||||
videoElement = null;
|
||||
running = false;
|
||||
canvas.parentNode.removeChild(canvas);
|
||||
context = null;
|
||||
threeCtx = null;
|
||||
arWorker.terminate();
|
||||
arWorker = null;
|
||||
}
|
||||
}
|
||||
|
||||
return exports;
|
||||
|
||||
|
||||
})();
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
<!doctype html>
|
||||
|
||||
<html style="width: 100%; height: 100%">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Jocly</title>
|
||||
<meta name="description" content="Jocly embedded viewport">
|
||||
<meta name="author" content="Jocly">
|
||||
|
||||
</head>
|
||||
|
||||
<body style="width: 100%; height: 100%; margin: 0">
|
||||
|
||||
<div id="area" style="width: 100%; height: 100%"></div>
|
||||
|
||||
<script src="jocly.js"></script>
|
||||
<script src="jocly.embed.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,131 +0,0 @@
|
|||
/* Copyright 2017 Jocly
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the GNU Affero General Public License in all respects
|
||||
* for all of the code used other than as permitted herein. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you do not
|
||||
* wish to do so, delete this exception statement from your version. If you
|
||||
* delete this exception statement from all source files in the program,
|
||||
* then also delete it in the license file.
|
||||
*/
|
||||
|
||||
var gameId;
|
||||
var gGame;
|
||||
|
||||
window.addEventListener("message", receiveMessage, false);
|
||||
|
||||
function receiveMessage(event)
|
||||
{
|
||||
console.info("embed receives message",event.data);
|
||||
var origin = event.origin || event.originalEvent.origin;
|
||||
var url = new URL(window.location);
|
||||
if(origin!=url.origin)
|
||||
return;
|
||||
function Reply(message) {
|
||||
window.parent.postMessage({
|
||||
joclyEmbeddedGameId: gameId,
|
||||
replyId: event.data.replyId,
|
||||
message: message
|
||||
},"*");
|
||||
}
|
||||
var message = event.data.message;
|
||||
switch(message.type) {
|
||||
case "init":
|
||||
gameId = message.id;
|
||||
var area = document.getElementById("area");
|
||||
Jocly.createInternalGame(message.gameName).then((game) => {
|
||||
gGame = game;
|
||||
game.AddListener(Listen);
|
||||
function Start() {
|
||||
game.AttachElement(area).then(()=>{
|
||||
game.GameInitView();
|
||||
game.DisplayBoard();
|
||||
Reply();
|
||||
});
|
||||
}
|
||||
if (document.readyState === "complete"
|
||||
|| document.readyState === "loaded"
|
||||
|| document.readyState === "interactive")
|
||||
Start();
|
||||
else
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
Start();
|
||||
});
|
||||
});
|
||||
break;
|
||||
case "humanTurn":
|
||||
gGame.HumanTurn();
|
||||
break;
|
||||
case "machineTurn":
|
||||
gGame.StartMachine(message.options);
|
||||
break;
|
||||
case "getFinished":
|
||||
var finished = gGame.GetFinished();
|
||||
Reply({
|
||||
finished: !!finished,
|
||||
winner: finished
|
||||
});
|
||||
break;
|
||||
case "getMoveString":
|
||||
var move = new (gGame.GetMoveClass())(message.move);
|
||||
Reply(move.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function Listen(message) {
|
||||
switch(message.type) {
|
||||
case "human-move":
|
||||
gGame.ApplyMove(message.move);
|
||||
var finished = gGame.GetFinished();
|
||||
if(!finished)
|
||||
gGame.InvertWho();
|
||||
gGame.DisplayBoard();
|
||||
Object.assign(message,{
|
||||
finished: !!finished,
|
||||
winner: finished
|
||||
});
|
||||
break;
|
||||
case "machine-move":
|
||||
var move = message.result.move;
|
||||
delete message.result.move;
|
||||
gGame.PlayMove(move)
|
||||
.then(()=>{
|
||||
var finished = gGame.GetFinished();
|
||||
if(!finished)
|
||||
gGame.InvertWho();
|
||||
gGame.DisplayBoard();
|
||||
window.parent.postMessage({
|
||||
joclyEmbeddedGameId: gameId,
|
||||
message: {
|
||||
type: "machine-move",
|
||||
moveData: message.result,
|
||||
move: move,
|
||||
finished: !!finished,
|
||||
winner: finished
|
||||
}
|
||||
},"*");
|
||||
});
|
||||
return;
|
||||
}
|
||||
window.parent.postMessage({
|
||||
joclyEmbeddedGameId: gameId,
|
||||
message: message
|
||||
},"*");
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/* Copyright 2017 Jocly
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the GNU Affero General Public License in all respects
|
||||
* for all of the code used other than as permitted herein. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you do not
|
||||
* wish to do so, delete this exception statement from your version. If you
|
||||
* delete this exception statement from all source files in the program,
|
||||
* then also delete it in the license file.
|
||||
*/
|
||||
|
||||
const SystemJS = require("../../node_modules/systemjs/dist/system.js");
|
||||
|
||||
function GetScriptPath() {
|
||||
var scripts= document.getElementsByTagName('script');
|
||||
var path= scripts[scripts.length-1].src.split('?')[0];
|
||||
var mydir= path.split('/').slice(0, -1).join('/')+'/';
|
||||
return new URL(mydir).pathname;
|
||||
}
|
||||
|
||||
const joclyScriptPath = GetScriptPath();
|
||||
|
||||
SystemJS.config({
|
||||
baseURL: joclyScriptPath
|
||||
});
|
||||
|
||||
function ExportFunction(fName) {
|
||||
exports[fName] = function() {
|
||||
var args = arguments;
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
SystemJS.import("jocly.core.js").then((m)=>{
|
||||
m[fName].apply(m,args).then(function() {
|
||||
resolve.apply(null,arguments);
|
||||
},(e)=>{
|
||||
reject(e);
|
||||
});
|
||||
},(e)=>{
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
["listGames","createGame","createInternalGame"].forEach((fName)=>{
|
||||
ExportFunction(fName);
|
||||
});
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
/* Copyright 2017 Jocly
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the GNU Affero General Public License in all respects
|
||||
* for all of the code used other than as permitted herein. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you do not
|
||||
* wish to do so, delete this exception statement from your version. If you
|
||||
* delete this exception statement from all source files in the program,
|
||||
* then also delete it in the license file.
|
||||
*/
|
||||
|
||||
var gameConfigs = {}
|
||||
var gameIdRef = 0;
|
||||
var messageListenerInstalled = false;
|
||||
var games = {};
|
||||
var msgIdRef = 0;
|
||||
var messageReplies = {};
|
||||
|
||||
function MessageListener(event) {
|
||||
var game = games[event.data.joclyEmbeddedGameId];
|
||||
console.info("proxy receives message",event.data);
|
||||
if(game) {
|
||||
var replyId = event.data.replyId;
|
||||
if(replyId) {
|
||||
var reply = messageReplies[replyId];
|
||||
if(reply) {
|
||||
delete messageReplies[replyId];
|
||||
reply(event.data.message);
|
||||
}
|
||||
} else
|
||||
game.listeners.forEach((listener)=>{
|
||||
listener.call(game,event.data.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function GameProxyClass(gameName) {
|
||||
this.gameName = gameName;
|
||||
this.listeners = [];
|
||||
this.id = ++gameIdRef;
|
||||
}
|
||||
|
||||
GameProxyClass.prototype.attachElement = function(element,options) {
|
||||
var self = this;
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
if(!messageListenerInstalled) {
|
||||
messageListenerInstalled = true;
|
||||
window.addEventListener("message",MessageListener);
|
||||
}
|
||||
|
||||
this.element = element;
|
||||
var iframeUrl = "jocly.embed.html";
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
var attrs = {
|
||||
name: "jocly-embedded-"+self.id,
|
||||
frameborder: 0,
|
||||
src: SystemJS.getConfig().baseURL+iframeUrl,
|
||||
width: "100%",
|
||||
height: "100%"
|
||||
}
|
||||
Object.keys(attrs).forEach((attr)=>{
|
||||
iframe.setAttribute(attr,attrs[attr]);
|
||||
});
|
||||
Object.assign(iframe.style,{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
whiteSpace: "normal",
|
||||
});
|
||||
|
||||
var wrapper = document.createElement("div");
|
||||
Object.assign(wrapper.style,{
|
||||
position: "relative",
|
||||
whiteSpace: "nowrap",
|
||||
width: "100%",
|
||||
height: "100%"
|
||||
});
|
||||
wrapper.appendChild(iframe);
|
||||
element.appendChild(wrapper);
|
||||
|
||||
this.iframe = iframe;
|
||||
|
||||
iframe.onload = ()=>{
|
||||
PostMessage(self,{
|
||||
type: "init",
|
||||
id: this.id,
|
||||
gameName: this.gameName
|
||||
},(reply)=>{
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
function PostMessage(game,message,reply) {
|
||||
var wrapper = {
|
||||
message: message
|
||||
}
|
||||
if(reply) {
|
||||
var replyId = ++msgIdRef;
|
||||
wrapper.replyId = replyId;
|
||||
messageReplies[replyId] = reply;
|
||||
}
|
||||
game.iframe.contentWindow.postMessage(wrapper,"*");
|
||||
}
|
||||
|
||||
GameProxyClass.prototype.listen = function(listener) {
|
||||
var self = this;
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
self.listeners.push(listener);
|
||||
resolve();
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
GameProxyClass.prototype.unlisten = function(listener) {
|
||||
var self = this;
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
for(var i = self.listeners.length-1;i>=0;i--)
|
||||
if(self.listeners[i]==listener)
|
||||
self.listeners.splice(i,1);
|
||||
resolve();
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
GameProxyClass.prototype.humanTurn = function() {
|
||||
var self = this;
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
PostMessage(self,{
|
||||
type: "humanTurn"
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
GameProxyClass.prototype.machineTurn = function(options) {
|
||||
var self = this;
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
PostMessage(self,{
|
||||
type: "machineTurn",
|
||||
options: options
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
GameProxyClass.prototype.getFinished = function() {
|
||||
var self = this;
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
PostMessage(self,{
|
||||
type: "getFinished"
|
||||
},(result) => {
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
GameProxyClass.prototype.getMoveString = function(move) {
|
||||
var self = this;
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
PostMessage(self,{
|
||||
type: "getMoveString",
|
||||
move: move
|
||||
},(move) => {
|
||||
resolve(move);
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
function CreateGame(gameName) {
|
||||
var promise = new Promise((resolve,reject)=>{
|
||||
|
||||
function CreateGame(config) {
|
||||
var game = new GameProxyClass(gameName);
|
||||
games[game.id] = game;
|
||||
Object.assign(game,config);
|
||||
resolve(game);
|
||||
}
|
||||
|
||||
var config = gameConfigs[gameName];
|
||||
if(config)
|
||||
CreateGame(config);
|
||||
else {
|
||||
Jocly.listGames()
|
||||
.then((games)=>{
|
||||
var gameDescr = games[gameName];
|
||||
if (!gameDescr)
|
||||
return reject(new Error("Game " + gameName + " not found"));
|
||||
SystemJS.import("games/" + gameDescr.module + "/" + gameName + "-config.js")
|
||||
.then((config)=>{
|
||||
gameConfigs[gameName] = config;
|
||||
CreateGame(config);
|
||||
});
|
||||
|
||||
},reject);
|
||||
}
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
|
||||
this.GameProxy = {
|
||||
createGame: CreateGame
|
||||
}
|
||||
else
|
||||
exports.createGame = CreateGame;
|
|
@ -1,475 +0,0 @@
|
|||
/* Copyright 2017 Jocly
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the GNU Affero General Public License in all respects
|
||||
* for all of the code used other than as permitted herein. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you do not
|
||||
* wish to do so, delete this exception statement from your version. If you
|
||||
* delete this exception statement from all source files in the program,
|
||||
* then also delete it in the license file.
|
||||
*/
|
||||
|
||||
function JHStateMachine() {
|
||||
}
|
||||
|
||||
JHStateMachine.prototype={}
|
||||
|
||||
JHStateMachine.prototype.init=function() {
|
||||
this.smState=null;
|
||||
this.smStates={};
|
||||
this.smEventQueue=[];
|
||||
this.smScheduled=false;
|
||||
this.smPauseNotified=false;
|
||||
this.smPaused=true;
|
||||
this.smHistory=[];
|
||||
this.smGroups={};
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smDebug=function() {}
|
||||
JHStateMachine.prototype.smWarning=function() {}
|
||||
JHStateMachine.prototype.smError=function() {}
|
||||
|
||||
JHStateMachine.prototype.smTransition=function(states,events,newState,methods) {
|
||||
states=this.smSolveStates(states);
|
||||
if(typeof(events)=="string") {
|
||||
events=[events];
|
||||
}
|
||||
if(typeof(methods)=="string") {
|
||||
methods=[methods];
|
||||
}
|
||||
for(var s in states) {
|
||||
var stateName=states[s];
|
||||
if(typeof(this.smStates[stateName])=="undefined") {
|
||||
this.smStates[stateName]={
|
||||
transitions: {},
|
||||
enteringMethods: [],
|
||||
leavingMethods: []
|
||||
}
|
||||
}
|
||||
for(var e in events) {
|
||||
var eventName=events[e];
|
||||
if(typeof(this.smStates[stateName].transitions[eventName])=="undefined") {
|
||||
this.smStates[stateName].transitions[eventName]={
|
||||
state: (newState!=null)?newState:stateName,
|
||||
methods: []
|
||||
};
|
||||
}
|
||||
for(var m in methods) {
|
||||
var methodName=methods[m];
|
||||
this.smStates[stateName].transitions[eventName].methods.push(methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(newState!=null && typeof(this.smStates[newState])=="undefined") {
|
||||
this.smStates[newState]={
|
||||
transitions: {},
|
||||
enteringMethods: [],
|
||||
leavingMethods: []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smEntering=function(states,methods) {
|
||||
if(typeof(states)=="string") {
|
||||
states=[states];
|
||||
}
|
||||
if(typeof(methods)=="string") {
|
||||
methods=[methods];
|
||||
}
|
||||
for(var s in states) {
|
||||
var stateName=states[s];
|
||||
if(typeof(this.smStates[stateName])=="undefined") {
|
||||
this.smStates[stateName]={
|
||||
transitions: {},
|
||||
enteringMethods: [],
|
||||
leavingMethods: []
|
||||
}
|
||||
}
|
||||
for(var m in methods) {
|
||||
var methodName=methods[m];
|
||||
this.smStates[stateName].enteringMethods.push(methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smLeaving=function(states,methods) {
|
||||
if(typeof(states)=="string") {
|
||||
states=[states];
|
||||
}
|
||||
if(typeof(methods)=="string") {
|
||||
methods=[methods];
|
||||
}
|
||||
for(var s in states) {
|
||||
var stateName=states[s];
|
||||
if(typeof(this.smStates[stateName])=="undefined") {
|
||||
this.smStates[stateName]={
|
||||
transitions: {},
|
||||
enteringMethods: [],
|
||||
leavingMethods: []
|
||||
}
|
||||
}
|
||||
for(var m in methods) {
|
||||
var methodName=methods[m];
|
||||
this.smStates[stateName].leavingMethods.push(methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smStateGroup=function(group,states) {
|
||||
if(typeof(states)=="string")
|
||||
states=[states];
|
||||
if(typeof(this.smGroups[group])=="undefined")
|
||||
this.smGroups[group]=[];
|
||||
states=this.smSolveStates(states);
|
||||
for(var i in states) {
|
||||
var state=states[i];
|
||||
if(!this.smContained(state,this.smGroups[group]))
|
||||
this.smGroups[group].push(state);
|
||||
}
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smSetInitialState=function(state) {
|
||||
this.smState=state;
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smGetState=function() {
|
||||
return this.smState;
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smHandleEvent=function(event,args) {
|
||||
|
||||
if(typeof(this.smStates[this.smState])=="undefined") {
|
||||
console.error("Unknown state '",this.smState,"'");
|
||||
return;
|
||||
}
|
||||
var hEntry={
|
||||
date: new Date().getTime(),
|
||||
fromState: this.smState,
|
||||
event: event,
|
||||
methods: []
|
||||
}
|
||||
try {
|
||||
hEntry.args=JSON.stringify(args);
|
||||
} catch(e) {
|
||||
//console.error("handleEvent(event,...) JSON.stringify(args): ",e);
|
||||
}
|
||||
|
||||
var transition=this.smStates[this.smState].transitions[event];
|
||||
if(typeof(transition)=="undefined") {
|
||||
console.warn("JHStateMachine: Event '",event,"' not handled in state '",this.smState,"'");
|
||||
return;
|
||||
}
|
||||
|
||||
this.smCurrentEvent=event;
|
||||
|
||||
var stateChanged=(this.smState!=transition.state);
|
||||
|
||||
if(stateChanged) {
|
||||
var leavingMethods=this.smStates[this.smState].leavingMethods;
|
||||
for(var i in leavingMethods) {
|
||||
try {
|
||||
hEntry.methods.push(leavingMethods[i]);
|
||||
if(typeof leavingMethods[i]=="function")
|
||||
leavingMethods[i].call(this,args);
|
||||
else
|
||||
this['$'+leavingMethods[i]](args);
|
||||
} catch(e) {
|
||||
console.error("Exception in leaving [",this.smState,"] --> "+
|
||||
(typeof leavingMethods[i]=="function"?leavingMethods[i].name:leavingMethods[i])
|
||||
+"(",args,"): ",e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(var i in transition.methods) {
|
||||
try {
|
||||
hEntry.methods.push(transition.methods[i]);
|
||||
if(typeof transition.methods[i]=="function")
|
||||
transition.methods[i].call(this,args);
|
||||
else
|
||||
this['$'+transition.methods[i]](args);
|
||||
} catch(e) {
|
||||
console.error("Exception in ["+this.smState+"] -- "+event+" --> "+
|
||||
(typeof transition.methods[i]=="function"?transition.methods[i].name:transition.methods[i])
|
||||
+"(",args,"): ",
|
||||
e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
this.smJHStateMachineLeavingState(this.smState,event,args);
|
||||
|
||||
|
||||
this.smDebug("{",this.smState,"} == [",event,"] ==> {",transition.state,"}");
|
||||
|
||||
|
||||
this.smState=transition.state;
|
||||
|
||||
if(stateChanged) {
|
||||
var enteringMethods=this.smStates[this.smState].enteringMethods;
|
||||
for(var i in enteringMethods) {
|
||||
try {
|
||||
hEntry.methods.push(enteringMethods[i]);
|
||||
if(typeof enteringMethods[i]=="function")
|
||||
enteringMethods[i].call(this,args);
|
||||
else
|
||||
this['$'+enteringMethods[i]](args);
|
||||
} catch(e) {
|
||||
console.error("Exception in entering ["+this.smState+"] --> "+
|
||||
(typeof enteringMethods[i]=="function"?enteringMethods[i].name:enteringMethods[i])
|
||||
+"(",args,"): ",e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.smCurrentEvent=null;
|
||||
|
||||
this.smJHStateMachineEnteringState(this.smState,event,args);
|
||||
|
||||
hEntry.toState=this.smState;
|
||||
this.smHistory.splice(0,0,hEntry);
|
||||
while(this.smHistory.length>50)
|
||||
this.smHistory.pop();
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smPlay=function() {
|
||||
var $this=this;
|
||||
if(this.smPaused) {
|
||||
this.smPaused=false;
|
||||
setTimeout(function() {
|
||||
$this.smRun();
|
||||
},0);
|
||||
}
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smPause=function() {
|
||||
this.smPaused=true;
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smStep=function() {
|
||||
this.smPauseNotified=false;
|
||||
if(this.smEventQueue.length>0) {
|
||||
var eventItem=this.smEventQueue.shift();
|
||||
this.smHandleEvent(eventItem.event,eventItem.args);
|
||||
}
|
||||
this.smNotifyPause();
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smRun=function() {
|
||||
this.smScheduled=false;
|
||||
|
||||
var stepCount=0;
|
||||
while(this.smEventQueue.length>0) {
|
||||
if(this.smPaused) {
|
||||
this.smRunEnd(stepCount);
|
||||
return;
|
||||
} else {
|
||||
stepCount++;
|
||||
this.smStep();
|
||||
}
|
||||
}
|
||||
while(this.smPaused==false && this.smEventQueue.length>0) {
|
||||
stepCount++;
|
||||
this.smStep();
|
||||
}
|
||||
this.smRunEnd(stepCount);
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smRunEnd=function() {
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smQueueEvent=function(event,args) {
|
||||
var self=this;
|
||||
this.smEventQueue.push({event: event, args: args});
|
||||
this.smNotifyPause();
|
||||
if(!this.smScheduled) {
|
||||
this.smScheduled=true;
|
||||
setTimeout(function() {
|
||||
self.smRun();
|
||||
},0);
|
||||
}
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smNotifyPause=function() {
|
||||
if(this.smEventQueue.length>0 && this.smPaused==true) {
|
||||
var item=this.smEventQueue[0];
|
||||
this.smJHStateMachinePaused(item.event,item.args);
|
||||
}
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smJHStateMachineEnteringState=function(state,event,args) {
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smJHStateMachineLeavingState=function(state,event,args) {
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smJHStateMachinePaused=function(state,event,args) {
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smGetTable=function() {
|
||||
var cells={}
|
||||
for(var s in this.smStates) {
|
||||
var state=this.smStates[s];
|
||||
for(var e in state.transitions) {
|
||||
var toState=state.transitions[e].state;
|
||||
var cellname=s+"/"+toState;
|
||||
if(typeof(cells[cellname])=="undefined") {
|
||||
cells[cellname]={};
|
||||
}
|
||||
cells[cellname][e]=[];
|
||||
if(s!=toState) {
|
||||
for(var m in state.leavingMethods) {
|
||||
cells[cellname][e].push(state.leavingMethods[m]);
|
||||
}
|
||||
}
|
||||
for(var m in state.transitions[e].methods) {
|
||||
cells[cellname][e].push(state.transitions[e].methods[m]);
|
||||
}
|
||||
if(s!=toState) {
|
||||
for(var m in this.smStates[toState].enteringMethods) {
|
||||
cells[cellname][e].push(this.smStates[toState].enteringMethods[m]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var table=["<table><tr><td></td>"];
|
||||
for(var s in this.smStates) {
|
||||
table.push("<td class='state'>"+s+"</td>");
|
||||
}
|
||||
table.push("</tr>");
|
||||
for(var s1 in this.smStates) {
|
||||
table.push("<tr><td class='state'>"+s1+"</td>");
|
||||
var state1=this.smStates[s1];
|
||||
for(var s2 in this.smStates) {
|
||||
var state2=this.smStates[s2];
|
||||
var cellname=s1+"/"+s2;
|
||||
if(typeof(cells[cellname])=="undefined") {
|
||||
table.push("<td class='empty'></td>");
|
||||
} else {
|
||||
table.push("<td class='transition'>");
|
||||
for(var e in cells[cellname]) {
|
||||
table.push("<div class='event'>");
|
||||
table.push("<div class='eventname'>"+e+"</div>");
|
||||
for(var m in cells[cellname][e]) {
|
||||
table.push("<div class='method'>"+cells[cellname][e][m]+"</div>");
|
||||
}
|
||||
table.push("</div>");
|
||||
}
|
||||
table.push("</td>");
|
||||
}
|
||||
}
|
||||
table.push("</tr>");
|
||||
}
|
||||
table.push("</table>");
|
||||
return table.join("");
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smGetHistoryTable=function() {
|
||||
var table=["<table><tr><th>Date</th><th>To</th><th>Event</th><th>Methods</th><th>From</th></tr>"];
|
||||
for(var i in this.smHistory) {
|
||||
var hEntry=this.smHistory[i];
|
||||
table.push("<tr>");
|
||||
var date=new Date(hEntry.date);
|
||||
var timestamp=date.getHours()+":"+date.getMinutes()+":"+date.getSeconds()+"."+date.getMilliseconds();
|
||||
table.push("<td class='timestamp'>"+timestamp+"</td>");
|
||||
table.push("<td class='to'>"+hEntry.toState+"</td>");
|
||||
table.push("<td><div class='event'>"+hEntry.event+"</div><div class='args'>("+hEntry.args+")</div></td>");
|
||||
table.push("<td class='methods'>");
|
||||
for(var j in hEntry.methods) {
|
||||
table.push(hEntry.methods[j]+"<br/>");
|
||||
}
|
||||
table.push("</td>");
|
||||
table.push("<td class='from'>"+hEntry.fromState+"</td>");
|
||||
table.push("</tr>");
|
||||
}
|
||||
table.push("</table>");
|
||||
return table.join("");
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smSolveStates=function(states) {
|
||||
var states0=[];
|
||||
if(typeof(states)=="string") {
|
||||
states=[states];
|
||||
}
|
||||
for(var s in states) {
|
||||
var state=states[s];
|
||||
if(typeof(this.smGroups[state])=="undefined") {
|
||||
if(!this.smContained(state,states0))
|
||||
states0.push(state);
|
||||
} else {
|
||||
for(var s0 in this.smGroups[state])
|
||||
if(!this.smContained(this.smGroups[state][s0]),states0)
|
||||
states0.push(this.smGroups[state][s0]);
|
||||
}
|
||||
}
|
||||
return states0;
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smContained=function(state,group) {
|
||||
for(var i in group) {
|
||||
if(state==group[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JHStateMachine.prototype.smCheck=function() {
|
||||
var result={
|
||||
missing: [],
|
||||
unused: []
|
||||
}
|
||||
var existingFnt=[];
|
||||
for(var s in this.smStates) {
|
||||
for(var i in this.smStates[s].enteringMethods) {
|
||||
var fnt=this.smStates[s].enteringMethods[i];
|
||||
existingFnt[fnt]=true;
|
||||
}
|
||||
for(var i in this.smStates[s].leavingMethods) {
|
||||
var fnt=this.smStates[s].leavingMethods[i];
|
||||
existingFnt[fnt]=true;
|
||||
}
|
||||
for(var e in this.smStates[s].transitions) {
|
||||
var event=this.smStates[s].transitions[e];
|
||||
for(var i in event.methods) {
|
||||
var fnt=event.methods[i];
|
||||
existingFnt[fnt]=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(var fnt in existingFnt) {
|
||||
if(typeof(this['$'+fnt])!="function") {
|
||||
result.missing.push(fnt);
|
||||
console.error("JHStateMachine: missing function $",fnt);
|
||||
}
|
||||
}
|
||||
for(var k in this) {
|
||||
try {
|
||||
if(k[0]=='$' && typeof(this[k])=="function") {
|
||||
var fnt=k.substr(1);
|
||||
if(typeof(existingFnt[fnt])=="undefined") {
|
||||
//this.warning("JHStateMachine.check "+this.target.name+": unused function "+k);
|
||||
result.unused.push(fnt);
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
return result;
|
||||
}
|
Before Width: | Height: | Size: 812 B |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 671 B |
Before Width: | Height: | Size: 487 B |
Before Width: | Height: | Size: 849 B |
Before Width: | Height: | Size: 838 B |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 428 B |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 303 B |
Before Width: | Height: | Size: 243 B |
Before Width: | Height: | Size: 891 B |
Before Width: | Height: | Size: 828 B |
Before Width: | Height: | Size: 243 B |
Before Width: | Height: | Size: 333 B |
Before Width: | Height: | Size: 636 B |
Before Width: | Height: | Size: 841 B |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 971 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 385 B |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 801 B |
Before Width: | Height: | Size: 801 B |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 58 KiB |
|
@ -1,154 +0,0 @@
|
|||
{
|
||||
|
||||
"metadata" :
|
||||
{
|
||||
"formatVersion" : 3.1,
|
||||
"generatedBy" : "Blender 2.64 Exporter",
|
||||
"vertices" : 24,
|
||||
"faces" : 6,
|
||||
"normals" : 6,
|
||||
"colors" : 0,
|
||||
"uvs" : [4],
|
||||
"materials" : 1,
|
||||
"morphTargets" : 0,
|
||||
"bones" : 0
|
||||
},
|
||||
|
||||
"scale" : 1.000000,
|
||||
|
||||
"materials" : [ {
|
||||
"DbgColor" : 15658734,
|
||||
"DbgIndex" : 0,
|
||||
"DbgName" : "Material",
|
||||
"blending" : "NormalBlending",
|
||||
"colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorSpecular" : [0.5, 0.5, 0.5],
|
||||
"depthTest" : true,
|
||||
"depthWrite" : true,
|
||||
"mapDiffuse" : "nz.jpg",
|
||||
"mapDiffuseWrap" : ["repeat", "repeat"],
|
||||
"shading" : "Lambert",
|
||||
"specularCoef" : 50,
|
||||
"transparency" : 1.0,
|
||||
"transparent" : false,
|
||||
"vertexColors" : false
|
||||
},
|
||||
|
||||
{
|
||||
"DbgColor" : 15597568,
|
||||
"DbgIndex" : 1,
|
||||
"DbgName" : "back",
|
||||
"blending" : "NormalBlending",
|
||||
"colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorSpecular" : [0.5, 0.5, 0.5],
|
||||
"depthTest" : true,
|
||||
"depthWrite" : true,
|
||||
"mapDiffuse" : "nx.jpg",
|
||||
"mapDiffuseWrap" : ["repeat", "repeat"],
|
||||
"shading" : "Lambert",
|
||||
"specularCoef" : 50,
|
||||
"transparency" : 1.0,
|
||||
"transparent" : false,
|
||||
"vertexColors" : false
|
||||
},
|
||||
|
||||
{
|
||||
"DbgColor" : 15597568,
|
||||
"DbgIndex" : 1,
|
||||
"DbgName" : "left",
|
||||
"blending" : "NormalBlending",
|
||||
"colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorSpecular" : [0.5, 0.5, 0.5],
|
||||
"depthTest" : true,
|
||||
"depthWrite" : true,
|
||||
"mapDiffuse" : "pz.jpg",
|
||||
"mapDiffuseWrap" : ["repeat", "repeat"],
|
||||
"shading" : "Lambert",
|
||||
"specularCoef" : 50,
|
||||
"transparency" : 1.0,
|
||||
"transparent" : false,
|
||||
"vertexColors" : false
|
||||
},
|
||||
|
||||
{
|
||||
"DbgColor" : 15597568,
|
||||
"DbgIndex" : 1,
|
||||
"DbgName" : "north",
|
||||
"blending" : "NormalBlending",
|
||||
"colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorSpecular" : [0.5, 0.5, 0.5],
|
||||
"depthTest" : true,
|
||||
"depthWrite" : true,
|
||||
"mapDiffuse" : "px.jpg",
|
||||
"mapDiffuseWrap" : ["repeat", "repeat"],
|
||||
"shading" : "Lambert",
|
||||
"specularCoef" : 50,
|
||||
"transparency" : 1.0,
|
||||
"transparent" : false,
|
||||
"vertexColors" : false
|
||||
},
|
||||
|
||||
{
|
||||
"DbgColor" : 15597568,
|
||||
"DbgIndex" : 1,
|
||||
"DbgName" : "up",
|
||||
"blending" : "NormalBlending",
|
||||
"colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorSpecular" : [0.5, 0.5, 0.5],
|
||||
"depthTest" : true,
|
||||
"depthWrite" : true,
|
||||
"mapDiffuse" : "py.jpg",
|
||||
"mapDiffuseWrap" : ["repeat", "repeat"],
|
||||
"shading" : "Lambert",
|
||||
"specularCoef" : 50,
|
||||
"transparency" : 1.0,
|
||||
"transparent" : false,
|
||||
"vertexColors" : false
|
||||
},
|
||||
|
||||
{
|
||||
"DbgColor" : 15597568,
|
||||
"DbgIndex" : 1,
|
||||
"DbgName" : "bottom",
|
||||
"blending" : "NormalBlending",
|
||||
"colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
|
||||
"colorSpecular" : [0.5, 0.5, 0.5],
|
||||
"depthTest" : true,
|
||||
"depthWrite" : true,
|
||||
"mapDiffuse" : "ny.jpg",
|
||||
"mapDiffuseWrap" : ["repeat", "repeat"],
|
||||
"shading" : "Lambert",
|
||||
"specularCoef" : 50,
|
||||
"transparency" : 1.0,
|
||||
"transparent" : false,
|
||||
"vertexColors" : false
|
||||
}],
|
||||
|
||||
"vertices" : [10,-10,10,10,-10,-10,10,10,10,10,10,-10,-10,-10,10,10,-10,10,-10,10,10,10,10,10,-10,-10,-10,-10,-10,10,-10,10,-10,-10,10,10,10,-10,-10,-10,-10,-10,10,10,-10,-10,10,-10,-10,10,10,10,10,10,-10,10,-10,10,10,-10,10,-10,-10,10,-10,10,-10,-10,-10,-10,-10,10],
|
||||
|
||||
"morphTargets" : [],
|
||||
|
||||
"normals" : [-1,0,0,0,0,-1,1,0,0,0,0,1,0,-1,0,0,1,0],
|
||||
|
||||
"colors" : [],
|
||||
|
||||
"uvs" : [[0.0001,0.0001,0.9999,0.0001,0.9999,0.9999,0.0001,0.9999]],
|
||||
|
||||
"faces" : [43,1,0,2,3,0,0,1,2,3,0,0,0,0,43,5,4,6,7,1,0,1,2,3,1,1,1,1,43,9,8,10,11,2,0,1,2,3,2,2,2,2,43,13,12,14,15,3,0,1,2,3,3,3,3,3,43,17,16,18,19,4,3,0,1,2,4,4,4,4,43,21,20,22,23,5,0,1,2,3,5,5,5,5],
|
||||
|
||||
"bones" : [],
|
||||
|
||||
"skinIndices" : [],
|
||||
|
||||
"skinWeights" : [],
|
||||
|
||||
"animation" : {}
|
||||
|
||||
|
||||
}
|
Before Width: | Height: | Size: 788 KiB |