[Bf-blender-cvs] [f9adc7f] asset-engine: Start to make Amber a bit more serious!
Bastien Montagne
noreply at git.blender.org
Fri Mar 13 22:28:02 CET 2015
Commit: f9adc7fbac6a8263730acd084db3efa302201b59
Author: Bastien Montagne
Date: Fri Mar 13 16:17:00 2015 +0100
Branches: asset-engine
https://developer.blender.org/rBf9adc7fbac6a8263730acd084db3efa302201b59
Start to make Amber a bit more serious!
Still useless - behaves more or less like a very basic, broken filebrowser.
But basics are here, and listing process seems to be working pretty well.
===================================================================
M release/scripts/startup/bl_operators/amber.py
===================================================================
diff --git a/release/scripts/startup/bl_operators/amber.py b/release/scripts/startup/bl_operators/amber.py
index c42c01d..2a564b7 100644
--- a/release/scripts/startup/bl_operators/amber.py
+++ b/release/scripts/startup/bl_operators/amber.py
@@ -32,41 +32,140 @@ from bpy.props import (
CollectionProperty,
)
+import concurrent.futures as futures
+import os
+import stat
+import time
+
+class AmberJob:
+ def __init__(self, executor, job_id):
+ self.executor = executor
+ self.job_id = job_id
+ self.status = {'VALID'}
+ self.progress = 0.0
+
+
+class AmberJobList(AmberJob):
+ @staticmethod
+ def ls(path):
+ ret = [".."] + os.listdir(path)
+ time.sleep(0.1) # 100% Artificial Lag (c)
+ return ret
+
+ @staticmethod
+ def stat(path):
+ st = os.lstat(path)
+ time.sleep(0.1) # 100% Artificial Lag (c)
+ return path, (stat.S_ISDIR(st.st_mode), st.st_size, st.st_mtime)
+
+ def start(self):
+ self.nbr = 0
+ self.tot = 0
+ self.ls_task = self.executor.submit(self.ls, self.root)
+ self.status = {'VALID', 'RUNNING'}
+
+ def update(self, entries, uuids):
+ if self.ls_task is not None:
+ if not self.ls_task.done():
+ return
+ paths = self.ls_task.result()
+ self.ls_task = None
+ self.tot = len(paths)
+ for p in paths:
+ self.stat_tasks.add(self.executor.submit(self.stat, self.root + p))
+ else:
+ done = set()
+ for tsk in self.stat_tasks:
+ if tsk.done():
+ path, (is_dir, size, timestamp) = tsk.result()
+ self.nbr += 1
+
+ entry = entries.entries.add()
+ entry.type = {'DIR'} if is_dir else {'BLENDER'} # TODO stupid!
+ entry.relpath = path
+ entry.uuid = entry.relpath.encode()[:8] + b"|" + bytes(self.nbr)
+ uuids[entry.uuid] = self.root + path
+ variant = entry.variants.add()
+ entry.variants.active = variant
+ rev = variant.revisions.add()
+ rev.size = size
+ rev.timestamp = timestamp
+ variant.revisions.active = rev
+
+ done.add(tsk)
+ self.stat_tasks -= done
+ self.progress = self.nbr / self.tot
+ if not self.stat_tasks and self.ls_task is None:
+ self.status = {'VALID'}
+
+ def __init__(self, executor, job_id, root):
+ super().__init__(executor, job_id)
+ self.root = root
+ self.entries = {}
+ self.ls_task = None
+ self.stat_tasks = set()
+
+ self.start()
+
+ def __del__(self):
+ # Avoid useless work!
+ if self.ls_task is not None:
+ self.ls_task.cancel()
+ for tsk in self.stat_tasks:
+ tsk.cancel()
+
+
class AssetEngineAmber(AssetEngine):
bl_label = "Amber"
def __init__(self):
+ self.executor = futures.ThreadPoolExecutor(8) # Using threads for now, if issues arise we'll switch to process.
self.jobs = {}
self.uuids = {}
+ self.job_uuid = 1
+
+ def __del__(self):
+ self.executor.shutdown(wait=False)
+
def status(self, job_id):
if job_id:
job = self.jobs.get(job_id, None)
- #~ if job is not None:
- #~ return {'VALID'}
- return set()
- else:
- return {'VALID'}
+ return job.status if job is not None else set()
+ return {'VALID'}
def progress(self, job_id):
- return 0.5
+ if job_id:
+ job = self.jobs.get(job_id, None)
+ return job.progress if job is not None else 0.0
+ progress = 0.0
+ nbr_jobs = 0
+ for job in self.jobs.values():
+ if 'RUNNING' in job.status:
+ nbr_jobs += 1
+ progress += job.progress
+ return progress / nbr_jobs if nbr_jobs else 0.0
def kill(self, job_id):
- pass
+ if job_id:
+ self.jobs.pop(job_id, None)
+ return
+ for job in self.jobs.values():
+ job.kill()
def list_dir(self, job_id, entries):
- if len(entries.entries) == 0:
- entry = entries.entries.add()
- entry.type = {'BLENDER'}
- entry.relpath = "foobar.blend"
- entry.name = "MyLittleTest"
- entry.uuid = entry.relpath.encode()[:8] + b"|0000000001"
- self.uuids[entry.uuid] = "/home/i74700deb64/Téléchargements/wall_UE_D_01.blend"
- variant = entry.variants.add()
- entry.variants.active = variant
- rev = variant.revisions.add()
- variant.revisions.active = rev
- return 1
+ job = self.jobs.get(job_id, None)
+ if job is not None and isinstance(job, AmberJobList):
+ print(job.root, entries.root_path)
+ if job.root != entries.root_path:
+ self.jobs[job_id] = AmberJobList(self.executor, job_id, entries.root_path)
+ else:
+ job.update(entries, self.uuids)
+ else:
+ self.job_uuid += 1
+ job_id = self.job_uuid
+ self.jobs[job_id] = AmberJobList(self.executor, job_id, entries.root_path)
+ return job_id
def load_pre(self, uuids, entries):
# Not quite sure this engine will need it in the end, but for sake of testing...
More information about the Bf-blender-cvs
mailing list