+class ExportError(Exception):
+ def __init__(self, objs):
+ super().__init__(" -> ".join(o.name for o in objs))
+ self.objs = objs
+
+class ExportContext:
+ def __init__(self, ctx, *args, verbose=False):
+ self.obj = None
+
+ if type(ctx)==ExportContext:
+ self.level = ctx.level+1
+ self.parent = ctx
+ self.context = ctx.context
+ self.verbose = ctx.verbose
+ self.descr, self.start, self.delta = args
+ if type(self.descr)!=str:
+ self.obj = self.descr
+ self.descr = self.descr.name
+ else:
+ self.level = 0
+ self.parent = None
+ self.context = ctx
+ self.verbose = verbose
+ self.descr = None
+ self.start = 0.0
+ self.delta = 1.0
+ self.context.window_manager.progress_begin(self.start, self.delta)
+
+ if self.verbose and self.descr:
+ d = self.descr
+ if self.obj:
+ d += " ({})".format(type(self.obj).__name__)
+ print("{} {}".format("ยท"*self.level, d))
+
+ self.slice_delta = 0.0
+ self.progress = self.start
+ self.child = None
+ self.context.window_manager.progress_update(self.progress)
+ self.last_progress_update = self.progress
+
+ def export(self, func, *args, **kwargs):
+ try:
+ func(self, *args, **kwargs)
+ except Exception as e:
+ tasks = []
+ c = self
+ while c:
+ tasks.append(c)
+ c = c.child
+ objs = [t.obj for t in tasks if t.obj]
+ raise ExportError(objs) from e
+
+ def task(self, task, end):
+ self.child = ExportContext(self, task, self.progress, self.start+end*self.delta-self.progress)
+ self.progress += self.child.delta
+ return self.child
+
+ def set_progress(self, progr):
+ self.progress = self.start+progr*self.delta
+ self.child = None
+ if self.progress>self.last_progress_update+0.001:
+ self.context.window_manager.progress_update(self.progress)
+ self.last_progress_update = self.progress
+
+ def set_slices(self, count):
+ if count>0:
+ self.slice_delta = self.delta/count
+ else:
+ self.slice_delta = 0.0
+
+ def next_slice(self, task):
+ self.child = ExportContext(self, task, self.progress, self.slice_delta)
+ self.progress += self.slice_delta
+ return self.child