merge batch.queue and batch.updateAndQueue to one function set

This commit is contained in:
Tyler Renelle 2013-02-02 13:40:26 -05:00
parent 4e896240ea
commit ba10f7943d
3 changed files with 74 additions and 60 deletions

View file

@ -46,9 +46,14 @@ get '/', (page, model, next) ->
#user = result.at(0) #user = result.at(0)
model.ref '_user', user model.ref '_user', user
batch = new schema.BatchUpdate(model) batch = new schema.BatchUpdate(model)
batch.startTransaction()
userObj = batch.userObj userObj = batch.userObj
return page.redirect '/500.html' unless userObj? #this should never happen, but it is. Looking into it unless userObj?
#this should never happen, but it is. Looking into it
console.error 'User object was null!'
return page.redirect '/500.html'
# Setup Item Store # Setup Item Store
items = userObj.items items = userObj.items
@ -254,14 +259,14 @@ ready (model) ->
revive = (batch) -> revive = (batch) ->
# Reset stats # Reset stats
batch.queue 'stats.hp', 50 batch.set 'stats.hp', 50
batch.queue 'stats.lvl', 1 batch.set 'stats.lvl', 1
batch.queue 'stats.money', 0 batch.set 'stats.money', 0
batch.queue 'stats.exp', 0 batch.set 'stats.exp', 0
# Reset items # Reset items
batch.queue 'items.armor', 0 batch.set 'items.armor', 0
batch.queue 'items.weapon', 0 batch.set 'items.weapon', 0
# Reset item store # Reset item store
model.set '_view.items.armor', content.items.armor[1] model.set '_view.items.armor', content.items.armor[1]
@ -269,16 +274,18 @@ ready (model) ->
exports.revive = (e, el) -> exports.revive = (e, el) ->
batch = new schema.BatchUpdate(model) batch = new schema.BatchUpdate(model)
batch.startTransaction()
revive(batch) revive(batch)
batch.commit() batch.commit()
resetDom(model) resetDom(model)
exports.reset = (e, el) -> exports.reset = (e, el) ->
batch = new schema.BatchUpdate(model) batch = new schema.BatchUpdate(model)
batch.startTransaction()
taskTypes = ['habit', 'daily', 'todo', 'reward'] taskTypes = ['habit', 'daily', 'todo', 'reward']
batch.queue 'tasks', {} batch.set 'tasks', {}
_.each taskTypes, (type) -> batch.queue "#{type}Ids", [] _.each taskTypes, (type) -> batch.set "#{type}Ids", []
batch.queue 'balance', 2 if user.get('balance') < 2 #only if they haven't manually bought tokens batch.set 'balance', 2 if user.get('balance') < 2 #only if they haven't manually bought tokens
revive(batch, true) revive(batch, true)
batch.commit() batch.commit()
resetDom(model) resetDom(model)

View file

