~ubuntu-branches/ubuntu/raring/fyre/raring

« back to all changes in this revision

Viewing changes to contrib/fyre_remote.py

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Haas
  • Date: 2005-05-25 21:59:19 UTC
  • Revision ID: james.westby@ubuntu.com-20050525215919-jawtso5ic23qb401
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
#
 
3
# This is an example Python module for controlling Fyre
 
4
# in remote control mode. Run it for a quick demonstration,
 
5
# or import it in your own scripts.
 
6
#
 
7
 
 
8
import socket
 
9
 
 
10
RESPONSE_READY        = 220
 
11
RESPONSE_OK           = 250
 
12
RESPONSE_PROGRESS     = 251
 
13
RESPONSE_FALSE        = 252
 
14
RESPONSE_BINARY       = 380
 
15
RESPONSE_UNRECOGNIZED = 500
 
16
RESPONSE_BAD_VALUE    = 501
 
17
RESPONSE_UNSUPPORTED  = 502
 
18
 
 
19
 
 
20
class FyreException(Exception):
 
21
    def __init__(self, code, message, command=None):
 
22
        msg = "%d %s" % (code, message)
 
23
        if command:
 
24
            msg = "%s (in response to %r" % (msg, command)
 
25
        Exception.__init__(self, msg)
 
26
 
 
27
 
 
28
class FyreServer:
 
29
    """This class represents a socket connection to
 
30
       a remote Fyre server (fyre -r)
 
31
       """
 
32
    defaultPort = 7931
 
33
 
 
34
    def __init__(self, host):
 
35
        if host.find(":") >= 0:
 
36
            host, port = host.split(":")
 
37
            port = int(port)
 
38
        else:
 
39
            port = self.defaultPort
 
40
 
 
41
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
42
        self.socket.connect((host, port))
 
43
        self.file = self.socket.makefile()
 
44
        self.asyncQueue = []
 
45
 
 
46
        # Read the server's greeting
 
47
        code, message = self._readResponse()
 
48
        if code != RESPONSE_READY:
 
49
            raise FyreException(code, message)
 
50
 
 
51
    def flush(self):
 
52
        """Send all pending asynchronous commands. If any
 
53
           of them returned an error, this raises an
 
54
           exception indicating which command resulted
 
55
           in which response code.
 
56
           """
 
57
        self.file.flush()
 
58
        for command in self.asyncQueue:
 
59
            code, message = self._readResponse()
 
60
            if code < 200 or code >= 300:
 
61
                raise FyreException(code, message, command)
 
62
        self.asyncQueue = []
 
63
 
 
64
    def _readResponse(self):
 
65
        """Read the server's next response, returning
 
66
           a (response_code, message) tuple.
 
67
           """
 
68
        line = self.file.readline().strip()
 
69
        code, message = line.split(" ", 1)
 
70
        return int(code), message
 
71
 
 
72
    def command(self, *tokens):
 
73
        """Send a command in which the return value doesn't
 
74
           matter except for detecting errors. This command
 
75
           will be buffered, and any errors won't be detected
 
76
           until the next flush().
 
77
           """
 
78
        cmd = " ".join(map(str, tokens))
 
79
        self.file.write(cmd + "\n")
 
80
        self.asyncQueue.append(cmd)
 
81
 
 
82
    def query(self, *tokens):
 
83
        """Immediately send a command in which we care about
 
84
           the response value. This forces a flush() first,
 
85
           so errors from other commands may be first discovered
 
86
           here. Returns a (response_code, message) tuple.
 
87
           """
 
88
        self.flush()
 
89
        cmd = " ".join(map(str, tokens))
 
90
        self.file.write(cmd + "\n")
 
91
        self.file.flush()
 
92
        return self._readResponse()
 
93
 
 
94
    def setParams(self, **kwargs):
 
95
        """Set any number of parameters, given as keyword arguments.
 
96
           Like command(), these will not take effect until the next
 
97
           flush().
 
98
           """
 
99
        for item in kwargs.iteritems():
 
100
            self.command("set_param", "%s=%s" % item)
 
101
 
 
102
 
 
103
if __name__ == "__main__":
 
104
    # A simple demo...
 
105
    # This connects to the Fyre server, sets up a bunch of image
 
106
    # parameters, (copied straight out of a saved .png file) then
 
107
    # varies some of the parameters to create a simple animation.
 
108
    # This could be extended into a more complex animation, maybe
 
109
    # even one based on sensors or a simulation.
 
110
 
 
111
    import math, sys
 
112
 
 
113
    if len(sys.argv) > 1:
 
114
        host = sys.argv[1]
 
115
    else:
 
116
        host = "localhost"
 
117
 
 
118
    fyre = FyreServer(host)
 
119
    fyre.command("set_render_time", 0.02)
 
120
    fyre.setParams(size = "400x300",
 
121
                   exposure = 0.030000,
 
122
                   zoom = 0.8,
 
123
                   gamma = 1.010000,
 
124
                   a = 4.394958,
 
125
                   b = 1.028872,
 
126
                   c = 1.698752,
 
127
                   d = 3.954149,
 
128
                   xoffset = 0.308333,
 
129
                   yoffset = 0.058333,
 
130
                   emphasize_transient = 1,
 
131
                   transient_iterations = 3,
 
132
                   initial_conditions = "circular_uniform",
 
133
                   initial_xscale = 0.824000,
 
134
                   initial_yscale = 0.018000)
 
135
    fyre.command("set_gui_style", "simple")
 
136
 
 
137
    t = 0
 
138
    while 1:
 
139
        fyre.setParams(initial_xoffset = t * 1.5,
 
140
                       initial_yoffset = math.sin(t) * 0.1)
 
141
        fyre.command("calc_step")
 
142
        fyre.flush()
 
143
        t += 0.1
 
144
 
 
145
### The End ###
 
146