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)
model.ref '_user', user
batch = new schema.BatchUpdate(model)
batch.startTransaction()
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
items = userObj.items
@ -254,14 +259,14 @@ ready (model) ->
revive = (batch) ->
# Reset stats
batch.queue 'stats.hp', 50
batch.queue 'stats.lvl', 1
batch.queue 'stats.money', 0
batch.queue 'stats.exp', 0
batch.set 'stats.hp', 50
batch.set 'stats.lvl', 1
batch.set 'stats.money', 0
batch.set 'stats.exp', 0
# Reset items
batch.queue 'items.armor', 0
batch.queue 'items.weapon', 0
batch.set 'items.armor', 0
batch.set 'items.weapon', 0
# Reset item store
model.set '_view.items.armor', content.items.armor[1]
@ -269,16 +274,18 @@ ready (model) ->
exports.revive = (e, el) ->
batch = new schema.BatchUpdate(model)
batch.startTransaction()
revive(batch)
batch.commit()
resetDom(model)
exports.reset = (e, el) ->
batch = new schema.BatchUpdate(model)
batch.startTransaction()
taskTypes = ['habit', 'daily', 'todo', 'reward']
batch.queue 'tasks', {}
_.each taskTypes, (type) -> batch.queue "#{type}Ids", []
batch.queue 'balance', 2 if user.get('balance') < 2 #only if they haven't manually bought tokens
batch.set 'tasks', {}
_.each taskTypes, (type) -> batch.set "#{type}Ids", []
batch.set 'balance', 2 if user.get('balance') < 2 #only if they haven't manually bought tokens
revive(batch, true)
batch.commit()
resetDom(model)

View file

@ -35,14 +35,14 @@ module.exports.newUserObject = ->
module.exports.updateUser = (batch) ->
userObj = batch.userObj
batch.queue('notifications.kickstarter', 'show') unless userObj.notifications?.kickstarter?
batch.queue('friends', []) unless !_.isEmpty(userObj.friends)
batch.set('notifications.kickstarter', 'show') unless userObj.notifications?.kickstarter?
batch.set('friends', []) unless !_.isEmpty(userObj.friends)
# Preferences, including API key
# Some side-stepping to avoid unecessary set (one day, model.update... one day..)
prefs = _.clone(userObj.preferences)
_.defaults prefs, { gender: 'm', armorSet: 'v1', api_token: derby.uuid() }
batch.queue('preferences', prefs) unless _.isEqual(prefs, userObj.preferences)
prefs = _.defaults prefs, { gender: 'm', armorSet: 'v1', api_token: derby.uuid() }
batch.set('preferences', prefs) unless _.isEqual(prefs, userObj.preferences)
## Task List Cleanup
# 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))
# 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) ->
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
user = model.at("_user")
userObj = user.get()
orig_commit = model._commit
model._commit = (txn) ->
txn.dontPersist = true
orig_commit.apply(model, arguments)
origCommit = model._commit
transactionInProgress = false
updates = {}
{
queue: (path, val) -> updates[path] = val
{
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}.
otherwise, null means commit the changes immediately
Handles updating the user model. If this is an en-mass operation (eg, server cron), changes are queued
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) ->
@queue path, val
# Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790
arr = path.split('.')
arr.reduce (curr, next, index) ->
if (arr.length - 1) == index
curr[next] = val
curr[next]
, userObj
set: (path, val) ->
if transactionInProgress
updates[path] = val
# Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790
arr = path.split('.')
arr.reduce (curr, next, index) ->
if (arr.length - 1) == index then curr[next] = val
return curr[next]
, userObj
else
user.set(path, val)
commit: ->
_.each updates, (val, path) ->
user.set(path, val)
model._commit = orig_commit
user.set "update__", updates # some hackery in our own branched racer-db-mongo, see findAndModify
model._commit = origCommit
# 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?
# Game Over
if newStats.hp <= 0
batch.updateAndQueue 'stats.lvl', 0 # signifies dead
batch.updateAndQueue 'stats.hp', 0
batch.set 'stats.lvl', 0 # signifies dead
batch.set 'stats.hp', 0
return
else
batch.updateAndQueue 'stats.hp', newStats.hp
batch.set 'stats.hp', newStats.hp
if newStats.exp?
# level up & carry-over exp
tnl = user.get '_tnl'
if newStats.exp >= tnl
newStats.exp -= tnl
batch.updateAndQueue 'stats.lvl', userObj.stats.lvl + 1
batch.updateAndQueue 'stats.hp', 50
batch.set 'stats.lvl', userObj.stats.lvl + 1
batch.set 'stats.hp', 50
newStats.lvl = userObj.stats.lvl
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
batch.queue 'flags.partyEnabled', true
batch.updateAndQueue 'stats.exp', newStats.exp
batch.set 'flags.partyEnabled', true
batch.set 'stats.exp', newStats.exp
if newStats.money?
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
# {direction} 'up' or 'down'
@ -99,9 +99,10 @@ score = (taskId, direction, times, batch, cron) ->
times ?= 1
commit = false
unless batch
unless batch?
commit = true
batch = new schema.BatchUpdate(model)
batch.startTransaction()
userObj = batch.userObj
{money, hp, exp, lvl} = userObj.stats
@ -140,7 +141,7 @@ score = (taskId, direction, times, batch, cron) ->
if (delta > 0) then addPoints() else subtractPoints()
taskObj.history ?= []
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'
calculateDelta()
@ -165,7 +166,7 @@ score = (taskId, direction, times, batch, cron) ->
hp += money # hp - money difference
money = 0
batch.updateAndQueue "#{taskPath}.value", value
batch.set "#{taskPath}.value", value
updateStats {hp: hp, exp: exp, money: money}, batch
batch.commit() if commit
return delta
@ -212,7 +213,7 @@ cron = (resetDom_cb) ->
else
absVal = if (completed) then Math.abs(value) else value
todoTally += absVal
batch.queue('tasks.' + taskObj.id, taskObj)
batch.set('tasks.' + taskObj.id, taskObj)
# Finished tallying
userObj.history ?= {}; userObj.history.todos ?= []; userObj.history.exp ?= []
@ -227,8 +228,8 @@ cron = (resetDom_cb) ->
# Set the new user specs, and animate HP loss
[hpAfter, userObj.stats.hp] = [userObj.stats.hp, hpBefore]
batch.queue('stats', userObj.stats)
batch.queue('history', userObj.history)
batch.set('stats', userObj.stats)
batch.set('history', userObj.history)
batch.commit()
resetDom_cb(model)
setTimeout (-> user.set 'stats.hp', hpAfter), 1000 # animate hp loss