@ -35,14 +35,14 @@ module.exports.newUserObject = ->
module.exports.updateUser = (batch) -> module.exports.updateUser = (batch) ->
userObj = batch.userObj userObj = batch.userObj
batch.queue('notifications.kickstarter', 'show') unless userObj.notifications?.kickstarter? batch.set('notifications.kickstarter', 'show') unless userObj.notifications?.kickstarter?
batch.queue('friends', []) unless !_.isEmpty(userObj.friends) batch.set('friends', []) unless !_.isEmpty(userObj.friends)
# Preferences, including API key # Preferences, including API key
# Some side-stepping to avoid unecessary set (one day, model.update... one day..) # Some side-stepping to avoid unecessary set (one day, model.update... one day..)
prefs = _.clone(userObj.preferences) prefs = _.clone(userObj.preferences)
_.defaults prefs, { gender: 'm', armorSet: 'v1', api_token: derby.uuid() } prefs = _.defaults prefs, { gender: 'm', armorSet: 'v1', api_token: derby.uuid() }
batch.queue('preferences', prefs) unless _.isEqual(prefs, userObj.preferences) batch.set('preferences', prefs) unless _.isEqual(prefs, userObj.preferences)
## Task List Cleanup ## Task List Cleanup
# FIXME temporary hack to fix lists (Need to figure out why these are happening) # FIXME temporary hack to fix lists (Need to figure out why these are happening)
@ -60,48 +60,54 @@ module.exports.updateUser = (batch) ->
preened = _.filter(union, (val) -> _.contains(taskIds, val)) preened = _.filter(union, (val) -> _.contains(taskIds, val))
# There were indeed issues found, set the new list # There were indeed issues found, set the new list
batch.queue(path, preened) # if _.difference(preened, userObj[path]).length != 0 batch.set(path, preened) # if _.difference(preened, userObj[path]).length != 0
module.exports.BatchUpdate = BatchUpdate = (model) -> module.exports.BatchUpdate = BatchUpdate = (model) ->
user = model.at('_user') user = model.at("_user")
# this is really stupid, but i can't find how to get around user.get() making only available what has been gotten specifically before
# userObj = {}
# _.each Object.keys(userSchema), (key) -> userObj[key] = lodash.cloneDeep user.get(key)
# userObj = lodash.cloneDeep obj # whaaa???
#FIXME - this doesn't work, modifying userObj modifies the value of user.get() at that path
# though that shouldn't be happening
userObj = user.get() userObj = user.get()
origCommit = model._commit
orig_commit = model._commit transactionInProgress = false
model._commit = (txn) ->
txn.dontPersist = true
orig_commit.apply(model, arguments)
updates = {} updates = {}
{
queue: (path, val) -> updates[path] = val
{
userObj: userObj userObj: userObj
startTransaction: ->
# start a batch transaction - nothing between now and @commit() will be set immediately
transactionInProgress = true
# Really strange, user.get() seems to only return attributes which have previously been accessed. So in
# many cases, userObj.tasks.{taskId}.value is undefined - so we manually .get() each attribute here.
# Additionally, for some reason after getting the user object, changing properies manually (userObj.stats.hp = 50)
# seems to actually run user.set('stats.hp',50) which we don't want to do - so we deepClone here
#_.each Object.keys(userSchema), (key) -> userObj[key] = lodash.cloneDeep user.get(key)
#userObj = user.get()
model._commit = (txn) ->
txn.dontPersist = true
origCommit.apply(model, arguments)
### ###
Handles updating the user model. If this is an en-mass operation (eg, server cron), pass the user object as {update}. Handles updating the user model. If this is an en-mass operation (eg, server cron), changes are queued
otherwise, null means commit the changes immediately but not actually set to the model. It also modifies userObj in case you need to access properties manually later.
If transaction not in progress, it just runs standard model.set()
### ###
updateAndQueue: (path, val) -> set: (path, val) ->
@queue path, val if transactionInProgress
# Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790 updates[path] = val
arr = path.split('.') # Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790
arr.reduce (curr, next, index) -> arr = path.split('.')
if (arr.length - 1) == index arr.reduce (curr, next, index) ->
curr[next] = val if (arr.length - 1) == index then curr[next] = val
curr[next] return curr[next]
, userObj , userObj
else
user.set(path, val)
commit: -> commit: ->
_.each updates, (val, path) -> _.each updates, (val, path) ->
user.set(path, val) user.set(path, val)
model._commit = orig_commit model._commit = origCommit
user.set "update__", updates # some hackery in our own branched racer-db-mongo, see findAndModify # some hackery in our own branched racer-db-mongo, see findAndModify of lefnire/racer-db-mongo#habitrpg index.js
user.set "update__", updates
transactionInProgress = false
} }

View file

