aboutsummaryrefslogtreecommitdiff
path: root/boltzgas/visualizer.py
blob: 44cec7a284474541d8b1e94744a5a0a42c1723b4 (plain)
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
from OpenGL.GL import *
from OpenGL.GLUT import *

from boltzgas.visual import View

class SimulationController:
    def __init__(self, gas, instruments, updates_per_frame):
        self.running = False
        self.gas = gas
        self.instruments = instruments
        self.updates_per_frame = updates_per_frame

    def isRunning(self):
        return self.running

    def run(self):
        self.running = True

    def pause(self):
        self.running = False

    def evolve(self):
        if self.running:
            for i in range(0,self.updates_per_frame):
                self.gas.evolve()

            for instrument in self.instruments:
                instrument.update()

    def shutdown(self):
        self.pause()

        for instrument in self.instruments:
            try:
                instrument.shutdown()
            except AttributeError:
                return # Doesn't matter, shutdown is optional


def make_display_handler(controller, view):
    def on_display():
        controller.evolve()
        view.display()

    return on_display

def make_reshape_handler(view):
    def on_reshape(width, height):
        view.reshape(width, height)

    return on_reshape

def make_timer():
    def on_timer(t):
        glutTimerFunc(t, on_timer, t)
        glutPostRedisplay()

    return on_timer

def make_keyboard_handler(controller):
    def on_keyboard(key, x, y):
        if controller.isRunning():
            controller.pause()
        else:
            controller.run()

    return on_keyboard

def make_close_handler(controller):
    def on_close():
        controller.shutdown()

    return on_close

def simulate(config, gas, instruments, decorations, windows, updates_per_frame = 5):
    glutInit()
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowPosition(0, 0)
    glutCreateWindow("BoltzGas")

    gas.setup()
    for instrument in instruments:
        instrument.setup()

    view = View(gas, decorations, windows)
    controller = SimulationController(gas, instruments, updates_per_frame)

    glutDisplayFunc(make_display_handler(controller, view))
    glutReshapeFunc(make_reshape_handler(view))
    glutTimerFunc(20, make_timer(), 20)
    glutKeyboardFunc(make_keyboard_handler(controller))
    glutCloseFunc(make_close_handler(controller))

    glutMainLoop()