Fixes critical design issue when it comes to projected fits. Disabled some of the more advanced functionality (projection amount and active) to cope to development. Crash still happens occasionally when adding projected fit for unknown reasons - not 100% reproducable yet
This commit is contained in:
@@ -21,6 +21,7 @@ from sqlalchemy import *
|
||||
from sqlalchemy.orm import *
|
||||
from sqlalchemy.sql import and_
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db.saveddata.module import modules_table
|
||||
@@ -51,25 +52,27 @@ projectedFits_table = Table("projectedFits", saveddata_meta,
|
||||
)
|
||||
|
||||
class ProjectedFit(object):
|
||||
def __init__(self, source_item, dest_item, amount=1, active=True):
|
||||
print "init projected item", source_item, dest_item, active, amount
|
||||
self.source_item = source_item
|
||||
self.dest_item = dest_item
|
||||
def __init__(self, source_fit, k, amount=1, active=True):
|
||||
print "init projected: ", k, source_fit.name, active, amount
|
||||
self.sourceID = k
|
||||
self.source_item = source_fit
|
||||
self.victim_item = None
|
||||
self.amount = amount
|
||||
self.active = active
|
||||
self.dest_item.projectionInfo = self
|
||||
#self.dest_item.setProjectionInfo(self.source_item.ID, self)
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
print "db init"
|
||||
print "\t source:",self.source_item
|
||||
print "\t dest:", self.dest_item
|
||||
self.dest_item.projectionInfo = self
|
||||
print "\t source:", self.source_fit
|
||||
print "\t dest:", self.victim_fit
|
||||
#self.dest_item.setProjectionInfo(self.source_item.ID, self)
|
||||
#print self.dest_item.ship.item.name, ">", self.source_item.ship.item.name,self
|
||||
|
||||
Fit._Fit__projectedFits = association_proxy(
|
||||
"projected_items",
|
||||
"dest_item",
|
||||
creator=lambda dest_item: ProjectedFit(None, dest_item)
|
||||
"victimOf", # look at the victimOf association...
|
||||
"source_fit", # .. and return the source fits
|
||||
creator=lambda k, victim_fit: ProjectedFit(victim_fit, k)
|
||||
)
|
||||
|
||||
mapper(Fit, fits_table,
|
||||
@@ -128,15 +131,17 @@ mapper(Fit, fits_table,
|
||||
backref="fits"),
|
||||
"_Fit__damagePattern": relation(DamagePattern),
|
||||
"_Fit__targetResists": relation(TargetResists),
|
||||
"dest_items": relationship(
|
||||
"projectedOnto": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=projectedFits_table.c.victimID == fits_table.c.ID,
|
||||
backref='dest_item',
|
||||
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
||||
backref='source_fit',
|
||||
collection_class=attribute_mapped_collection('victimID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"projected_items": relationship(
|
||||
"victimOf": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=fits_table.c.ID == projectedFits_table.c.sourceID,
|
||||
backref='source_item',
|
||||
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
|
||||
backref='victim_fit',
|
||||
collection_class=attribute_mapped_collection('sourceID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -119,7 +119,7 @@ class Fit(object):
|
||||
self.__capUsed = None
|
||||
self.__capRecharge = None
|
||||
self.__calculatedTargets = []
|
||||
self.__projectionInfo = None
|
||||
self.__projectionMap = {}
|
||||
self.factorReload = False
|
||||
self.fleet = None
|
||||
self.boostsFits = set()
|
||||
@@ -208,15 +208,10 @@ class Fit(object):
|
||||
|
||||
@property
|
||||
def projectedFits(self):
|
||||
return self.__projectedFits
|
||||
return self.__projectedFits.values()
|
||||
|
||||
@property
|
||||
def projectionInfo(self):
|
||||
return self.__projectionInfo
|
||||
|
||||
@projectionInfo.setter
|
||||
def projectionInfo(self, projectionInfo):
|
||||
self.__projectionInfo = projectionInfo
|
||||
def getProjectionInfo(self, fitID):
|
||||
return self.projectedOnto.get(fitID, None)
|
||||
|
||||
@property
|
||||
def projectedDrones(self):
|
||||
@@ -371,7 +366,11 @@ class Fit(object):
|
||||
# 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
|
||||
if self.projectionInfo is None:
|
||||
# @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:
|
||||
@@ -417,10 +416,13 @@ 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.projectedFits
|
||||
if targetFit:
|
||||
logger.debug("Applying projections to target: %d %s (%s)" %
|
||||
(targetFit.ID, targetFit.name, targetFit.ship.item.name))
|
||||
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)
|
||||
|
||||
refreshBoosts = False
|
||||
if withBoosters is True:
|
||||
@@ -489,7 +491,7 @@ class Fit(object):
|
||||
self.register(item)
|
||||
item.calculateModifiedAttributes(self, runTime, False)
|
||||
if projected is True:
|
||||
for _ in xrange(self.projectionInfo.amount):
|
||||
#for _ in xrange(projectionInfo.amount):
|
||||
targetFit.register(item)
|
||||
item.calculateModifiedAttributes(targetFit, runTime, True)
|
||||
|
||||
@@ -498,7 +500,7 @@ class Fit(object):
|
||||
# Only apply projected fits if fit it not projected itself.
|
||||
if not projected:
|
||||
for fit in self.projectedFits:
|
||||
if fit.projectionInfo.active:
|
||||
#if fit.getProjectionInfo(self.ID).active:
|
||||
fit.calculateModifiedAttributes(self, withBoosters=withBoosters, dirtyStorage=dirtyStorage)
|
||||
|
||||
timer.checkpoint('Done with fit calculation')
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
from gui import builtinViewColumns
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui import bitmapLoader
|
||||
import gui.mainFrame
|
||||
|
||||
import wx
|
||||
from eos.types import Drone, Cargo, Fit, Module, Slot, Rack
|
||||
import service
|
||||
@@ -29,6 +31,7 @@ class BaseName(ViewColumn):
|
||||
name = "Base Name"
|
||||
def __init__(self, fittingView, params):
|
||||
ViewColumn.__init__(self, fittingView)
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.columnText = "Name"
|
||||
self.shipImage = fittingView.imageList.GetImageIndex("ship_small", "icons")
|
||||
self.mask = wx.LIST_MASK_TEXT
|
||||
@@ -39,7 +42,8 @@ class BaseName(ViewColumn):
|
||||
elif isinstance(stuff, Cargo):
|
||||
return "%dx %s" % (stuff.amount, stuff.item.name)
|
||||
elif isinstance(stuff, Fit):
|
||||
return "%dx %s (%s)" % (stuff.projectionInfo.amount, stuff.name, stuff.ship.item.name)
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
return "%dx %s (%s)" % (stuff.getProjectionInfo(fitID).amount, stuff.name, stuff.ship.item.name)
|
||||
elif isinstance(stuff, Rack):
|
||||
if service.Fit.getInstance().serviceFittingOptions["rackLabels"]:
|
||||
if stuff.slot == Slot.MODE:
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui import bitmapLoader
|
||||
import gui.mainFrame
|
||||
|
||||
import wx
|
||||
from eos.types import Drone, Module, Rack, Fit
|
||||
from eos.types import State as State_
|
||||
@@ -27,6 +29,7 @@ class State(ViewColumn):
|
||||
name = "State"
|
||||
def __init__(self, fittingView, params):
|
||||
ViewColumn.__init__(self, fittingView)
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.resizable = False
|
||||
self.size = 16
|
||||
self.maxsize = self.size
|
||||
@@ -56,9 +59,12 @@ class State(ViewColumn):
|
||||
else:
|
||||
return self.fittingView.imageList.GetImageIndex("state_%s_small" % State_.getName(stuff.state).lower(), "icons")
|
||||
elif isinstance(stuff, Fit):
|
||||
if stuff.projectionInfo is None:
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
projectionInfo = stuff.getProjectionInfo(fitID)
|
||||
|
||||
if projectionInfo is None:
|
||||
return -1
|
||||
if stuff.projectionInfo.active:
|
||||
if projectionInfo.active:
|
||||
return generic_active
|
||||
return generic_inactive
|
||||
else:
|
||||
|
||||
@@ -325,7 +325,8 @@ class Fit(object):
|
||||
if isinstance(thing, eos.types.Fit):
|
||||
if thing.ID == fitID:
|
||||
return
|
||||
fit.projectedFits.append(thing)
|
||||
|
||||
fit.__projectedFits[thing.ID] = thing
|
||||
elif thing.category.name == "Drone":
|
||||
drone = None
|
||||
for d in fit.projectedDrones.find(thing):
|
||||
@@ -374,10 +375,10 @@ class Fit(object):
|
||||
def changeAmount(self, fitID, projected_fit, amount):
|
||||
"""Change amount of projected fits"""
|
||||
fit = eos.db.getFit(fitID)
|
||||
amount = min(20, max(1, amount)) # 1 <= a <= 5
|
||||
|
||||
if projected_fit.projectionInfo is not None:
|
||||
projected_fit.projectionInfo.amount = amount
|
||||
amount = min(20, max(1, amount)) # 1 <= a <= 20
|
||||
projectionInfo = projected_fit.getProjectionInfo(fitID)
|
||||
if projectionInfo:
|
||||
projectionInfo.amount = amount
|
||||
|
||||
eos.db.commit()
|
||||
self.recalc(fit)
|
||||
@@ -389,7 +390,8 @@ class Fit(object):
|
||||
elif isinstance(thing, eos.types.Module):
|
||||
fit.projectedModules.remove(thing)
|
||||
else:
|
||||
fit.projectedFits.remove(thing)
|
||||
del fit.__projectedFits[thing.ID]
|
||||
#fit.projectedFits.remove(thing)
|
||||
|
||||
eos.db.commit()
|
||||
self.recalc(fit)
|
||||
@@ -937,7 +939,7 @@ class Fit(object):
|
||||
self.recalc(fit)
|
||||
|
||||
def recalc(self, fit, withBoosters=False):
|
||||
logger.debug("="*10+"recalc"+"="*10)
|
||||
logger.debug("="*10+"recalc"+"="*10)
|
||||
if fit.factorReload is not self.serviceFittingOptions["useGlobalForceReload"]:
|
||||
fit.factorReload = self.serviceFittingOptions["useGlobalForceReload"]
|
||||
fit.clear()
|
||||
|
||||
Reference in New Issue
Block a user