@ -67,29 +67,29 @@ updateStats = (newStats, batch) ->
if newStats.hp? if newStats.hp?
# Game Over # Game Over
if newStats.hp <= 0 if newStats.hp <= 0
batch.updateAndQueue 'stats.lvl', 0 # signifies dead batch.set 'stats.lvl', 0 # signifies dead
batch.updateAndQueue 'stats.hp', 0 batch.set 'stats.hp', 0
return return
else else
batch.updateAndQueue 'stats.hp', newStats.hp batch.set 'stats.hp', newStats.hp
if newStats.exp? if newStats.exp?
# level up & carry-over exp # level up & carry-over exp
tnl = user.get '_tnl' tnl = user.get '_tnl'
if newStats.exp >= tnl if newStats.exp >= tnl
newStats.exp -= tnl newStats.exp -= tnl
batch.updateAndQueue 'stats.lvl', userObj.stats.lvl + 1 batch.set 'stats.lvl', userObj.stats.lvl + 1
batch.updateAndQueue 'stats.hp', 50 batch.set 'stats.hp', 50
newStats.lvl = userObj.stats.lvl newStats.lvl = userObj.stats.lvl
if !userObj.items?.itemsEnabled and newStats.lvl >= 2 if !userObj.items?.itemsEnabled and newStats.lvl >= 2
batch.queue 'items.itemsEnabled', true #bit of trouble using userSet here batch.set 'items.itemsEnabled', true #bit of trouble using userSet here
if !userObj.flags?.partyEnabled and newStats.lvl >= 3 if !userObj.flags?.partyEnabled and newStats.lvl >= 3
batch.queue 'flags.partyEnabled', true batch.set 'flags.partyEnabled', true
batch.updateAndQueue 'stats.exp', newStats.exp batch.set 'stats.exp', newStats.exp
if newStats.money? if newStats.money?
money = 0.0 if (!money? or money<0) money = 0.0 if (!money? or money<0)
batch.updateAndQueue 'stats.money', newStats.money batch.set 'stats.money', newStats.money
# {taskId} task you want to score # {taskId} task you want to score
# {direction} 'up' or 'down' # {direction} 'up' or 'down'
@ -99,9 +99,10 @@ score = (taskId, direction, times, batch, cron) ->
times ?= 1 times ?= 1
commit = false commit = false
unless batch unless batch?
commit = true commit = true
batch = new schema.BatchUpdate(model) batch = new schema.BatchUpdate(model)
batch.startTransaction()
userObj = batch.userObj userObj = batch.userObj
{money, hp, exp, lvl} = userObj.stats {money, hp, exp, lvl} = userObj.stats
@ -140,7 +141,7 @@ score = (taskId, direction, times, batch, cron) ->
if (delta > 0) then addPoints() else subtractPoints() if (delta > 0) then addPoints() else subtractPoints()
taskObj.history ?= [] taskObj.history ?= []
taskObj.history.push historyEntry taskObj.history.push historyEntry
batch.updateAndQueue "#{taskPath}.history", taskObj.history if taskObj.value != value batch.set "#{taskPath}.history", taskObj.history if taskObj.value != value
when 'daily' when 'daily'
calculateDelta() calculateDelta()
@ -165,7 +166,7 @@ score = (taskId, direction, times, batch, cron) ->
hp += money # hp - money difference hp += money # hp - money difference
money = 0 money = 0
batch.updateAndQueue "#{taskPath}.value", value batch.set "#{taskPath}.value", value
updateStats {hp: hp, exp: exp, money: money}, batch updateStats {hp: hp, exp: exp, money: money}, batch
batch.commit() if commit batch.commit() if commit
return delta return delta
@ -212,7 +213,7 @@ cron = (resetDom_cb) ->
else else
absVal = if (completed) then Math.abs(value) else value absVal = if (completed) then Math.abs(value) else value
todoTally += absVal todoTally += absVal
batch.queue('tasks.' + taskObj.id, taskObj) batch.set('tasks.' + taskObj.id, taskObj)
# Finished tallying # Finished tallying
userObj.history ?= {}; userObj.history.todos ?= []; userObj.history.exp ?= [] userObj.history ?= {}; userObj.history.todos ?= []; userObj.history.exp ?= []
@ -227,8 +228,8 @@ cron = (resetDom_cb) ->
# Set the new user specs, and animate HP loss # Set the new user specs, and animate HP loss
[hpAfter, userObj.stats.hp] = [userObj.stats.hp, hpBefore] [hpAfter, userObj.stats.hp] = [userObj.stats.hp, hpBefore]
batch.queue('stats', userObj.stats) batch.set('stats', userObj.stats)
batch.queue('history', userObj.history) batch.set('history', userObj.history)
batch.commit() batch.commit()
resetDom_cb(model) resetDom_cb(model)
setTimeout (-> user.set 'stats.hp', hpAfter), 1000 # animate hp loss setTimeout (-> user.set 'stats.hp', hpAfter), 1000 # animate hp loss