File: engine_manager.py

package info (click to toggle)
mayavi2 4.8.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 21,892 kB
  • sloc: python: 49,447; javascript: 32,885; makefile: 129; fortran: 60
file content (206 lines) | stat: -rw-r--r-- 7,268 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
"""
Central registry for figures with mlab.
"""

# Standard library imports
import os
import warnings

# Enthought librairies imports
from traits.api import HasTraits, Instance

# Local imports
from mayavi.preferences.api import preference_manager
from mayavi.core.registry import registry
from mayavi.core.engine import Engine
from mayavi.core.off_screen_engine import OffScreenEngine
from mayavi.core.null_engine import NullEngine
from mayavi.core.common import process_ui_events
from .preferences_mirror import PreferencesMirror

# The mlab options.
options = PreferencesMirror()
options.preferences = preference_manager.mlab
env_toolkit = os.environ.get('ETS_TOOLKIT', '')


######################################################################
def check_backend():
    """ Check if either we are in test mode, or if there is a
        suitable traits backend installed.
    """
    from traitsui.toolkit import toolkit
    from traits.etsconfig.api import ETSConfig
    from mayavi.tools.engine_manager import options

    toolkit()  # This forces the selection of a toolkit.
    if (options.backend != 'test' and not options.offscreen) and \
       (ETSConfig.toolkit in ('null', '') and env_toolkit != 'null'):
        msg = '''Could not import backend for traitsui.  Make sure you
        have a suitable UI toolkit like PyQt/PySide or wxPython
        installed.'''
        raise ImportError(msg)


###############################################################################
# `EngineManager` class.
###############################################################################
class EngineManager(HasTraits):
    """ Central registry for figures with mlab.

        This is a container for a list of engines having declared
        themselves as usable by mlab.

        This object is meant to be a thin wrapper on top of the different
        Engine classes, making sure that mlab knows how to start an
        engine and get a figure.
    """

    current_engine = Instance(Engine)

    def get_engine(self):
        """ Returns an engine in agreement with the options.
        """

        # First check if the current engine is running and if it is in
        # the registered engines.
        ce = self.current_engine
        if ce is not None:
            if not ce.running or ce not in registry.engines.values():
                self.current_engine = None

        if self.current_engine is not None:
            engines = list((self.current_engine,))
        else:
            engines = list()
        engines.extend(list(registry.engines.values()))
        if options.backend == 'envisage':
            suitable = [e for e in engines
                        if e.__class__.__name__ == 'EnvisageEngine']
        elif options.backend == 'test':
            suitable = [e for e in engines
                        if e.__class__.__name__ == 'NullEngine']
        elif options.offscreen:
            suitable = [e for e in engines
                        if e.__class__.__name__ == 'OffScreenEngine']
        elif options.backend == 'auto':
            suitable = [e for e in engines
                        if e.__class__.__name__ not in ('NullEngine',
                                                        'OffScreenEngine')]
        else:
            suitable = [e for e in engines
                        if e.__class__.__name__ == 'Engine']
        if len(suitable) == 0:
            return self.new_engine()
        else:
            # Return the most engine add to the list most recently.
            self.current_engine = suitable[-1]
            return suitable[-1]

    def get_null_engine(self):
        """Return a suitable null engine and make that the current
        engine.
        """
        # First check if the current engine is running and if it is in
        # the registered engines.
        ce = self.current_engine
        if ce is not None:
            if not ce.running or ce not in registry.engines.values():
                self.current_engine = None

        if self.current_engine is not None:
            engines = list((self.current_engine,))
        else:
            engines = list()
        engines.extend(list(registry.engines.values()))
        engine = None
        for e in engines:
            if e.__class__.__name__ == 'NullEngine':
                engine = e
                break
        else:
            engine = NullEngine(name='Null Mlab Engine')
            engine.start()
        self.current_engine = engine
        return engine

    def set_engine(self, engine):
        """ Sets the mlab engine.
        """
        if not engine.running:
            warnings.warn('Engine is not running', stacklevel=2)
        self.current_engine = engine
        registry.register_engine(engine)

    def new_engine(self):
        """ Creates a new engine, envisage or not depending on the
            options.
        """
        check_backend()
        if options.backend == 'envisage':
            from mayavi.plugins.app import Mayavi
            m = Mayavi(start_gui_event_loop=False)
            m.main()
            process_ui_events()
            window = m.application.workbench.active_window
            engine = window.get_service(Engine)
        elif options.backend == 'test':
            engine = NullEngine(name='Null Mlab Engine')
            engine.start()
        else:
            if options.offscreen:
                engine = OffScreenEngine(name='Mlab offscreen Engine')
                engine.start()
            else:
                engine = Engine(name='Mlab Engine')
                engine.start()
        self.current_engine = engine
        return engine

    def find_figure_engine(self, fig):
        """ Find the engine corresponding to a given mayavi scene.
        """
        for engine in registry.engines.values():
            if fig in engine.scenes:
                return engine
        else:
            raise TypeError("Figure not attached to a mayavi engine.")

    def show_engine(self, engine=None, rich_view=True):
        """ Show a dialog with the mayavi pipeline. This dialog allows to
            edit graphically the properties of the different objects on
            the scenes.
        """
        if engine is None:
            engine = self.get_engine()
        if engine.__class__.__name__ == 'EnvisageEngine' or \
           options.backend == 'test':
            # FIXME: This should pop up the relevent envisage view
            pass
        elif rich_view:
            from mayavi.core.ui.engine_rich_view import \
                    EngineRichView
            figure = engine.current_scene
            view = EngineRichView(engine=engine)
            if figure is None:
                scene = None
            else:
                scene = figure.scene
            return view.scene_editing_view(scene=scene)
        else:
            from mayavi.core.ui.engine_view import \
                    EngineView
            scene = engine.current_scene
            view = EngineView(engine=engine)
            return view.edit_traits()


engine_manager = EngineManager()

get_engine = engine_manager.get_engine

get_null_engine = engine_manager.get_null_engine

set_engine = engine_manager.set_engine

show_pipeline = engine_manager.show_engine