[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