diff --git a/app/assets/main.html b/app/assets/main.html index d2a3257b4..74737fd6b 100644 --- a/app/assets/main.html +++ b/app/assets/main.html @@ -31,9 +31,9 @@ <link rel="shortcut icon" href="/images/favicon.ico"> <link rel="stylesheet" href="/stylesheets/app.css"> - <script src="/lib/ace/ace.js"></script> - <!--[if IE 9]> <script src="/javascripts/vendor_with_box2d.js"></script> <![endif]--> - <!--[if !IE]><!--> <script src="/javascripts/vendor.js"></script> <!--<![endif]--> + <script src="/lib/ace/ace.js"></script> + <!--[if IE 9]><script src="/javascripts/box2d.js"></script><![endif]--> + <script src="/javascripts/vendor.js"></script> <script src="/javascripts/aether.js"></script> <script src="/javascripts/app.js"></script> <!-- it's all Backbone! --> diff --git a/app/lib/Angel.coffee b/app/lib/Angel.coffee index 94edc3088..39059ea7b 100644 --- a/app/lib/Angel.coffee +++ b/app/lib/Angel.coffee @@ -4,6 +4,7 @@ {now} = require 'lib/world/world_utils' World = require 'lib/world/world' CocoClass = require 'lib/CocoClass' +GoalManager = require 'lib/world/GoalManager' module.exports = class Angel extends CocoClass @nicks: ['Archer', 'Lana', 'Cyril', 'Pam', 'Cheryl', 'Woodhouse', 'Ray', 'Krieger'] @@ -210,6 +211,11 @@ module.exports = class Angel extends CocoClass @hireWorker() if rehire hireWorker: -> + unless Worker? + unless @initialized + @initialized = true + @doWork() + return null return if @worker @say 'Hiring worker.' @worker = new Worker @shared.workerCode @@ -232,7 +238,7 @@ module.exports = class Angel extends CocoClass work.testWorld = testWorld = new World work.userCodeMap testWorld.loadFromLevel work.level if @shared.goalManager - testGM = new @shared.goalManager.constructor @testWorld + testGM = new GoalManager(testWorld) testGM.setGoals work.goals testGM.setCode work.userCodeMap testGM.worldGenerationWillBegin() @@ -243,11 +249,12 @@ module.exports = class Angel extends CocoClass # If performance was really a priority in IE9, we would rework things to be able to skip this step. goalStates = testGM?.getGoalStates() - serialized = testWorld.serialize().serializedWorld + work.testWorld.goalManager.worldGenerationEnded() if work.testWorld.ended + serialized = testWorld.serialize() window.BOX2D_ENABLED = false - World.deserialize serialized, @angelsShare.worldClassMap, @shared.lastSerializedWorldFrames, @finishBeholdingWorld(goalStates) + World.deserialize serialized.serializedWorld, @shared.worldClassMap, @shared.lastSerializedWorldFrames, @finishBeholdingWorld(goalStates), serialized.startFrame, serialized.endFrame window.BOX2D_ENABLED = true - @shared.lastSerializedWorldFrames = serialized.frames + @shared.lastSerializedWorldFrames = serialized.serializedWorld.frames doSimulateWorld: (work) -> work.t1 = now() @@ -258,6 +265,7 @@ module.exports = class Angel extends CocoClass i = 0 while i < work.testWorld.totalFrames frame = work.testWorld.getFrame i++ + Backbone.Mediator.publish 'god:world-load-progress-changed', progress: 1 work.testWorld.ended = true system.finish work.testWorld.thangs for system in work.testWorld.systems work.t2 = now() diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index 32bb91bf7..be9ef5a7b 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -19,6 +19,7 @@ class CocoModel extends Backbone.Model @on 'error', @onError, @ @on 'add', @onLoaded, @ @saveBackup = _.debounce(@saveBackup, 500) + console.debug = console.log unless console.debug # Needed for IE10 and earlier setProjection: (project) -> return if project is @project diff --git a/app/views/play/level/tome/Spell.coffee b/app/views/play/level/tome/Spell.coffee index af5349f6e..43bfb0faf 100644 --- a/app/views/play/level/tome/Spell.coffee +++ b/app/views/play/level/tome/Spell.coffee @@ -110,19 +110,22 @@ module.exports = class Spell unless aether console.error @toString(), 'couldn\'t find a spellThang with aether of', @thangs cb false - workerMessage = - function: 'hasChangedSignificantly' - a: (newSource ? @originalSource) - spellKey: @spellKey - b: (currentSource ? @source) - careAboutLineNumbers: true - careAboutLint: true - @worker.addEventListener 'message', (e) => - workerData = JSON.parse e.data - if workerData.function is 'hasChangedSignificantly' and workerData.spellKey is @spellKey - @worker.removeEventListener 'message', arguments.callee, false - cb(workerData.hasChanged) - @worker.postMessage JSON.stringify(workerMessage) + if @worker + workerMessage = + function: 'hasChangedSignificantly' + a: (newSource ? @originalSource) + spellKey: @spellKey + b: (currentSource ? @source) + careAboutLineNumbers: true + careAboutLint: true + @worker.addEventListener 'message', (e) => + workerData = JSON.parse e.data + if workerData.function is 'hasChangedSignificantly' and workerData.spellKey is @spellKey + @worker.removeEventListener 'message', arguments.callee, false + cb(workerData.hasChanged) + @worker.postMessage JSON.stringify(workerMessage) + else + cb(aether.hasChangedSignificantly((newSource ? @originalSource), (currentSource ? @source), true, true)) createAether: (thang) -> aceConfig = me.get('aceConfig') ? {} @@ -130,11 +133,12 @@ module.exports = class Spell skipProtectAPI = @skipProtectAPI or not writable aetherOptions = createAetherOptions functionName: @name, codeLanguage: @language, functionParameters: @parameters, skipProtectAPI: skipProtectAPI aether = new Aether aetherOptions - workerMessage = - function: 'createAether' - spellKey: @spellKey - options: aetherOptions - @worker.postMessage JSON.stringify workerMessage + if @worker + workerMessage = + function: 'createAether' + spellKey: @spellKey + options: aetherOptions + @worker.postMessage JSON.stringify workerMessage aether updateLanguageAether: (@language) -> @@ -142,10 +146,11 @@ module.exports = class Spell spellThang.aether?.setLanguage @language spellThang.castAether = null Backbone.Mediator.publish 'tome:spell-changed-language', spell: @, language: @language - workerMessage = - function: 'updateLanguageAether' - newLanguage: @language - @worker.postMessage JSON.stringify workerMessage + if @worker + workerMessage = + function: 'updateLanguageAether' + newLanguage: @language + @worker.postMessage JSON.stringify workerMessage @transpile() toString: -> diff --git a/app/views/play/level/tome/SpellView.coffee b/app/views/play/level/tome/SpellView.coffee index aba6881cb..a2542ca08 100644 --- a/app/views/play/level/tome/SpellView.coffee +++ b/app/views/play/level/tome/SpellView.coffee @@ -400,19 +400,23 @@ module.exports = class SpellView extends CocoView @clearAetherDisplay() if codeHasChangedSignificantly and not codeIsAsCast - workerMessage = - function: 'transpile' - spellKey: @spell.spellKey - source: source + if @worker + workerMessage = + function: 'transpile' + spellKey: @spell.spellKey + source: source - @worker.addEventListener 'message', (e) => - workerData = JSON.parse e.data - if workerData.function is 'transpile' and workerData.spellKey is @spell.spellKey - @worker.removeEventListener 'message', arguments.callee, false - aether.problems = workerData.problems - aether.raw = source - finishUpdatingAether(aether) - @worker.postMessage JSON.stringify(workerMessage) + @worker.addEventListener 'message', (e) => + workerData = JSON.parse e.data + if workerData.function is 'transpile' and workerData.spellKey is @spell.spellKey + @worker.removeEventListener 'message', arguments.callee, false + aether.problems = workerData.problems + aether.raw = source + finishUpdatingAether(aether) + @worker.postMessage JSON.stringify(workerMessage) + else + aether.transpile source + finishUpdatingAether(aether) else finishUpdatingAether(aether) diff --git a/app/views/play/level/tome/TomeView.coffee b/app/views/play/level/tome/TomeView.coffee index 008953742..de1f10008 100644 --- a/app/views/play/level/tome/TomeView.coffee +++ b/app/views/play/level/tome/TomeView.coffee @@ -89,6 +89,7 @@ module.exports = class TomeView extends CocoView @cast() createWorker: -> + return null unless Worker? return new Worker('/javascripts/workers/aether_worker.js') generateTeamSpellMap: (spellObject) -> diff --git a/config.coffee b/config.coffee index 62d05b3d8..4f0ab82b7 100644 --- a/config.coffee +++ b/config.coffee @@ -25,9 +25,11 @@ exports.config = vendor[\/\\](?!scripts[\/\\]Box2d) |bower_components[\/\\](?!aether) )/// - 'javascripts/vendor_with_box2d.js': ///^( - vendor[\/\\] - |bower_components[\/\\](?!aether) # include box2dweb for profiling (and for IE9...) + 'javascripts/box2d.js': ///^( + # Include box2dweb for profiling and IE9 + # Vector renamed to Box2DVector to avoid name collisions + # TODO: move this to assets/lib since we're not really joining anything here? + (vendor[\/\\]scripts[\/\\]Box2dWeb-2.1.a.3) )/// 'javascripts/lodash.js': ///^( (bower_components[\/\\]lodash[\/\\]dist[\/\\]lodash.js) diff --git a/vendor/scripts/Box2dWeb-2.1.a.3.js b/vendor/scripts/Box2dWeb-2.1.a.3.js index bca465363..6adc1337d 100644 --- a/vendor/scripts/Box2dWeb-2.1.a.3.js +++ b/vendor/scripts/Box2dWeb-2.1.a.3.js @@ -67,7 +67,7 @@ var Box2D = {}; })(Box2D); //#TODO remove assignments from global namespace -var Vector = Array; +var Box2DVector = Array; var Vector_a2j_Number = Box2D.NVector; //package structure if (typeof(Box2D) === "undefined") Box2D = {}; @@ -1012,7 +1012,7 @@ Box2D.postDefs = []; tClip.id.features.incidentVertex = 1; } b2Collision.MakeClipPointVector = function () { - var r = new Vector(2); + var r = new Box2DVector(2); r[0] = new ClipVertex(); r[1] = new ClipVertex(); return r; @@ -1424,7 +1424,7 @@ Box2D.postDefs = []; case b2Shape.e_circleShape: { var circle = (shape instanceof b2CircleShape ? shape : null); - this.m_vertices = new Vector(1, true); + this.m_vertices = new Box2DVector(1, true); this.m_vertices[0] = circle.m_p; this.m_count = 1; this.m_radius = circle.m_radius; @@ -1534,7 +1534,7 @@ Box2D.postDefs = []; } b2DynamicTree.prototype.Query = function (callback, aabb) { if (this.m_root == null) return; - var stack = new Vector(); + var stack = new Box2DVector(); var count = 0; stack[count++] = this.m_root; while (count > 0) { @@ -1570,7 +1570,7 @@ Box2D.postDefs = []; segmentAABB.upperBound.x = Math.max(p1.x, tX); segmentAABB.upperBound.y = Math.max(p1.y, tY); } - var stack = new Vector(); + var stack = new Box2DVector(); var count = 0; stack[count++] = this.m_root; while (count > 0) { @@ -1713,8 +1713,8 @@ Box2D.postDefs = []; } b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase = function () { this.m_tree = new b2DynamicTree(); - this.m_moveBuffer = new Vector(); - this.m_pairBuffer = new Vector(); + this.m_moveBuffer = new Box2DVector(); + this.m_pairBuffer = new Box2DVector(); this.m_pairCount = 0; }; b2DynamicTreeBroadPhase.prototype.CreateProxy = function (aabb, userData) { @@ -1819,7 +1819,7 @@ Box2D.postDefs = []; this.m_pointCount = 0; }; b2Manifold.prototype.b2Manifold = function () { - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); + this.m_points = new Box2DVector(b2Settings.b2_maxManifoldPoints); for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { this.m_points[i] = new b2ManifoldPoint(); } @@ -2177,7 +2177,7 @@ Box2D.postDefs = []; this.m_v1 = new b2SimplexVertex(); this.m_v2 = new b2SimplexVertex(); this.m_v3 = new b2SimplexVertex(); - this.m_vertices = new Vector(3); + this.m_vertices = new Box2DVector(3); }; b2Simplex.prototype.b2Simplex = function () { this.m_vertices[0] = this.m_v1; @@ -2535,7 +2535,7 @@ Box2D.postDefs = []; this.m_normal = new b2Vec2(); }; b2WorldManifold.prototype.b2WorldManifold = function () { - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); + this.m_points = new Box2DVector(b2Settings.b2_maxManifoldPoints); for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { this.m_points[i] = new b2Vec2(); } @@ -3099,7 +3099,7 @@ Box2D.postDefs = []; } b2PolygonShape.prototype.SetAsArray = function (vertices, vertexCount) { if (vertexCount === undefined) vertexCount = 0; - var v = new Vector(); + var v = new Box2DVector(); var i = 0, tVec; for (i = 0; @@ -3468,8 +3468,8 @@ Box2D.postDefs = []; this.__super.b2Shape.call(this); this.m_type = b2Shape.e_polygonShape; this.m_centroid = new b2Vec2(); - this.m_vertices = new Vector(); - this.m_normals = new Vector(); + this.m_vertices = new Box2DVector(); + this.m_normals = new Box2DVector(); } b2PolygonShape.prototype.Reserve = function (count) { if (count === undefined) count = 0; @@ -3504,7 +3504,7 @@ Box2D.postDefs = []; b2PolygonShape.ComputeOBB = function (obb, vs, count) { if (count === undefined) count = 0; var i = 0; - var p = new Vector(count + 1); + var p = new Box2DVector(count + 1); for (i = 0; i < count; ++i) { p[i] = vs[i]; @@ -5450,9 +5450,9 @@ Box2D.postDefs = []; } b2Island.b2Island = function () {}; b2Island.prototype.b2Island = function () { - this.m_bodies = new Vector(); - this.m_contacts = new Vector(); - this.m_joints = new Vector(); + this.m_bodies = new Box2DVector(); + this.m_contacts = new Box2DVector(); + this.m_joints = new Box2DVector(); } b2Island.prototype.Initialize = function (bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) { if (bodyCapacity === undefined) bodyCapacity = 0; @@ -5691,7 +5691,7 @@ Box2D.postDefs = []; this.warmStarting = step.warmStarting; } b2World.b2World = function () { - this.s_stack = new Vector(); + this.s_stack = new Box2DVector(); this.m_contactManager = new b2ContactManager(); this.m_contactSolver = new b2ContactSolver(); this.m_island = new b2Island(); @@ -6156,7 +6156,7 @@ Box2D.postDefs = []; } b2World.prototype.RayCastAll = function (point1, point2) { var __this = this; - var result = new Vector(); + var result = new Box2DVector(); function RayCastAllWrapper(fixture, point, normal, fraction) { if (fraction === undefined) fraction = 0; @@ -6521,7 +6521,7 @@ Box2D.postDefs = []; var poly = ((shape instanceof b2PolygonShape ? shape : null)); var vertexCount = parseInt(poly.GetVertexCount()); var localVertices = poly.GetVertices(); - var vertices = new Vector(vertexCount); + var vertices = new Box2DVector(vertexCount); for (i = 0; i < vertexCount; ++i) { vertices[i] = b2Math.MulX(xf, localVertices[i]); @@ -6543,7 +6543,7 @@ Box2D.postDefs = []; Box2D.Dynamics.b2World.s_backupA = new b2Sweep(); Box2D.Dynamics.b2World.s_backupB = new b2Sweep(); Box2D.Dynamics.b2World.s_timestep = new b2TimeStep(); - Box2D.Dynamics.b2World.s_queue = new Vector(); + Box2D.Dynamics.b2World.s_queue = new Box2DVector(); Box2D.Dynamics.b2World.s_jointColor = new b2Color(0.5, 0.8, 0.8); Box2D.Dynamics.b2World.e_newFixture = 0x0001; Box2D.Dynamics.b2World.e_locked = 0x0002; @@ -6827,7 +6827,7 @@ Box2D.postDefs = []; this.K = new b2Mat22(); }; b2ContactConstraint.prototype.b2ContactConstraint = function () { - this.points = new Vector(b2Settings.b2_maxManifoldPoints); + this.points = new Box2DVector(b2Settings.b2_maxManifoldPoints); for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { this.points[i] = new b2ContactConstraintPoint(); } @@ -6856,9 +6856,9 @@ Box2D.postDefs = []; } } b2ContactFactory.prototype.InitializeRegisters = function () { - this.m_registers = new Vector(b2Shape.e_shapeTypeCount); + this.m_registers = new Box2DVector(b2Shape.e_shapeTypeCount); for (var i = 0; i < b2Shape.e_shapeTypeCount; i++) { - this.m_registers[i] = new Vector(b2Shape.e_shapeTypeCount); + this.m_registers[i] = new Box2DVector(b2Shape.e_shapeTypeCount); for (var j = 0; j < b2Shape.e_shapeTypeCount; j++) { this.m_registers[i][j] = new b2ContactRegister(); } @@ -6922,7 +6922,7 @@ Box2D.postDefs = []; }; b2ContactSolver.b2ContactSolver = function () { this.m_step = new b2TimeStep(); - this.m_constraints = new Vector(); + this.m_constraints = new Box2DVector(); }; b2ContactSolver.prototype.b2ContactSolver = function () {} b2ContactSolver.prototype.Initialize = function (step, contacts, contactCount, allocator) { @@ -7414,7 +7414,7 @@ Box2D.postDefs = []; b2PositionSolverManifold.prototype.b2PositionSolverManifold = function () { this.m_normal = new b2Vec2(); this.m_separations = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); + this.m_points = new Box2DVector(b2Settings.b2_maxManifoldPoints); for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { this.m_points[i] = new b2Vec2(); }