The Assimilation Project  based on Assimilation version 1.1.7.1474836767
assimglib.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # vim: smartindent tabstop=4 shiftwidth=4 expandtab number colorcolumn=100
3 #
4 # This file is part of the Assimilation Project.
5 #
6 # Author: Alan Robertson <alanr@unix.sh>
7 # Copyright (C) 2014 - Assimilation Systems Limited
8 #
9 # Free support is available from the Assimilation Project community - http://assimproj.org
10 # Paid support is available from Assimilation Systems Limited - http://assimilationsystems.com
11 #
12 # The Assimilation software is free software: you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation, either version 3 of the License, or
15 # (at your option) any later version.
16 #
17 # The Assimilation software is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with the Assimilation Project software. If not, see http://www.gnu.org/licenses/
24 #
25 #
26 '''
27 This file provides wrapper functions for some glib mainloop-related classes that we need to know
28 about. It is somewhat compatible with the GObject introspection libraries for the same code.
29 The advantage we have is that we don't need that code which can be complicated to get in a
30 particular environment - since it involved both Python code and C code.
31 This is easy for us to do since we are using ctypes and ctypesgen anyway.
32 '''
33 
34 from ctypes import py_object, POINTER, CFUNCTYPE
35 from AssimCtypes import \
36  G_IO_IN, G_IO_PRI, G_IO_ERR, G_IO_OUT, G_IO_HUP, \
37  g_main_loop_new, g_main_loop_run, g_main_loop_quit, g_main_context_default, \
38  assim_set_io_watch, g_source_remove, g_timeout_add, \
39  guint, gboolean, GIOChannel, GIOCondition, GIOFunc, GSourceFunc, UNCHECKED, g_main_loop_unref
40 
41 IO_IN = G_IO_IN
42 IO_PRI = G_IO_PRI
43 IO_ERR = G_IO_ERR
44 IO_OUT = G_IO_OUT
45 IO_HUP = G_IO_HUP
46 
47 
48 class MainLoop(object):
49  '''
50  This class encapsulates the glib mainloop paradigm.
51  '''
52  default = None
53  def __init__(self):
54  'Create a default mainloop object'
55  self.mainloop = g_main_loop_new(g_main_context_default(), True)
56  MainLoop.default = self
57 
58  def run(self):
59  'Run this mainloop until quit is called on it'
60  g_main_loop_run(self.mainloop)
61 
62  def quit(self):
63  'Stop this mainloop - causing run() call to return'
64  g_main_loop_quit(self.mainloop)
65 
66  def __del__(self):
67  self.quit()
68  g_main_loop_unref(self.mainloop)
69 
70 # Ctypesgen gets these wrong from our perspective...
71 # For our purposes, the last argument needs to be py_object instead of gpointer
72 GIOFunc = CFUNCTYPE(UNCHECKED(gboolean), POINTER(GIOChannel), guint, py_object)
73 GSourceFunc = CFUNCTYPE(UNCHECKED(gboolean), py_object)
74 
75 assim_set_io_watch.argtypes = [guint, GIOCondition, GIOFunc, py_object]
76 g_timeout_add.argtypes = [guint, GSourceFunc, py_object]
77 
78 
79 
80 # We don't need any additional public methods (pylint complaint)
81 # pylint: disable=R0903
82 class IOWatch(object):
83  'This class encapsulates an I/O source based on the Glib g_io_add_watch'
84  save_callbacks = []
85  def __init__(self, fileno, conditions, callback, otherobj=None):
86  '''
87  fileno is the UNIX file descriptor
88  Conditions is a bitwise-OR of at least one of {IO_IN, IO_PRI, IO_ERR, IO_OUT, IO_HUP}
89  The callback function receives three parameters:
90  source
91  calledcondition
92  otherobj (as passed to io_add_watch)
93  and returns a bool - True if we should keep watching this file descriptor, False if not.
94 
95  Return: int (source id of our watch condition - suitable to passing to source_remove)
96 
97  Note that you must keep a reference around to the return result or the callback may crash
98  if the elements of this object get garbage collected.
99  '''
100  self.callback = GIOFunc(callback)
101  IOWatch.save_callbacks.append(self.callback)
102  self.sourceid = assim_set_io_watch(fileno, conditions, self.callback, otherobj)
103  #print >> sys.stderr, ('io_add_watch: (src=%s/%s, obj=%s/%s)' % \
104  # (callback, cb, otherobj, obj))
105  #print >> sys.stderr, ('io_add_watch: Returning %s' % str(retval))
106 
107  def __del__(self):
108  g_source_remove(self.sourceid)
109 
110 
111 # We don't need any additional public methods (pylint complaint)
112 # pylint: disable=R0903
113 class GMainTimeout(object):
114  'This class encapsulates an timeout source based on the Glib g_timeout_add'
115  save_callbacks = []
116  def __init__ (self, interval, callback, otherobj=None):
117  '''
118  Call a callback function at the (repeating) interval given
119  '''
120  self.callback = GSourceFunc(callback)
121  self.sourceid = g_timeout_add(interval, self.callback, otherobj)
122  GMainTimeout.save_callbacks.append(self.callback)
123 
124  def __del__(self):
125  g_source_remove(self.sourceid)
def __init__(self, interval, callback, otherobj=None)
Definition: assimglib.py:116
WINEXPORT guint assim_set_io_watch(int fd, GIOCondition condition, GIOFunc func, gpointer user_data)
Simiplified interface to g_io_add_watch for our Python code.
Definition: misc.c:765
def __init__(self, fileno, conditions, callback, otherobj=None)
Definition: assimglib.py:85