Commits

ZyX_I committed f0bb9a8

@%aurum/repo: Started working on asynchronous repeatedly run commands support

  • Participants
  • Parent commits 3fb846d

Comments (0)

Files changed (4)

aurum-addon-info.txt

         "plugin/aurum/cache.vim",
         "python/aurum/__init__.py",
         "python/aurum/aumercurial.py",
+        "python/aurum/repeatedcmd.py",
         "python/aurum/utils.py",
         "ruby/aurum-command-t-rubyinit.rb",
         "ruby/command-t/aurum_controller.rb",

autoload/aurum/repo.vim

 "▶1
-execute frawor#Setup('5.3', {'@/resources': '0.0',
+execute frawor#Setup('5.4', {'@/resources': '0.0',
             \                       '@/os': '0.0',
             \                  '@/options': '0.0',
             \          '@%aurum/lineutils': '0.0',
 function s:deffuncs.checkremote(...)
     return 0
 endfunction
+"▶1 aget :: _, rcid + python -> ?
+let s:userepeatedcmd=0
+if has('python') && exists('*pyeval')
+    try
+        python import aurum.repeatedcmd
+        let s:userepeatedcmd=1
+    catch
+    endtry
+endif
+if s:userepeatedcmd
+    function s:deffuncs.aget(repo, rcid)
+        return pyeval('aurum.repeatedcmd.get(vim.bindeval("a:rcid"))')
+    endfunction
+    function s:deffuncs.aremove(repo, rcid)
+        return pyeval('aurum.repeatedcmd.remove(vim.bindeval("a:rcid"))')
+    endfunction
+endif
 "▶1 iterfuncs: cs generators
 " startfunc (here)  :: repo, opts → d
 "▶2 ancestors
 "▶1 regdriver feature
 let s:requiredfuncs=['repo', 'getcs', 'checkdir']
 let s:optfuncs=['readfile', 'annotate', 'diff', 'status', 'commit', 'update',
-            \   'dirty', 'diffre', 'getrepoprop', 'forget', 'branch', 'label',
-            \   'push', 'pull']
+            \   'diffre', 'getrepoprop', 'forget', 'branch', 'label',
+            \   'push', 'pull', 'astatus', 'agetcs', 'agetrepoprop', 'aget',
+            \   'aremove']
 "▶2 regdriver :: {f}, name, funcs → + s:drivers
 function s:F.regdriver(plugdict, fdict, name, funcs)
     "▶3 Check arguments
         function s:driver.getroot(path)
             return a:path
         endfunction
+<                                                           *aurum-rf-astatus*
+  astatus :: interval, [hex[, hex[, [ file ][, clean[, ign]]]]] -> rcid
+  agetcs :: interval, rev -> rcid                            *aurum-rf-agetcs*
+  agetrepoprop :: interval, propname -> rcid           *aurum-rf-agetrepoprop*
+    Register asyncronous repeated every {interval} seconds |aurum-rf-status|, 
+    |aurum-rf-getcs| or |aurum-rf-getrepoprop| calls (really their pure python 
+    replacements). Return an ID. Use |aurum-rf-aget| to get actual aurum-rf-* 
+    output. All currently existing implementations require python-2* with 
+    working threading module.
+  aget :: rcid -> ?                                            *aurum-rf-aget*
+    Output current value of repeatedly run function.
+  aremove :: rcid                                           *aurum-rf-aremove*
+    Stop repeating functions.
 
 ------------------------------------------------------------------------------
 8.2. Changeset                                               *aurum-changeset*

python/aurum/repeatedcmd.py

+from multiprocessing import Process, Queue, Value
+from aurum.utils import readsystem
+import time
+
+class ProcessHaltedError(Exception):
+    pass
+
+class RepeatedCmd(object):
+    __slots__ = set(('interval', 'func', 'timer', 'value'))
+    def __init__(self, interval, func, *args, **kwargs):
+        self.interval = Value('f', float(interval))
+        self.queue    = Queue()
+        self.func     = func
+        def procfunc(queue, interval, func, args, kwargs):
+            while True:
+                value = func(*args, **kwargs)
+                while(not queue.empty()):
+                    queue.get()
+                queue.put(value)
+                time.sleep(interval.value)
+        self.process  = Process(target=procfunc,
+                                args=(self.queue, self.interval, func, args, kwargs))
+        self.process.start()
+        self.value = None
+
+    def setinterval(self, interval):
+        if not self.process.is_alive():
+            raise ProcessHaltedError('Child process is not alive')
+        self.interval.value = float(interval)
+
+    def getvalue(self):
+        if not self.process.is_alive():
+            raise ProcessHaltedError('Child process is not alive')
+        if self.value is None or not self.queue.empty():
+            while(not self.queue.empty()):
+                self.value = self.queue.get()
+        return self.value
+
+    def getcurrentvalue(self):
+        self.value = self.func()
+        return self.value
+
+    def stop(self):
+        if not self.process.is_alive():
+            raise ProcessHaltedError('Child process is not alive')
+        self.process.terminate()
+
+    __del__ = stop
+
+processes={}
+
+thcount=0
+
+def new(*args, **kwargs):
+    global thcount
+    global processes
+    rcid=thcount
+    thcount+=1
+    processes[rcid]=RepeatedCmd(*args, **kwargs)
+    return rcid
+
+def get(rcid):
+    global processes
+    return processes[rcid].getvalue()
+
+def remove(rcid):
+    global processes
+    thread=processes.pop(rcid)
+    thread.stop()