batch update for general scoring. note, model.on * broken

This commit is contained in:
Tyler Renelle 2013-02-01 00:39:42 -05:00
parent 1350f74c78
commit ecaf8643a4
3 changed files with 45 additions and 38 deletions

View file

@ -45,7 +45,8 @@ get '/', (page, model, next) ->
model.subscribe q, (err, user) ->
#user = result.at(0)
model.ref '_user', user
userObj = user.get()
batch = new schema.BatchUpdate(model)
userObj = batch.getUser()
return page.redirect '/500.html' unless userObj? #this should never happen, but it is. Looking into it
@ -59,7 +60,9 @@ get '/', (page, model, next) ->
model.set '_view', _view
schema.updateUser(model, userObj)
schema.updateUser(batch)
batch.commit()
setupListReferences(model)
setupModelFns(model)

View file

@ -29,9 +29,8 @@ module.exports.newUserObject = ->
when 'reward' then newUser.rewardIds.push guid
return newUser
module.exports.updateUser = (model, userObj) ->
user = model.at('_user')
batch = new BatchUpdate(model)
module.exports.updateUser = (batch) ->
userObj = batch.getUser()
batch.queue('notifications.kickstarter', 'show') unless userObj.notifications?.kickstarter?
batch.queue('friends', []) unless !_.isEmpty(userObj.friends)
@ -63,6 +62,7 @@ module.exports.updateUser = (model, userObj) ->
module.exports.BatchUpdate = BatchUpdate = (model) ->
user = model.at('_user')
userObj = undefined
updates = {}
{
queue: (path, val) ->
@ -74,6 +74,22 @@ module.exports.BatchUpdate = BatchUpdate = (model) ->
model._commit = commit
updates[path] = val
getUser: -> userObj ?= user.get()
###
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
###
updateAndQueue: (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]
, @getUser()
@queue path, val
commit: ->
user.set "update__", updates # some hackery in our own branched racer-db-mongo, see findAndModify
}

View file

@ -53,30 +53,13 @@ taskDeltaFormula = (currentValue, direction) ->
delta = if (currentValue < 0) then (( -0.1 * currentValue + 1 ) * sign) else (( Math.pow(0.9,currentValue) ) * sign)
return delta
###
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
###
userSet = (path, value, update) ->
if update
# 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] = value
curr[next]
, update
else
user.set path, value
###
Updates user stats with new stats. Handles death, leveling up, etc
{stats} new stats
{update} if aggregated changes, pass in userObj as update. otherwise commits will be made immediately
###
updateStats = (newStats, update) ->
userObj = update || user.get()
updateStats = (newStats, batch) ->
userObj = batch.getUser()
# if user is dead, dont do anything
return if userObj.stats.lvl == 0
@ -84,38 +67,42 @@ updateStats = (newStats, update) ->
if newStats.hp?
# Game Over
if newStats.hp <= 0
userSet 'stats.lvl', 0, update # signifies dead
userSet 'stats.hp', 0, update
batch.updateAndQueue 'stats.lvl', 0 # signifies dead
batch.updateAndQueue 'stats.hp', 0
return
else
userSet 'stats.hp', newStats.hp, update
batch.updateAndQueue 'stats.hp', newStats.hp
if newStats.exp?
# level up & carry-over exp
tnl = user.get '_tnl'
if newStats.exp >= tnl
newStats.exp -= tnl
userSet 'stats.lvl', userObj.stats.lvl + 1, update
userSet 'stats.hp', 50, update
batch.updateAndQueue 'stats.lvl', userObj.stats.lvl + 1
batch.updateAndQueue 'stats.hp', 50
newStats.lvl = userObj.stats.lvl
if !userObj.items?.itemsEnabled and newStats.lvl >= 2
user.set 'items.itemsEnabled', true #bit of trouble using userSet here
batch.queue 'items.itemsEnabled', true #bit of trouble using userSet here
if !userObj.flags?.partyEnabled and newStats.lvl >= 3
user.set 'flags.partyEnabled', true
userSet 'stats.exp', newStats.exp, update
batch.queue 'flags.partyEnabled', true
batch.updateAndQueue 'stats.exp', newStats.exp
if newStats.money?
money = 0.0 if (!money? or money<0)
userSet 'stats.money', newStats.money, update
batch.updateAndQueue 'stats.money', newStats.money
# {taskId} task you want to score
# {direction} 'up' or 'down'
# {times} # times to call score on this task (1 unless cron, usually)
# {update} if we're running updates en-mass (eg, cron on server) pass in userObj
score = (taskId, direction, times, update) ->
score = (taskId, direction, times, batch) ->
times ?= 1
userObj = update or user.get()
commit = !batch?
console.log {commit:commit}
batch ?= new schema.BatchUpdate(model)
userObj = batch.getUser()
{money, hp, exp, lvl} = userObj.stats
taskPath = "tasks.#{taskId}"
@ -175,8 +162,9 @@ score = (taskId, direction, times, update) ->
hp += money # hp - money difference
money = 0
userSet "#{taskPath}.value", value, update
updateStats {hp: hp, exp: exp, money: money}, update
batch.updateAndQueue "#{taskPath}.value", value
updateStats {hp: hp, exp: exp, money: money}, batch
batch.commit() if commit
return delta
###
@ -188,8 +176,8 @@ cron = (resetDom_cb) ->
daysPassed = helpers.daysBetween(today, user.get('lastCron'))
if daysPassed > 0
user.set 'lastCron', today
userObj = user.get()
batch = new schema.BatchUpdate(model)
userObj = batch.getUser()
hpBefore = userObj.stats.hp #we'll use this later so we can animate hp loss
# Tally each task
todoTally = 0