Switching from the slow _.cloneDeep to the fast $.extend

This commit is contained in:
Scott Erickson 2014-03-18 13:08:26 -07:00
parent 87b225b061
commit 37a9b7f319
18 changed files with 102 additions and 20 deletions

View file

@ -0,0 +1,82 @@
#CocoClass = require 'lib/CocoClass'
#
#module.exports = class AsyncCloner extends CocoClass
# constructor: (@source, @depth=2) ->
# # passing in a depth of 0 will just _.clone the first layer, and will result in 1 indexList
# super()
# @indexLists = []
# @initClone()
#
# initClone: () ->
# @target = AsyncCloner.cloneToDepth(@source, @depth)
# @indexLists = [_.keys(@target)] if _.isObject @target
#
# @cloneToDepth: (value, depth) ->
# value = _.clone(value)
# return value unless depth and _.isObject value
# value[key] = @cloneToDepth(value[key], depth-1) for key in _.keys value
# value
#
# clone: ->
# while @indexLists.length
# #console.log 'Clone loop:', JSON.stringify @indexLists
# @moveIndexForward() # fills or empties the index so @indexLists.length === @depth + 1
# break if @done()
# @cloneOne()
# @moveIndexForwardOne()
# break if @done() or @timeToSleep()
#
# moveIndexForward: ->
# while @indexLists.length
# nextValue = @getNextValue()
# if _.isObject(nextValue)
# if @indexLists.length <= @depth
# # push a new list if it's a collection
# @indexLists.push _.keys(nextValue)
# continue
# else
# break # we done, the next value needs to be deep cloned
# #console.log 'Skipping:', @getNextPath()
# @moveIndexForwardOne() # move past this value otherwise
# #console.log '\tMoved index forward', JSON.stringify @indexLists
#
# getNextValue: ->
# value = @target
# value = value[indexList[0]] for indexList in @indexLists
# value
#
# getNextParent: ->
# parent = @target
# parent = parent[indexList[0]] for indexList in @indexLists[...-1]
# parent
#
# getNextPath: ->
# (indexList[0] for indexList in @indexLists when indexList.length).join '.'
#
# moveIndexForwardOne: ->
# @indexLists[@indexLists.length-1].shift() # move the index forward one
# # if we reached the end of an index list, trim down through all finished lists
# while @indexLists.length and not @indexLists[@indexLists.length-1].length
# @indexLists.pop()
# @indexLists[@indexLists.length-1].shift() if @indexLists.length
#
# cloneOne: ->
# if @indexLists.length isnt @depth + 1
# throw new Error('Cloner is in an invalid state!')
# parent = @getNextParent()
# key = @indexLists[@indexLists.length-1][0]
# parent[key] = _.cloneDeep parent[key]
# #console.log 'Deep Cloned:', @getNextPath()
#
# done: -> not @indexLists.length
#
# timeToSleep: -> false
###
Overall, the loop is:
Fill indexes if we need to to the depth we've cloned
Clone that one, popping it off the list.
If the last list is now empty, pop that list and every subsequent list if needed.
Check for doneness, or timeout.
###

View file

@ -178,7 +178,7 @@ module.exports = class LevelBus extends Bus
return unless @onPoint()
state = @session.get('state')
state.thangs ?= {}
methods = _.cloneDeep(e.methods)
methods = $.extend(true, {}, (e.methods))
delete method.metrics.statements for methodName, method of methods
state.thangs[e.thangID] = { methods: methods }
@session.set('state', state)

View file

@ -64,7 +64,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
@triggered = []
@ended = []
@noteGroupQueue = []
@scripts = _.cloneDeep(@originalScripts)
@scripts = $.extend(true, {}, @originalScripts)
addScriptSubscriptions: ->
idNum = 0

View file

@ -1,7 +1,7 @@
module.exports = class SpriteParser
constructor: (@thangTypeModel) ->
# Create a new ThangType, or work with one we've been building
@thangType = _.cloneDeep(@thangTypeModel.attributes.raw)
@thangType = $.extend(true, {}, @thangTypeModel.attributes.raw)
@thangType ?= {}
@thangType.shapes ?= {}
@thangType.containers ?= {}

View file

@ -56,7 +56,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
constructor: (@thangType, options) ->
super()
@options = _.extend(_.cloneDeep(@options), options)
@options = _.extend($.extend(true, {}, @options), options)
@setThang @options.thang
console.error @toString(), "has no ThangType!" unless @thangType
@actionQueue = []

View file

@ -30,7 +30,7 @@ module.exports = class WizardSprite extends IndieSprite
constructor: (thangType, options) ->
if options?.isSelf
options.colorConfig = _.cloneDeep(me.get('wizard')?.colorConfig) or {}
options.colorConfig = $.extend(true, {}, me.get('wizard')?.colorConfig) or {}
super thangType, options
@isSelf = options.isSelf
@targetPos = @thang.pos
@ -67,7 +67,7 @@ module.exports = class WizardSprite extends IndieSprite
@setNameLabel me.displayName() if @displayObject.visible # not if we hid the wiz
newColorConfig = me.get('wizard')?.colorConfig or {}
shouldUpdate = not _.isEqual(newColorConfig, @options.colorConfig)
@options.colorConfig = _.cloneDeep(newColorConfig)
@options.colorConfig = $.extend(true, {}, newColorConfig)
if shouldUpdate
@setupSprite()
@playAction(@currentAction)

View file

