Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
9c8841e838
25 changed files with 1277 additions and 95 deletions
app
assets/javascripts/workers
locale
models
Article.coffeeCocoModel.coffeeFile.coffeeLevel.coffeeLevelComponent.coffeeLevelFeedback.coffeeLevelSession.coffeeLevelSystem.coffeePatch.coffeeThangType.coffeeUser.coffee
schemas/models
styles/play
views
editor/components
play/level
vendor/scripts
99
app/assets/javascripts/workers/aether_worker.js
Normal file
99
app/assets/javascripts/workers/aether_worker.js
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
var window = self;
|
||||||
|
var Global = self;
|
||||||
|
|
||||||
|
importScripts("/javascripts/tome_aether.js");
|
||||||
|
console.log("imported scripts!");
|
||||||
|
var aethers = {};
|
||||||
|
|
||||||
|
var createAether = function (spellKey, options)
|
||||||
|
{
|
||||||
|
aethers[spellKey] = new Aether(options);
|
||||||
|
return JSON.stringify({
|
||||||
|
"message": "Created aether for " + spellKey,
|
||||||
|
"function": "createAether"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var hasChangedSignificantly = function(spellKey, a,b,careAboutLineNumbers,careAboutLint) {
|
||||||
|
|
||||||
|
var hasChanged = aethers[spellKey].hasChangedSignificantly(a,b,careAboutLineNumbers,careAboutLint);
|
||||||
|
var functionName = "hasChangedSignificantly";
|
||||||
|
var returnObject = {
|
||||||
|
"function":functionName,
|
||||||
|
"hasChanged": hasChanged,
|
||||||
|
"spellKey": spellKey
|
||||||
|
};
|
||||||
|
return JSON.stringify(returnObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateLanguageAether = function(newLanguage)
|
||||||
|
{
|
||||||
|
for (var spellKey in aethers)
|
||||||
|
{
|
||||||
|
if (aethers.hasOwnProperty(spellKey))
|
||||||
|
{
|
||||||
|
aethers[spellKey].setLanguage(newLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var lint = function(spellKey, source)
|
||||||
|
{
|
||||||
|
var currentAether = aethers[spellKey];
|
||||||
|
var lintMessages = currentAether.lint(source);
|
||||||
|
var functionName = "lint";
|
||||||
|
var returnObject = {
|
||||||
|
"lintMessages": lintMessages,
|
||||||
|
"function": functionName
|
||||||
|
};
|
||||||
|
return JSON.stringify(returnObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
var transpile = function(spellKey, source)
|
||||||
|
{
|
||||||
|
var currentAether = aethers[spellKey];
|
||||||
|
currentAether.transpile(source);
|
||||||
|
var functionName = "transpile";
|
||||||
|
var returnObject = {
|
||||||
|
"problems": currentAether.problems,
|
||||||
|
"function": functionName,
|
||||||
|
"spellKey": spellKey
|
||||||
|
};
|
||||||
|
return JSON.stringify(returnObject);
|
||||||
|
};
|
||||||
|
self.addEventListener('message', function(e) {
|
||||||
|
var data = JSON.parse(e.data);
|
||||||
|
if (data.function == "createAether")
|
||||||
|
{
|
||||||
|
self.postMessage(createAether(data.spellKey, data.options));
|
||||||
|
}
|
||||||
|
else if (data.function == "updateLanguageAether")
|
||||||
|
{
|
||||||
|
updateLanguageAether(data.newLanguage)
|
||||||
|
}
|
||||||
|
else if (data.function == "hasChangedSignificantly")
|
||||||
|
{
|
||||||
|
self.postMessage(hasChangedSignificantly(
|
||||||
|
data.spellKey,
|
||||||
|
data.a,
|
||||||
|
data.b,
|
||||||
|
data.careAboutLineNumbers,
|
||||||
|
data.careAboutLint
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else if (data.function == "lint")
|
||||||
|
{
|
||||||
|
self.postMessage(lint(data.spellKey, data.source));
|
||||||
|
}
|
||||||
|
else if (data.function == "transpile")
|
||||||
|
{
|
||||||
|
self.postMessage(transpile(data.spellKey, data.source));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var message = "Didn't execute any function...";
|
||||||
|
var returnObject = {"message":message, "function":"none"};
|
||||||
|
self.postMessage(JSON.stringify(returnObject));
|
||||||
|
}
|
||||||
|
}, false);
|
|
@ -1,11 +1,11 @@
|
||||||
module.exports = nativeDescription: "Nederlands (België)", englishDescription: "Dutch (Belgium)", translation:
|
module.exports = nativeDescription: "Nederlands (België)", englishDescription: "Dutch (Belgium)", translation:
|
||||||
common:
|
common:
|
||||||
loading: "Aan het laden..."
|
loading: "Bezig met laden..."
|
||||||
saving: "Opslaan..."
|
saving: "Opslaan..."
|
||||||
sending: "Verzenden..."
|
sending: "Verzenden..."
|
||||||
send: "Verzend"
|
send: "Verzend"
|
||||||
cancel: "Annuleren"
|
cancel: "Annuleren"
|
||||||
save: "Opslagen"
|
save: "Opslaan"
|
||||||
publish: "Publiceren"
|
publish: "Publiceren"
|
||||||
create: "Creëer"
|
create: "Creëer"
|
||||||
delay_1_sec: "1 seconde"
|
delay_1_sec: "1 seconde"
|
||||||
|
@ -46,7 +46,7 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription:
|
||||||
employers: "Werkgevers"
|
employers: "Werkgevers"
|
||||||
|
|
||||||
versions:
|
versions:
|
||||||
save_version_title: "Nieuwe versie opslagen"
|
save_version_title: "Nieuwe versie opslaan"
|
||||||
new_major_version: "Nieuwe hoofd versie"
|
new_major_version: "Nieuwe hoofd versie"
|
||||||
cla_prefix: "Om bewerkingen op te slaan, moet je eerst akkoord gaan met onze"
|
cla_prefix: "Om bewerkingen op te slaan, moet je eerst akkoord gaan met onze"
|
||||||
cla_url: "CLA"
|
cla_url: "CLA"
|
||||||
|
@ -308,7 +308,7 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription:
|
||||||
|
|
||||||
editor:
|
editor:
|
||||||
main_title: "CodeCombat Editors"
|
main_title: "CodeCombat Editors"
|
||||||
main_description: "Maak je eigen levels, campagnes, eenheden en leermateriaal. Wij bieden alle programma's aan die u nodig heeft!"
|
main_description: "Maak je eigen levels, campagnes, eenheden en leermateriaal. Wij bieden alle programma's aan die je nodig hebt!"
|
||||||
article_title: "Artikel Editor"
|
article_title: "Artikel Editor"
|
||||||
article_description: "Schrijf artikels die spelers een overzicht geven over programmeer concepten die kunnen gebruikt worden over een variëteit van levels en campagnes."
|
article_description: "Schrijf artikels die spelers een overzicht geven over programmeer concepten die kunnen gebruikt worden over een variëteit van levels en campagnes."
|
||||||
thang_title: "Thang Editor"
|
thang_title: "Thang Editor"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription: "Dutch (Netherlands)", translation:
|
module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription: "Dutch (Netherlands)", translation:
|
||||||
common:
|
common:
|
||||||
loading: "Aan het laden..."
|
loading: "Bezig met laden..."
|
||||||
saving: "Opslaan..."
|
saving: "Opslaan..."
|
||||||
sending: "Verzenden..."
|
sending: "Verzenden..."
|
||||||
send: "Verzend"
|
send: "Verzend"
|
||||||
cancel: "Annuleren"
|
cancel: "Annuleren"
|
||||||
save: "Opslagen"
|
save: "Opslaan"
|
||||||
publish: "Publiceren"
|
publish: "Publiceren"
|
||||||
create: "Creëer"
|
create: "Creëer"
|
||||||
delay_1_sec: "1 seconde"
|
delay_1_sec: "1 seconde"
|
||||||
|
@ -46,7 +46,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
employers: "Werkgevers"
|
employers: "Werkgevers"
|
||||||
|
|
||||||
versions:
|
versions:
|
||||||
save_version_title: "Nieuwe versie opslagen"
|
save_version_title: "Nieuwe versie opslaan"
|
||||||
new_major_version: "Nieuwe hoofd versie"
|
new_major_version: "Nieuwe hoofd versie"
|
||||||
cla_prefix: "Om bewerkingen op te slaan, moet je eerst akkoord gaan met onze"
|
cla_prefix: "Om bewerkingen op te slaan, moet je eerst akkoord gaan met onze"
|
||||||
cla_url: "CLA"
|
cla_url: "CLA"
|
||||||
|
@ -308,7 +308,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
|
|
||||||
editor:
|
editor:
|
||||||
main_title: "CodeCombat Editors"
|
main_title: "CodeCombat Editors"
|
||||||
main_description: "Maak je eigen levels, campagnes, eenheden en leermateriaal. Wij bieden alle programma's aan die u nodig heeft!"
|
main_description: "Maak je eigen levels, campagnes, eenheden en leermateriaal. Wij bieden alle programma's aan die je nodig hebt!"
|
||||||
article_title: "Artikel Editor"
|
article_title: "Artikel Editor"
|
||||||
article_description: "Schrijf artikels die spelers een overzicht geven over programmeer concepten die kunnen gebruikt worden over een variëteit van levels en campagnes."
|
article_description: "Schrijf artikels die spelers een overzicht geven over programmeer concepten die kunnen gebruikt worden over een variëteit van levels en campagnes."
|
||||||
thang_title: "Thang Editor"
|
thang_title: "Thang Editor"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", translation:
|
module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", translation:
|
||||||
common:
|
common:
|
||||||
loading: "Aan het laden..."
|
loading: "Bezig met laden..."
|
||||||
saving: "Opslaan..."
|
saving: "Opslaan..."
|
||||||
sending: "Verzenden..."
|
sending: "Verzenden..."
|
||||||
send: "Verzend"
|
send: "Verzend"
|
||||||
cancel: "Annuleren"
|
cancel: "Annuleren"
|
||||||
save: "Opslagen"
|
save: "Opslaan"
|
||||||
publish: "Publiceren"
|
publish: "Publiceren"
|
||||||
create: "Creëer"
|
create: "Creëer"
|
||||||
delay_1_sec: "1 seconde"
|
delay_1_sec: "1 seconde"
|
||||||
|
@ -46,7 +46,7 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t
|
||||||
employers: "Werkgevers"
|
employers: "Werkgevers"
|
||||||
|
|
||||||
versions:
|
versions:
|
||||||
save_version_title: "Nieuwe versie opslagen"
|
save_version_title: "Nieuwe versie opslaan"
|
||||||
new_major_version: "Nieuwe hoofd versie"
|
new_major_version: "Nieuwe hoofd versie"
|
||||||
cla_prefix: "Om bewerkingen op te slaan, moet je eerst akkoord gaan met onze"
|
cla_prefix: "Om bewerkingen op te slaan, moet je eerst akkoord gaan met onze"
|
||||||
cla_url: "CLA"
|
cla_url: "CLA"
|
||||||
|
@ -308,7 +308,7 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t
|
||||||
|
|
||||||
editor:
|
editor:
|
||||||
main_title: "CodeCombat Editors"
|
main_title: "CodeCombat Editors"
|
||||||
main_description: "Maak je eigen levels, campagnes, eenheden en leermateriaal. Wij bieden alle programma's aan die u nodig heeft!"
|
main_description: "Maak je eigen levels, campagnes, eenheden en leermateriaal. Wij bieden alle programma's aan die je nodig hebt!"
|
||||||
article_title: "Artikel Editor"
|
article_title: "Artikel Editor"
|
||||||
article_description: "Schrijf artikels die spelers een overzicht geven over programmeer concepten die kunnen gebruikt worden over een variëteit van levels en campagnes."
|
article_description: "Schrijf artikels die spelers een overzicht geven over programmeer concepten die kunnen gebruikt worden over een variëteit van levels en campagnes."
|
||||||
thang_title: "Thang Editor"
|
thang_title: "Thang Editor"
|
||||||
|
|
|
@ -2,5 +2,6 @@ CocoModel = require('./CocoModel')
|
||||||
|
|
||||||
module.exports = class Article extends CocoModel
|
module.exports = class Article extends CocoModel
|
||||||
@className: "Article"
|
@className: "Article"
|
||||||
|
@schema: require 'schemas/models/article'
|
||||||
urlRoot: "/db/article"
|
urlRoot: "/db/article"
|
||||||
saveBackups: true
|
saveBackups: true
|
||||||
|
|
|
@ -11,7 +11,6 @@ class CocoModel extends Backbone.Model
|
||||||
|
|
||||||
initialize: ->
|
initialize: ->
|
||||||
super()
|
super()
|
||||||
@constructor.schema ?= require "schemas/models/#{@urlRoot[4..].replace '.', '_'}"
|
|
||||||
if not @constructor.className
|
if not @constructor.className
|
||||||
console.error("#{@} needs a className set.")
|
console.error("#{@} needs a className set.")
|
||||||
@markToRevert()
|
@markToRevert()
|
||||||
|
@ -224,7 +223,7 @@ class CocoModel extends Backbone.Model
|
||||||
watch: (doWatch=true) ->
|
watch: (doWatch=true) ->
|
||||||
$.ajax("#{@urlRoot}/#{@id}/watch", {type:'PUT', data:{on:doWatch}})
|
$.ajax("#{@urlRoot}/#{@id}/watch", {type:'PUT', data:{on:doWatch}})
|
||||||
@watching = -> doWatch
|
@watching = -> doWatch
|
||||||
|
|
||||||
watching: ->
|
watching: ->
|
||||||
return me.id in (@get('watchers') or [])
|
return me.id in (@get('watchers') or [])
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,5 @@ CocoModel = require('./CocoModel')
|
||||||
|
|
||||||
module.exports = class File extends CocoModel
|
module.exports = class File extends CocoModel
|
||||||
@className: "File"
|
@className: "File"
|
||||||
urlRoot: "/db/file"
|
@schema: require 'schemas/models/file'
|
||||||
|
urlRoot: "/db/file"
|
||||||
|
|
|
@ -5,6 +5,7 @@ ThangType = require './ThangType'
|
||||||
|
|
||||||
module.exports = class Level extends CocoModel
|
module.exports = class Level extends CocoModel
|
||||||
@className: "Level"
|
@className: "Level"
|
||||||
|
@schema: require 'schemas/models/level'
|
||||||
urlRoot: "/db/level"
|
urlRoot: "/db/level"
|
||||||
|
|
||||||
serialize: (supermodel) ->
|
serialize: (supermodel) ->
|
||||||
|
|
|
@ -2,6 +2,7 @@ CocoModel = require('./CocoModel')
|
||||||
|
|
||||||
module.exports = class LevelComponent extends CocoModel
|
module.exports = class LevelComponent extends CocoModel
|
||||||
@className: "LevelComponent"
|
@className: "LevelComponent"
|
||||||
|
@schema: require 'schemas/models/level_component'
|
||||||
urlRoot: "/db/level.component"
|
urlRoot: "/db/level.component"
|
||||||
|
|
||||||
set: (key, val, options) ->
|
set: (key, val, options) ->
|
||||||
|
|
|
@ -2,4 +2,5 @@ CocoModel = require('./CocoModel')
|
||||||
|
|
||||||
module.exports = class LevelFeedback extends CocoModel
|
module.exports = class LevelFeedback extends CocoModel
|
||||||
@className: "LevelFeedback"
|
@className: "LevelFeedback"
|
||||||
|
@schema: require 'schemas/models/level_feedback'
|
||||||
urlRoot: "/db/level.feedback"
|
urlRoot: "/db/level.feedback"
|
||||||
|
|
|
@ -2,6 +2,7 @@ CocoModel = require('./CocoModel')
|
||||||
|
|
||||||
module.exports = class LevelSession extends CocoModel
|
module.exports = class LevelSession extends CocoModel
|
||||||
@className: "LevelSession"
|
@className: "LevelSession"
|
||||||
|
@schema: require 'schemas/models/level_session'
|
||||||
urlRoot: "/db/level.session"
|
urlRoot: "/db/level.session"
|
||||||
|
|
||||||
initialize: ->
|
initialize: ->
|
||||||
|
@ -10,7 +11,7 @@ module.exports = class LevelSession extends CocoModel
|
||||||
state = @get('state') or {}
|
state = @get('state') or {}
|
||||||
state.scripts ?= {}
|
state.scripts ?= {}
|
||||||
@set('state', state)
|
@set('state', state)
|
||||||
|
|
||||||
updatePermissions: ->
|
updatePermissions: ->
|
||||||
permissions = @get 'permissions'
|
permissions = @get 'permissions'
|
||||||
permissions = (p for p in permissions when p.target isnt 'public')
|
permissions = (p for p in permissions when p.target isnt 'public')
|
||||||
|
|
|
@ -3,6 +3,7 @@ SystemNameLoader = require('lib/SystemNameLoader')
|
||||||
|
|
||||||
module.exports = class LevelSystem extends CocoModel
|
module.exports = class LevelSystem extends CocoModel
|
||||||
@className: "LevelSystem"
|
@className: "LevelSystem"
|
||||||
|
@schema: require 'schemas/models/level_system'
|
||||||
urlRoot: "/db/level.system"
|
urlRoot: "/db/level.system"
|
||||||
|
|
||||||
set: (key, val, options) ->
|
set: (key, val, options) ->
|
||||||
|
|
|
@ -2,10 +2,11 @@ CocoModel = require('./CocoModel')
|
||||||
|
|
||||||
module.exports = class PatchModel extends CocoModel
|
module.exports = class PatchModel extends CocoModel
|
||||||
@className: "Patch"
|
@className: "Patch"
|
||||||
urlRoot: "/db/patch"
|
@schema: require 'schemas/models/patch'
|
||||||
|
urlRoot: "/db/patch"
|
||||||
|
|
||||||
setStatus: (status) ->
|
setStatus: (status) ->
|
||||||
PatchModel.setStatus @id, status
|
PatchModel.setStatus @id, status
|
||||||
|
|
||||||
@setStatus: (id, status) ->
|
@setStatus: (id, status) ->
|
||||||
$.ajax("/db/patch/#{id}/status", {type:"PUT", data: {status:status}})
|
$.ajax("/db/patch/#{id}/status", {type:"PUT", data: {status:status}})
|
||||||
|
|
|
@ -5,6 +5,7 @@ buildQueue = []
|
||||||
|
|
||||||
module.exports = class ThangType extends CocoModel
|
module.exports = class ThangType extends CocoModel
|
||||||
@className: "ThangType"
|
@className: "ThangType"
|
||||||
|
@schema: require 'schemas/models/thang_type'
|
||||||
urlRoot: "/db/thang.type"
|
urlRoot: "/db/thang.type"
|
||||||
building: {}
|
building: {}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ CocoModel = require('./CocoModel')
|
||||||
|
|
||||||
module.exports = class User extends CocoModel
|
module.exports = class User extends CocoModel
|
||||||
@className: "User"
|
@className: "User"
|
||||||
|
@schema: require 'schemas/models/user'
|
||||||
urlRoot: "/db/user"
|
urlRoot: "/db/user"
|
||||||
|
|
||||||
initialize: ->
|
initialize: ->
|
||||||
|
@ -72,4 +73,4 @@ module.exports = class User extends CocoModel
|
||||||
newSubs[newSubName] = { enabled: oldSubName in oldSubs } for oldSubName, newSubName of @emailMap
|
newSubs[newSubName] = { enabled: oldSubName in oldSubs } for oldSubName, newSubName of @emailMap
|
||||||
@set('emails', newSubs)
|
@set('emails', newSubs)
|
||||||
|
|
||||||
isEmailSubscriptionEnabled: (name) -> (@get('emails') or {})[name]?.enabled
|
isEmailSubscriptionEnabled: (name) -> (@get('emails') or {})[name]?.enabled
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
c = require './../schemas'
|
c = require './../schemas'
|
||||||
ThangComponentSchema = require './../models/thang_component'
|
ThangComponentSchema = require './thang_component'
|
||||||
|
|
||||||
SpecificArticleSchema = c.object()
|
SpecificArticleSchema = c.object()
|
||||||
c.extendNamedProperties SpecificArticleSchema # name first
|
c.extendNamedProperties SpecificArticleSchema # name first
|
||||||
|
|
|
@ -18,7 +18,7 @@ body.is-playing
|
||||||
position: relative
|
position: relative
|
||||||
|
|
||||||
canvas#surface
|
canvas#surface
|
||||||
background-color: #ddd
|
background-color: #333
|
||||||
width: 100%
|
width: 100%
|
||||||
display: block
|
display: block
|
||||||
z-index: 1
|
z-index: 1
|
||||||
|
|
|
@ -157,17 +157,18 @@ module.exports = class ThangComponentEditView extends CocoView
|
||||||
@reportChanges()
|
@reportChanges()
|
||||||
|
|
||||||
onAddComponentEnterPressed: (node) =>
|
onAddComponentEnterPressed: (node) =>
|
||||||
extantSystems =
|
if extantSystems
|
||||||
(@supermodel.getModelByOriginalAndMajorVersion LevelSystem, sn.original, sn.majorVersion).attributes.name.toLowerCase() for idx, sn of @level.get('systems')
|
extantSystems =
|
||||||
requireSystem = node.data.system.toLowerCase()
|
(@supermodel.getModelByOriginalAndMajorVersion LevelSystem, sn.original, sn.majorVersion).attributes.name.toLowerCase() for idx, sn of @level.get('systems')
|
||||||
|
requireSystem = node.data.system.toLowerCase()
|
||||||
|
|
||||||
if requireSystem not in extantSystems
|
if requireSystem not in extantSystems
|
||||||
warn_element = 'Component <b>' + node.data.name + '</b> requires system <b>' + requireSystem + '</b> which is currently not specified in this level.'
|
warn_element = 'Component <b>' + node.data.name + '</b> requires system <b>' + requireSystem + '</b> which is currently not specified in this level.'
|
||||||
noty({
|
noty({
|
||||||
text: warn_element,
|
text: warn_element,
|
||||||
layout: 'bottomLeft',
|
layout: 'bottomLeft',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
})
|
})
|
||||||
|
|
||||||
currentSelection = @addComponentsTreema?.getLastSelectedTreema()?.data._id
|
currentSelection = @addComponentsTreema?.getLastSelectedTreema()?.data._id
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ module.exports = class PlaybackView extends View
|
||||||
@$el.find('.toggle-fullscreen').hide()
|
@$el.find('.toggle-fullscreen').hide()
|
||||||
|
|
||||||
updatePopupContent: ->
|
updatePopupContent: ->
|
||||||
@timePopup.updateContent "<h2>#{@timeToString @newTime}</h2>#{@formatTime(@current, @currentTime)}<br/>#{@formatTime(@total, @totalTime)}"
|
@timePopup?.updateContent "<h2>#{@timeToString @newTime}</h2>#{@formatTime(@current, @currentTime)}<br/>#{@formatTime(@total, @totalTime)}"
|
||||||
|
|
||||||
# These functions could go to some helper class
|
# These functions could go to some helper class
|
||||||
|
|
||||||
|
|
|
@ -74,16 +74,20 @@ module.exports = class CastButtonView extends View
|
||||||
|
|
||||||
updateCastButton: ->
|
updateCastButton: ->
|
||||||
return if _.some @spells, (spell) => not spell.loaded
|
return if _.some @spells, (spell) => not spell.loaded
|
||||||
castable = _.some @spells, (spell) => spell.hasChangedSignificantly spell.getSource()
|
|
||||||
@castButtonGroup.toggleClass('castable', castable).toggleClass('casting', @casting)
|
async.some _.values(@spells), (spell, callback) =>
|
||||||
if @casting
|
spell.hasChangedSignificantly spell.getSource(), null, callback
|
||||||
s = $.i18n.t("play_level.tome_cast_button_casting", defaultValue: "Casting")
|
, (castable) =>
|
||||||
else if castable
|
|
||||||
s = $.i18n.t("play_level.tome_cast_button_castable", defaultValue: "Cast Spell") + " " + @castShortcut
|
@castButtonGroup.toggleClass('castable', castable).toggleClass('casting', @casting)
|
||||||
else
|
if @casting
|
||||||
s = $.i18n.t("play_level.tome_cast_button_cast", defaultValue: "Spell Cast")
|
s = $.i18n.t("play_level.tome_cast_button_casting", defaultValue: "Casting")
|
||||||
@castButton.text s
|
else if castable
|
||||||
@castButton.prop 'disabled', not castable
|
s = $.i18n.t("play_level.tome_cast_button_castable", defaultValue: "Cast Spell") + " " + @castShortcut
|
||||||
|
else
|
||||||
|
s = $.i18n.t("play_level.tome_cast_button_cast", defaultValue: "Spell Cast")
|
||||||
|
@castButton.text s
|
||||||
|
@castButton.prop 'disabled', not castable
|
||||||
|
|
||||||
setAutocastDelay: (delay) ->
|
setAutocastDelay: (delay) ->
|
||||||
#console.log "Set autocast delay to", delay
|
#console.log "Set autocast delay to", delay
|
||||||
|
|
|
@ -23,7 +23,7 @@ module.exports = class Spell
|
||||||
@parameters = p.parameters
|
@parameters = p.parameters
|
||||||
@permissions = read: p.permissions?.read ? [], readwrite: p.permissions?.readwrite ? [] # teams
|
@permissions = read: p.permissions?.read ? [], readwrite: p.permissions?.readwrite ? [] # teams
|
||||||
@thangs = {}
|
@thangs = {}
|
||||||
@view = new SpellView {spell: @, session: @session}
|
@view = new SpellView {spell: @, session: @session, worker: @worker}
|
||||||
@view.render() # Get it ready and code loaded in advance
|
@view.render() # Get it ready and code loaded in advance
|
||||||
@tabView = new SpellListTabEntryView spell: @, supermodel: @supermodel
|
@tabView = new SpellListTabEntryView spell: @, supermodel: @supermodel
|
||||||
@tabView.render()
|
@tabView.render()
|
||||||
|
@ -75,15 +75,27 @@ module.exports = class Spell
|
||||||
hasChanged: (newSource=null, currentSource=null) ->
|
hasChanged: (newSource=null, currentSource=null) ->
|
||||||
(newSource ? @originalSource) isnt (currentSource ? @source)
|
(newSource ? @originalSource) isnt (currentSource ? @source)
|
||||||
|
|
||||||
hasChangedSignificantly: (newSource=null, currentSource=null) ->
|
hasChangedSignificantly: (newSource=null, currentSource=null, cb) ->
|
||||||
for thangID, spellThang of @thangs
|
for thangID, spellThang of @thangs
|
||||||
aether = spellThang.aether
|
aether = spellThang.aether
|
||||||
break
|
break
|
||||||
unless aether
|
unless aether
|
||||||
console.error @toString(), "couldn't find a spellThang with aether of", @thangs
|
console.error @toString(), "couldn't find a spellThang with aether of", @thangs
|
||||||
return false
|
cb false
|
||||||
aether.hasChangedSignificantly (newSource ? @originalSource), (currentSource ? @source), true, true
|
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)
|
||||||
|
|
||||||
createAether: (thang) ->
|
createAether: (thang) ->
|
||||||
aceConfig = me.get('aceConfig') ? {}
|
aceConfig = me.get('aceConfig') ? {}
|
||||||
aetherOptions =
|
aetherOptions =
|
||||||
|
@ -111,13 +123,23 @@ module.exports = class Spell
|
||||||
aetherOptions.includeFlow = false
|
aetherOptions.includeFlow = false
|
||||||
#console.log "creating aether with options", aetherOptions
|
#console.log "creating aether with options", aetherOptions
|
||||||
aether = new Aether aetherOptions
|
aether = new Aether aetherOptions
|
||||||
|
workerMessage =
|
||||||
|
function: "createAether"
|
||||||
|
spellKey: @spellKey
|
||||||
|
options: aetherOptions
|
||||||
|
@worker.postMessage JSON.stringify workerMessage
|
||||||
aether
|
aether
|
||||||
|
|
||||||
updateLanguageAether: ->
|
updateLanguageAether: ->
|
||||||
aceConfig = me.get('aceConfig') ? {}
|
aceConfig = me.get('aceConfig') ? {}
|
||||||
|
newLanguage = (aceConfig.language ? 'javascript')
|
||||||
for thangId, spellThang of @thangs
|
for thangId, spellThang of @thangs
|
||||||
spellThang.aether?.setLanguage (aceConfig.language ? 'javascript')
|
spellThang.aether?.setLanguage newLanguage
|
||||||
spellThang.castAether = null
|
spellThang.castAether = null
|
||||||
|
workerMessage =
|
||||||
|
function: "updateLanguageAether"
|
||||||
|
newLanguage: newLanguage
|
||||||
|
@worker.postMessage JSON.stringify workerMessage
|
||||||
@transpile()
|
@transpile()
|
||||||
|
|
||||||
toString: ->
|
toString: ->
|
||||||
|
|
|
@ -47,6 +47,7 @@ module.exports = class SpellView extends View
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
super options
|
super options
|
||||||
|
@worker = options.worker
|
||||||
@session = options.session
|
@session = options.session
|
||||||
@listenTo(@session, 'change:multiplayer', @onMultiplayerChanged)
|
@listenTo(@session, 'change:multiplayer', @onMultiplayerChanged)
|
||||||
@spell = options.spell
|
@spell = options.spell
|
||||||
|
@ -278,9 +279,10 @@ module.exports = class SpellView extends View
|
||||||
]
|
]
|
||||||
@onCodeChangeMetaHandler = =>
|
@onCodeChangeMetaHandler = =>
|
||||||
return if @eventsSuppressed
|
return if @eventsSuppressed
|
||||||
if not @spellThang or @spell.hasChangedSignificantly @getSource(), @spellThang.aether.raw
|
@spell.hasChangedSignificantly @getSource(), @spellThang.aether.raw, (hasChanged) =>
|
||||||
callback() for callback in onSignificantChange # Do these first
|
if not @spellThang or hasChanged
|
||||||
callback() for callback in onAnyChange # Then these
|
callback() for callback in onSignificantChange # Do these first
|
||||||
|
callback() for callback in onAnyChange # Then these
|
||||||
@aceDoc.on 'change', @onCodeChangeMetaHandler
|
@aceDoc.on 'change', @onCodeChangeMetaHandler
|
||||||
|
|
||||||
setRecompileNeeded: (needed=true) =>
|
setRecompileNeeded: (needed=true) =>
|
||||||
|
@ -317,20 +319,37 @@ module.exports = class SpellView extends View
|
||||||
# to a new spellThang, we may want to refresh our Aether display.
|
# to a new spellThang, we may want to refresh our Aether display.
|
||||||
return unless aether = @spellThang?.aether
|
return unless aether = @spellThang?.aether
|
||||||
source = @getSource()
|
source = @getSource()
|
||||||
codeHasChangedSignificantly = force or @spell.hasChangedSignificantly source, aether.raw
|
@spell.hasChangedSignificantly source, aether.raw, (hasChanged) =>
|
||||||
needsUpdate = codeHasChangedSignificantly or @spellThang isnt @lastUpdatedAetherSpellThang
|
codeHasChangedSignificantly = force or hasChanged
|
||||||
return if not needsUpdate and aether is @displayedAether
|
needsUpdate = codeHasChangedSignificantly or @spellThang isnt @lastUpdatedAetherSpellThang
|
||||||
castAether = @spellThang.castAether
|
return if not needsUpdate and aether is @displayedAether
|
||||||
codeIsAsCast = castAether and not @spell.hasChangedSignificantly source, castAether.raw
|
castAether = @spellThang.castAether
|
||||||
aether = castAether if codeIsAsCast
|
codeIsAsCast = castAether and not hasChanged
|
||||||
return if not needsUpdate and aether is @displayedAether
|
aether = castAether if codeIsAsCast
|
||||||
|
return if not needsUpdate and aether is @displayedAether
|
||||||
# Now that that's figured out, perform the update.
|
|
||||||
@clearAetherDisplay()
|
# Now that that's figured out, perform the update.
|
||||||
aether.transpile source if codeHasChangedSignificantly and not codeIsAsCast
|
# The web worker Aether won't track state, so don't have to worry about updating it
|
||||||
@displayAether aether
|
@clearAetherDisplay()
|
||||||
@lastUpdatedAetherSpellThang = @spellThang
|
workerMessage =
|
||||||
@guessWhetherFinished aether if fromCodeChange
|
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
|
||||||
|
@displayAether aether
|
||||||
|
@lastUpdatedAetherSpellThang = @spellThang
|
||||||
|
@guessWhetherFinished aether if fromCodeChange
|
||||||
|
@worker.postMessage JSON.stringify(workerMessage)
|
||||||
|
#aether.transpile source if codeHasChangedSignificantly and not codeIsAsCast
|
||||||
|
#@displayAether aether
|
||||||
|
#@lastUpdatedAetherSpellThang = @spellThang
|
||||||
|
#@guessWhetherFinished aether if fromCodeChange
|
||||||
|
|
||||||
clearAetherDisplay: ->
|
clearAetherDisplay: ->
|
||||||
problem.destroy() for problem in @problems
|
problem.destroy() for problem in @problems
|
||||||
|
@ -400,10 +419,11 @@ module.exports = class SpellView extends View
|
||||||
return @onInfiniteLoop e if e.problem.id is "runtime_InfiniteLoop"
|
return @onInfiniteLoop e if e.problem.id is "runtime_InfiniteLoop"
|
||||||
return unless e.problem.userInfo.methodName is @spell.name
|
return unless e.problem.userInfo.methodName is @spell.name
|
||||||
return unless spellThang = _.find @spell.thangs, (spellThang, thangID) -> thangID is e.problem.userInfo.thangID
|
return unless spellThang = _.find @spell.thangs, (spellThang, thangID) -> thangID is e.problem.userInfo.thangID
|
||||||
return if @spell.hasChangedSignificantly @getSource() # don't show this error if we've since edited the code
|
@spell.hasChangedSignificantly @getSource(), null, (hasChanged) =>
|
||||||
spellThang.aether.addProblem e.problem
|
return if hasChanged
|
||||||
@lastUpdatedAetherSpellThang = null # force a refresh without a re-transpile
|
spellThang.aether.addProblem e.problem
|
||||||
@updateAether false, false
|
@lastUpdatedAetherSpellThang = null # force a refresh without a re-transpile
|
||||||
|
@updateAether false, false
|
||||||
|
|
||||||
onInfiniteLoop: (e) ->
|
onInfiniteLoop: (e) ->
|
||||||
return unless @spellThang
|
return unless @spellThang
|
||||||
|
@ -578,7 +598,9 @@ module.exports = class SpellView extends View
|
||||||
@aceSession.setMode @editModes[aceConfig.language ? 'javascript']
|
@aceSession.setMode @editModes[aceConfig.language ? 'javascript']
|
||||||
|
|
||||||
dismiss: ->
|
dismiss: ->
|
||||||
@recompile() if @spell.hasChangedSignificantly @getSource()
|
@spell.hasChangedSignificantly @getSource(), null, (hasChanged) =>
|
||||||
|
@recompile() if hasChanged
|
||||||
|
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
$(@ace?.container).find('.ace_gutter').off 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
|
$(@ace?.container).find('.ace_gutter').off 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
|
||||||
|
|
|
@ -71,7 +71,7 @@ module.exports = class TomeView extends View
|
||||||
@cast()
|
@cast()
|
||||||
console.warn "Warning: There are no Programmable Thangs in this level, which makes it unplayable."
|
console.warn "Warning: There are no Programmable Thangs in this level, which makes it unplayable."
|
||||||
delete @options.thangs
|
delete @options.thangs
|
||||||
|
|
||||||
onNewWorld: (e) ->
|
onNewWorld: (e) ->
|
||||||
thangs = _.filter e.world.thangs, 'isSelectable'
|
thangs = _.filter e.world.thangs, 'isSelectable'
|
||||||
programmableThangs = _.filter thangs, 'isProgrammable'
|
programmableThangs = _.filter thangs, 'isProgrammable'
|
||||||
|
@ -88,26 +88,7 @@ module.exports = class TomeView extends View
|
||||||
@cast()
|
@cast()
|
||||||
|
|
||||||
createWorker: ->
|
createWorker: ->
|
||||||
return
|
return new Worker("/javascripts/workers/aether_worker.js")
|
||||||
# In progress
|
|
||||||
worker = cw
|
|
||||||
initialize: (scope) ->
|
|
||||||
self.window = self
|
|
||||||
self.global = self
|
|
||||||
console.log 'Tome worker initialized.'
|
|
||||||
doIt: (data, callback, scope) ->
|
|
||||||
console.log 'doing', what
|
|
||||||
try
|
|
||||||
importScripts '/javascripts/tome_aether.js'
|
|
||||||
catch err
|
|
||||||
console.log err.toString()
|
|
||||||
a = new Aether()
|
|
||||||
callback 'good'
|
|
||||||
undefined
|
|
||||||
onAccepted = (s) -> console.log 'accepted', s
|
|
||||||
onRejected = (s) -> console.log 'rejected', s
|
|
||||||
worker.doIt('hmm').then onAccepted, onRejected
|
|
||||||
worker
|
|
||||||
|
|
||||||
generateTeamSpellMap: (spellObject) ->
|
generateTeamSpellMap: (spellObject) ->
|
||||||
teamSpellMap = {}
|
teamSpellMap = {}
|
||||||
|
@ -222,7 +203,7 @@ module.exports = class TomeView extends View
|
||||||
@spellPaletteView.toggleControls {}, spell.view.controlsEnabled # TODO: know when palette should have been disabled but didn't exist
|
@spellPaletteView.toggleControls {}, spell.view.controlsEnabled # TODO: know when palette should have been disabled but didn't exist
|
||||||
|
|
||||||
reloadAllCode: ->
|
reloadAllCode: ->
|
||||||
spell.view.reloadCode false for spellKey, spell of @spells when spell.team is me.team
|
spell.view.reloadCode false for spellKey, spell of @spells when spell.team is me.team or (spell.team in ["common", "neutral", null])
|
||||||
Backbone.Mediator.publish 'tome:cast-spells', spells: @spells
|
Backbone.Mediator.publish 'tome:cast-spells', spells: @spells
|
||||||
|
|
||||||
updateLanguageForAllSpells: ->
|
updateLanguageForAllSpells: ->
|
||||||
|
@ -230,5 +211,5 @@ module.exports = class TomeView extends View
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
spell.destroy() for spellKey, spell of @spells
|
spell.destroy() for spellKey, spell of @spells
|
||||||
@worker?._close()
|
@worker?.terminate()
|
||||||
super()
|
super()
|
||||||
|
|
|
@ -59,6 +59,7 @@ exports.config =
|
||||||
# Aether before box2d for some strange Object.defineProperty thing
|
# Aether before box2d for some strange Object.defineProperty thing
|
||||||
'bower_components/aether/build/aether.js'
|
'bower_components/aether/build/aether.js'
|
||||||
'bower_components/d3/d3.min.js'
|
'bower_components/d3/d3.min.js'
|
||||||
|
'vendor/scripts/async.js'
|
||||||
]
|
]
|
||||||
stylesheets:
|
stylesheets:
|
||||||
defaultExtension: 'sass'
|
defaultExtension: 'sass'
|
||||||
|
|
1043
vendor/scripts/async.js
vendored
Normal file
1043
vendor/scripts/async.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
Reference in a new issue