109 lines
2.5 KiB
Python
109 lines
2.5 KiB
Python
from copy import deepcopy
|
|
from nullptr.util import sg
|
|
|
|
class Reference:
|
|
def __init__(self, typ, symbol, store):
|
|
self.typ = typ
|
|
self.symbol = symbol
|
|
self.store = store
|
|
|
|
@classmethod
|
|
def create(cls, obj):
|
|
o = cls(type(obj), obj.symbol, obj.store)
|
|
return o
|
|
|
|
def resolve(self):
|
|
return self.store.get(self.typ, self.symbol)
|
|
|
|
def __repr__(self):
|
|
return f'*REF*{self.symbol}.{self.typ.ext()}'
|
|
|
|
class Base:
|
|
identifier = 'symbol'
|
|
|
|
def __init__(self, symbol, store):
|
|
self.disable_dirty = True
|
|
self.file_offset = None
|
|
self.store = store
|
|
self.symbol = symbol
|
|
self.define()
|
|
self.disable_dirty = False
|
|
|
|
@classmethod
|
|
def ext(cls):
|
|
raise NotImplementedError('no ext')
|
|
|
|
def define(self):
|
|
pass
|
|
|
|
def __hash__(self):
|
|
return hash((str(type(self)), self.symbol))
|
|
|
|
def __eq__(self, other):
|
|
return type(self) == type(other) and self.symbol == other.symbol
|
|
|
|
def get_system(self):
|
|
parts = self.symbol.split('-')
|
|
system_str = f'{parts[0]}-{parts[1]}'
|
|
system = self.store.get('System', system_str, create=True)
|
|
return system
|
|
|
|
def seta(self, attr, d, name=None, interp=None):
|
|
if name is None:
|
|
name = attr
|
|
val = sg(d, name)
|
|
if val is not None:
|
|
if interp is not None:
|
|
val = interp(val)
|
|
setattr(self, attr, val)
|
|
|
|
def setlst(self, attr, d, name, member, interp=None):
|
|
val = sg(d, name)
|
|
if val is not None:
|
|
lst = []
|
|
for x in val:
|
|
val = sg(x, member)
|
|
if interp is not None:
|
|
val = interp(val)
|
|
lst.append(val)
|
|
setattr(self, attr, lst)
|
|
|
|
def __setattr__(self, name, value):
|
|
if name not in ['symbol','store','disable_dirty', 'file_offset'] and not self.disable_dirty:
|
|
self.store.dirty(self)
|
|
if issubclass(type(value), Base):
|
|
value = Reference.create(value)
|
|
super().__setattr__(name, value)
|
|
|
|
def __getattribute__(self, nm):
|
|
val = super().__getattribute__(nm)
|
|
if type(val) == Reference:
|
|
val = val.resolve()
|
|
return val
|
|
|
|
def update(self, d):
|
|
pass
|
|
|
|
def is_expired(self):
|
|
return False
|
|
|
|
def load(self, d):
|
|
self.disable_dirty = True
|
|
self.__dict__.update(d)
|
|
self.disable_dirty = False
|
|
|
|
def type(self):
|
|
return self.__class__.__name__
|
|
|
|
def __str__(self):
|
|
return self.f()
|
|
|
|
def __repr__(self):
|
|
return self.f()
|
|
|
|
def f(self, detail=1):
|
|
r = self.symbol
|
|
if detail > 1:
|
|
r += '.' + self.ext()
|
|
return r
|