def __generic_init(self): # Attributes which store objects hidden behind properties self.__source = None self.__ship = None self.__character_proxy = None self.__character_core = None # Eos fit will be primary point of using Eos calculation engine for # fit-specific data self._eos_fit = EosFit() # Manages fit-specific data needed for undo/redo self._cmd_mgr = CommandManager(100) # There's little sense in changing proxy character, thus we assign # it here and it stays with fit forever self.__set_character_proxy(CharacterProxy())
class Fit(PyfaBase): """ Full pyfa model of fit: .fit .character_core (read-write fit-agnostic) .RestrictedSet(skills) .character_proxy (read-only fit-specific) .RestrictedSet(skills) .ship .stance .{subsystems} .modules.[high]/[med]/[low] """ __tablename__ = 'fits' id = Column('fit_id', Integer, primary_key=True) name = Column('fit_name', String, nullable=False) _db_ship_type_id = Column('ship_type_id', Integer) _db_stance_type_id = Column('stance_type_id', Integer) _db_character_id = Column('character_id', Integer, ForeignKey('characters.character_id')) _db_character = relationship('Character') def __init__(self, name='', source=None, ship=None): self.__generic_init() # Use default source, unless specified otherwise if source is None: source = SourceManager.default self._set_source(source) self._set_ship(ship) self.name = name @reconstructor def _dbinit(self): self.__generic_init() # Use default source for all reconstructed fits self._set_source(SourceManager.default) # Restore entities which are stored on fit in DB if self._db_ship_type_id is not None: self._set_ship(Ship(self._db_ship_type_id)) if self._db_stance_type_id is not None: self.ship._set_stance(Stance(self._db_stance_type_id)) # TODO: find appropriate way to reconstruct modules for module in self._db_modules: pass for subsystem in self._db_subsystems: self.ship.subsystems._add_to_set(subsystem) self.character_core = self._db_character def __generic_init(self): # Attributes which store objects hidden behind properties self.__source = None self.__ship = None self.__character_proxy = None self.__character_core = None # Eos fit will be primary point of using Eos calculation engine for # fit-specific data self._eos_fit = EosFit() # Manages fit-specific data needed for undo/redo self._cmd_mgr = CommandManager(100) # There's little sense in changing proxy character, thus we assign # it here and it stays with fit forever self.__set_character_proxy(CharacterProxy()) # Define list of source-dependent child objects, it's necessary # to update fit source @property def _src_children(self): return get_src_children(chain( (self.ship,), # Just proxy, character core is completely separate entity with # its own source management (self.character_proxy,), )) # Read-only info @property def stats(self): return self._eos_fit.stats # Children getters/setters @property def character_core(self): return self.__character_core @character_core.setter def character_core(self, new_char_core): old_char_core = self.__character_core if new_char_core is old_char_core: return # Update child reference self.__character_core = new_char_core # Update DB self._db_character = new_char_core # Handle all interactions between new character core and # character proxy (which is attached to this fit) on proxy # side self.character_proxy._parent_char_core = new_char_core @property def character_proxy(self): """ For character proxy we're not providing setter because it's supposed to stay with fit all the time. """ return self.__character_proxy def __set_character_proxy(self, new_char_proxy): old_char_proxy = self.__character_proxy if new_char_proxy is old_char_proxy: return if old_char_proxy is not None: if old_char_proxy._parent_fit is not self: raise ItemRemovalConsistencyError(old_char_proxy) # Handle all character proxy children removal on proxy itself old_char_proxy._parent_fit = None # Update child reference self.__character_proxy = new_char_proxy if new_char_proxy is not None: if new_char_proxy._parent_fit is not None: raise ItemAlreadyUsedError(new_char_proxy) # Handle all character proxy children addition on proxy itself new_char_proxy._parent_fit = self @property def ship(self): return self.__ship @ship.setter def ship(self, new_ship): command = ShipChangeCommand(self, new_ship) self._cmd_mgr.do(command) def _set_ship(self, new_ship): old_ship = self.__ship if new_ship is old_ship: return if old_ship is not None: if old_ship._parent_fit is not self: raise ItemRemovalConsistencyError(old_ship) old_ship._parent_fit = None self.__ship = new_ship if new_ship is not None: if new_ship._parent_fit is not None: raise ItemAlreadyUsedError(new_ship) new_ship._parent_fit = self # Undo/redo proxies @property def has_undo(self): return self._cmd_mgr.has_undo @property def has_redo(self): return self._cmd_mgr.has_redo def undo(self): self._cmd_mgr.undo() def redo(self): self._cmd_mgr.redo() def purge_commands(self): """ Purge all undos/redos fit currently has. Useful when you want to do some initial setup on the fit, and then purge commands to present fit without undo queue. """ self._cmd_mgr.purge() # Miscellanea public stuff @property def source(self): return self.__source @source.setter def source(self, new_source): command = SourceChangeCommand(self, new_source) self._cmd_mgr.do(command) def _set_source(self, new_source): """ Set fit's source. Source represents EVE data to be used. Required arguments: new_source -- source to use, can be None """ # Attempt to fetch source from source manager if passed object # is not instance of source class if not isinstance(new_source, Source) and new_source is not None: new_source = SourceManager.get(new_source) old_source = self.source # Do not update anything if sources are the same if new_source is old_source: return self.__source = new_source # Update eos model with new data self._eos_fit.source = getattr(new_source, 'eos', None) # Update pyfa model with new data for src_child in self._src_children: src_child._update_source() persist = pyfa_persist abandon = pyfa_abandon def validate(self): self._eos_fit.validate() # Auxiliary methods def __repr__(self): spec = ['id'] return make_repr_str(self, spec)