Handle use case of invalid fit's mucking things up

This commit is contained in:
blitzmann
2015-07-10 15:45:36 -04:00
parent 68dddf2810
commit 496e9b56b5
3 changed files with 35 additions and 41 deletions

View File

@@ -52,24 +52,24 @@ projectedFits_table = Table("projectedFits", saveddata_meta,
)
class ProjectedFit(object):
def __init__(self, source_fit, k, amount=1, active=True):
#print "init projected: source fit: ", source_fit.name, source_fit, "key (fit ID)", key, "active:", active, "amount:",amount
self.sourceID = k
def __init__(self, sourceID, source_fit, amount=1, active=True):
self.sourceID = sourceID
self.source_fit = source_fit
#self.victim_item = None
self.amount = amount
self.active = active
@reconstructor
def init(self):
print "db init"
print "\t source:", self.source_fit
print "\t dest:", self.victim_fit
if self.source_fit.isInvalid:
# Very rare for this to happen, but be prepared for it
eos.db.saveddata_session.delete(self.source_fit)
eos.db.saveddata_session.flush()
eos.db.saveddata_session.refresh(self.victim_fit)
Fit._Fit__projectedFits = association_proxy(
"victimOf", # look at the victimOf association...
"source_fit", # .. and return the source fits
creator=lambda k, source_fit: ProjectedFit(source_fit, k)
creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit)
)
mapper(Fit, fits_table,

View File

@@ -207,8 +207,9 @@ class Fit(object):
@property
def projectedFits(self):
#print "get projected fits for :", self.name
return self.__projectedFits.values()
# only in extreme edge cases will the fit be invalid, but to be sure do
# not return them. By this time
return [fit for fit in self.__projectedFits.values() if not fit.isInvalid]
def getProjectionInfo(self, fitID):
print "get projection info for fitID: ", fitID
@@ -331,7 +332,7 @@ class Fit(object):
if map[key](val) == False: raise ValueError(str(val) + " is not a valid value for " + key)
else: return val
def clear(self):
def clear(self, projected=False):
self.__effectiveTank = None
self.__weaponDPS = None
self.__minerYield = None
@@ -364,20 +365,18 @@ class Fit(object):
(self.character, self.extraAttributes),
)
# If we are in a root ship, add projected fits to clear list
# Do not add projected fits if self is already projected - this can
# cause infinite recursion in projection loop, eg A > B > C > A
# @todo: since fits persist, we need to be sure that even if a fit has
# projection info (loaded as a projected fit), this still happens when
# we clear the fit if the fit is the root
#if self.projectionInfo is None:
if True:
c = chain(c, self.projectedFits)
for stuff in c:
if stuff is not None and stuff != self:
stuff.clear()
# If this is the active fit that we are clearing, not a projected fit,
# then this will run and clear the projected ships and flag the next
# iteration to skip this part to prevent recursion.
if not projected:
for stuff in self.projectedFits:
if stuff is not None and stuff != self:
stuff.clear(projected=True)
#Methods to register and get the thing currently affecting the fit,
#so we can correctly map "Affected By"
def register(self, currModifier):
@@ -417,15 +416,11 @@ class Fit(object):
timer = Timer('Fit: %d, %s'%(self.ID, self.name), logger)
logger.debug("Starting fit calculation on: %d %s (%s)" %
(self.ID, self.name, self.ship.item.name))
print self
#print self.__projectedFits
#print self.projectedFits
if targetFit:
logger.debug("Applying projections to target: %d %s (%s)",
targetFit.ID, targetFit.name, targetFit.ship.item.name)
#projectionInfo = self.getProjectionInfo(targetFit.ID)
#logger.debug("ProjectionInfo: amount=%s, active=%s, instance=%s",
# projectionInfo.amount, projectionInfo.active, projectionInfo)
projectionInfo = self.getProjectionInfo(targetFit.ID)
logger.debug("ProjectionInfo: %s", ', '.join("%s: %s" % item for item in vars(projectionInfo).items()))
refreshBoosts = False
if withBoosters is True:
@@ -457,14 +452,7 @@ class Fit(object):
if self.__calculated and not projected:
logger.debug("Fit has already been calculated and is not projected, returning")
return
print
print "******** projected fits ********"
print self.__projectedFits
print "******** projectedOnto ********"
print self.projectedOnto
print "******** victimOf ********"
print self.victimOf
print
# Mark fit as calculated
self.__calculated = True
@@ -492,7 +480,7 @@ class Fit(object):
self.register(item)
item.calculateModifiedAttributes(self, runTime, False)
if projected is True:
#for _ in xrange(projectionInfo.amount):
for _ in xrange(projectionInfo.amount):
targetFit.register(item)
item.calculateModifiedAttributes(targetFit, runTime, True)
@@ -501,7 +489,7 @@ class Fit(object):
# Only apply projected fits if fit it not projected itself.
if not projected:
for fit in self.projectedFits:
#if fit.getProjectionInfo(self.ID).active:
if fit.getProjectionInfo(self.ID).active:
fit.calculateModifiedAttributes(self, withBoosters=withBoosters, dirtyStorage=dirtyStorage)
timer.checkpoint('Done with fit calculation')

View File

@@ -175,7 +175,7 @@ class Fit(object):
fit = eos.db.getFit(fitID)
sFleet = Fleet.getInstance()
sFleet.removeAssociatedFleetData(fit)
self.removeProjectedData(fitID)
#self.removeProjectedData(fitID)
eos.db.remove(fit)
@@ -247,6 +247,7 @@ class Fit(object):
fit.fleet = f
if not projected:
print "Not projected, getting projected fits"
for fitP in fit.projectedFits:
self.getFit(fitP.ID, projected = True)
self.recalc(fit, withBoosters=True)
@@ -326,9 +327,12 @@ class Fit(object):
if thing.ID == fitID:
return
if thing in fit.projectedFits:
return
fit.__projectedFits[thing.ID] = thing
# this bit is required -- see GH issue
# this bit is required -- see GH issue # 83
eos.db.saveddata_session.flush()
eos.db.saveddata_session.refresh(thing)
elif thing.category.name == "Drone":
@@ -369,9 +373,11 @@ class Fit(object):
thing.state = self.__getProposedState(thing, click)
if not thing.canHaveState(thing.state, fit):
thing.state = State.OFFLINE
elif isinstance(thing, eos.types.Fit) and thing.projectionInfo is not None:
elif isinstance(thing, eos.types.Fit):
print "toggle fit"
thing.projectionInfo.active = not thing.projectionInfo.active
projectionInfo = thing.getProjectionInfo(fitID)
if projectionInfo:
projectionInfo.active = not projectionInfo.active
eos.db.commit()
self.recalc(fit)