@ -90,7 +90,7 @@ module.exports = class GoalManager extends CocoClass
# IMPLEMENTATION DETAILS
addGoal: (goal) ->
goal = _.cloneDeep(goal)
goal = $.extend(true, {}, goal)
goal.id = @nextGoalID++ if not goal.id
return if @goalStates[goal.id]?
@goals.push(goal)

View file

@ -30,7 +30,7 @@ module.exports = class ThangType extends CocoModel
return @actions or @buildActions()
buildActions: ->
@actions = _.cloneDeep(@get('actions') or {})
@actions = $.extend(true, {}, @get('actions') or {})
for name, action of @actions
action.name = name
for relatedName, relatedAction of action.relatedActions ? {}

View file

@ -69,7 +69,7 @@ module.exports = class WizardSettingsView extends CocoView
colorGroup.find('.minicolors-swatch').toggle Boolean(enabled)
updateColorSettings: (colorGroup) =>
wizardSettings = _.cloneDeep(me.get('wizard')) or {}
wizardSettings = $.extend(true, {}, me.get('wizard')) or {}
wizardSettings.colorConfig ?= {}
colorName = colorGroup.data('name')
wizardSettings.colorConfig[colorName] ?= {}

View file

@ -68,7 +68,7 @@ module.exports = class ThangComponentEditView extends CocoView
treemaOptions =
supermodel: @supermodel
schema: { type: 'array', items: LevelComponent.schema.attributes }
data: (_.cloneDeep(c) for c in components)
data: ($.extend(true, {}, c) for c in components)
callbacks: {select: @onSelectAddableComponent, enter: @onAddComponentEnterPressed }
readOnly: true
noSortable: true
@ -155,7 +155,7 @@ module.exports = class ThangComponentEditView extends CocoView
reportChanges: ->
@callback?(_.cloneDeep(@extantComponentsTreema.data))
@callback?($.extend(true, {}, @extantComponentsTreema.data))
class ThangComponentsArrayNode extends TreemaArrayNode
valueClass: 'treema-thang-components-array'

View file

@ -25,7 +25,7 @@ module.exports = class LevelForkView extends View
forkLevel: ->
@showLoading()
forms.clearFormAlerts(@$el)
newLevel = new Level(_.cloneDeep(@level.attributes))
newLevel = new Level($.extend(true, {}, @level.attributes))
newLevel.unset '_id'
newLevel.unset 'version'
newLevel.unset 'creator'

View file

@ -21,7 +21,7 @@ module.exports = class ScriptsTabView extends View
onLevelLoaded: (e) ->
@level = e.level
@dimensions = @level.dimensions()
scripts = _.cloneDeep(@level.get('scripts') ? [])
scripts = $.extend(true, {}, @level.get('scripts') ? [])
scripts = _.cloneDeep defaultScripts unless scripts.length
treemaOptions =
schema: Level.schema.get('properties').scripts

View file

@ -61,7 +61,7 @@ module.exports = class LevelSystemAddView extends View
levelSystem =
original: s.get('original') ? id
majorVersion: s.get('version').major ? 0
config: _.cloneDeep(s.get('configSchema').default ? {})
config: $.extend(true, {}, s.get('configSchema').default ? {})
@extantSystems.push levelSystem
Backbone.Mediator.publish 'level-system-added', system: levelSystem
@renderAvailableSystems()

View file

@ -54,7 +54,7 @@ module.exports = class SystemsTabView extends View
@buildSystemsTreema()
buildSystemsTreema: ->
systems = _.cloneDeep(@level.get('systems') ? [])
systems = $.extend(true, {}, @level.get('systems') ? [])
unless systems.length
systems = @buildDefaultSystems()
insertedDefaults = true

View file

@ -40,7 +40,7 @@ module.exports = class ThangTypeEditView extends View
constructor: (options, @thangTypeID) ->
super options
@mockThang = _.cloneDeep(@mockThang)
@mockThang = $.extend(true, {}, @mockThang)
@thangType = new ThangType(_id: @thangTypeID)
@thangType.saveBackups = true
@thangType.fetch()
@ -320,7 +320,7 @@ module.exports = class ThangTypeEditView extends View
@treema.set('/', @getThangData())
getThangData: ->
data = _.cloneDeep(@thangType.attributes)
data = $.extend(true, {}, @thangType.attributes)
data = _.pick data, (value, key) => not (key in ['components'])
buildTreema: ->

View file

@ -25,7 +25,7 @@ module.exports = class DocsModal extends View
@docs = specific.concat(general)
marked.setOptions {gfm: true, sanitize: false, smartLists: true, breaks: false}
@docs = _.cloneDeep(@docs)
@docs = $.extend(true, {}, @docs)
doc.html = marked(utils.i18n doc, 'body') for doc in @docs
doc.name = (utils.i18n doc, 'name') for doc in @docs
doc.slug = _.string.slugify(doc.name) for doc in @docs

View file

@ -167,7 +167,7 @@ module.exports = class PlayLevelView extends View
@insertSubviews ladderGame: (@level.get('type') is "ladder")
@initVolume()
@session.on 'change:multiplayer', @onMultiplayerChanged, @
@originalSessionState = _.cloneDeep(@session.get('state'))
@originalSessionState = $.extend(true, {}, @session.get('state'))
@register()
@controlBar.setBus(@bus)
@surface.showLevel()

View file

@ -160,7 +160,7 @@ module.exports = class SpectateLevelView extends View
@insertSubviews ladderGame: @otherSession?
@initVolume()
@originalSessionState = _.cloneDeep(@session.get('state'))
@originalSessionState = $.extend(true, {}, @session.get('state'))
@register()
@controlBar.setBus(@bus)
@surface.showLevel()