source: trunk/src/testing/dim/sageData.py @ 4

Revision 4, 12.6 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1############################################################################
2#
3# DIM - A Direct Interaction Manager for SAGE
4# Copyright (C) 2007 Electronic Visualization Laboratory,
5# University of Illinois at Chicago
6#
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions are met:
11#
12#  * Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14#  * Redistributions in binary form must reproduce the above
15#    copyright notice, this list of conditions and the following disclaimer
16#    in the documentation and/or other materials provided with the distribution.
17#  * Neither the name of the University of Illinois at Chicago nor
18#    the names of its contributors may be used to endorse or promote
19#    products derived from this software without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32#
33# Direct questions, comments etc about SAGE UI to www.evl.uic.edu/cavern/forum
34#
35# Author: Ratko Jagodic
36#       
37############################################################################
38
39
40
41# python stuff
42import string, sys
43
44# my imports
45from sageApp import SageApp, SageAppInitial
46from sageDisplayInfo import SageDisplayInfo
47from globals import *
48import events
49
50
51## Main class to store all the messages returned by SAGE
52class SageData:
53
54
55    #### constructor initializes member values       
56    def __init__(self) :
57        self.hashApps = {}           # all the apps available for running??
58        self.hashAppStatusInfo = {}  # apps currently running
59        self.displayInfo = SageDisplayInfo()
60
61        self.sageGate = getSageGate()
62        self.sageGate.registerCallbackFunction(40000, self.setSageStatus)
63        self.sageGate.registerCallbackFunction(40001, self.setSageAppInfo)
64        #self.sageGate.registerCallbackFunction(40002, self.setSagePerfInfo)
65        self.sageGate.registerCallbackFunction(40003, self.sageAppShutDown)
66        self.sageGate.registerCallbackFunction(40004, self.setDisplayInfo)
67        self.sageGate.registerCallbackFunction(40005, self.setSageZValue)
68        self.sageGate.registerCallbackFunction(40006, self.setSageAppExecConfig)
69        self.sageGate.registerCallbackFunction(40007, self.setDisplayConnections)
70        self.sageGate.registerCallbackFunction(40018, self.setSageObjectInfo)
71
72
73    ### clears the current state (to be done when reconnecting)
74    def clear(self):
75        self.hashApps = {}           # all the apps available for running??
76        self.hashAppStatusInfo = {}
77       
78       
79    #### Set the sage status
80    def setSageStatus(self, appHash) : 
81        for appName, configs in appHash.iteritems():
82            self.hashApps[appName] = SageAppInitial(appName, configs)
83           
84
85    #----------------------------------------------------------------------
86
87
88    ### Set the possible execution configurations for each app
89    def setSageAppExecConfig(self, data):
90        tokens = string.split( data, '\n', 1 )
91        appName = tokens[0]
92        data = tokens[1] #the rest
93        configList = string.split( data, "config ")
94
95        del configList[0]  #remove the first item in the list
96
97        for config in configList:
98            if appName in self.hashApps.keys():
99                (name, stringConfig) = string.split(config, ":", 1)
100                self.hashApps[appName].AddConfig(name, stringConfig)
101
102
103    #----------------------------------------------------------------------
104 
105   
106    #### Set the SAGE display information
107    ####
108    def setDisplayInfo(self, data):
109        listTokens = string.split(data, '\n')
110
111        for i in range(0, len(listTokens), 3):
112            tileNumTokens = string.split(listTokens[i], ' ')
113            desktopTokens = string.split(listTokens[i+1], ' ')
114            tileConfTokens = string.split(listTokens[i+2], ' ')           
115           
116            # so that we can support the old sage as well
117            displayId = 0
118            if len(tileConfTokens) > 2:
119                displayId = int(tileConfTokens[2])
120
121            self.displayInfo.addDisplay(int(tileNumTokens[0]), int(tileNumTokens[1]), int(tileNumTokens[2]),
122                                   int(desktopTokens[0]), int(desktopTokens[1]),
123                                   int(tileConfTokens[0]), int(tileConfTokens[1]), displayId)
124
125        # for one display and old SAGE there are no connection messages so just
126        # pretend that one came in for drawing everything correctly
127        if self.displayInfo.getNumDisplays() == 1:
128            self.setDisplayConnections("")
129       
130
131    #----------------------------------------------------------------------
132   
133    # returns the SageDisplayInfo object
134    def getDisplayInfo(self, displayId=0):
135        return self.displayInfo.getDisplay(displayId)
136
137    #----------------------------------------------------------------------
138
139
140    def setDisplayConnections(self, data):
141        if data:
142            for connection in data.split('\n'):
143                tokens = connection.split()
144                displayId = int(tokens[2])
145                self.displayInfo.getDisplay(displayId).placement = int(tokens[1])
146
147        evt = events.DisplayInfoEvent(self.displayInfo)
148        getEvtMgr().postEvent(evt)
149
150
151    #----------------------------------------------------------------------
152   
153
154    #### Get the new list of z values from SAGE
155    #### and update local hashes, then call the function to update the UI visually
156    def setSageZValue(self, message):
157        tokens = string.split(message)
158        numZChanges = int(tokens[0])  #the first item that comes in is the number of z changes
159        zHash = {}   # key=appId, value=new z value
160       
161        # loop through all the tokens and update the z values of the apps
162        for i in range(numZChanges):
163            self.setZvalue( int(tokens[i*2+1]), int(tokens[i*2+2]) )
164            zHash[int(tokens[i*2+1])] = int(tokens[i*2+2])
165           
166        evt = events.ZChangeEvent(zHash)
167        getEvtMgr().postEvent(evt)
168
169
170    #----------------------------------------------------------------------
171
172   
173    #### Set the SAGE app status
174    #### prints Invalid app ID if does not exists
175    def setSageAppInfo(self, data):
176        listTokens = string.split(data)
177
178        # to support old sage as well
179        displayId = 0
180        orientation = 0
181        if len(listTokens) > 8:
182            orientation = int(listTokens[8])
183            displayId = int(listTokens[9])
184           
185
186        appId = int( listTokens[ 1 ] )
187        if appId in self.hashAppStatusInfo:
188            # update the app in the hash
189            self.hashAppStatusInfo[ appId ].setAll( listTokens[0], int(listTokens[1]),
190                   int(listTokens[2]), int(listTokens[3]), int(listTokens[4]), int(listTokens[5]),
191                   int(listTokens[6]), int(listTokens[7]), orientation, displayId)
192
193            # make the event
194            evt = events.AppInfoEvent(self.hashAppStatusInfo[appId])
195        else:
196            # when new app is started it is assigned a z=0 but since previous app on top had z=0,
197            # we set this one even higher temporarily (z=-1) so that it gets drawn on top
198            # the new z order message comes right after the app is started so this -1 is temporary
199            zValue = int(listTokens[7])
200            for app in self.hashAppStatusInfo.itervalues():
201                if app.getZvalue() == zValue:
202                    zValue = -1
203            self.hashAppStatusInfo[ appId ] = SageApp( listTokens[0], int(listTokens[1]),
204                   int(listTokens[2]), int(listTokens[3]), int(listTokens[4]), int(listTokens[5]),
205                   int(listTokens[6]), zValue, orientation, displayId)
206
207            # make the event
208            evt = events.NewAppEvent(self.hashAppStatusInfo[appId])
209
210        # post the event about the state change
211        getEvtMgr().postEvent(evt)
212
213
214    #----------------------------------------------------------------------
215   
216   
217    ##### ShutDown the sage application
218    ##### prints invalid app ID if doesn't exist
219    def sageAppShutDown(self, data):
220        listTokens = string.split(data)
221        appId = int(listTokens[0])
222
223        if appId in self.hashAppStatusInfo :
224            # do this first and then remove the app from the hash!!
225            # make and post the event
226            evt = events.AppKilledEvent(self.hashAppStatusInfo[appId])
227            getEvtMgr().postEvent(evt)
228
229            # delete the app
230            del self.hashAppStatusInfo[appId]
231
232
233    #----------------------------------------------------------------------
234
235
236    def setSageObjectInfo(self, data):
237        evt = events.ObjectInfoEvent(data)
238        getEvtMgr().postEvent(evt)
239       
240
241    #----------------------------------------------------------------------
242   
243   
244    #   Get the z value of the app
245    #   @arg appInstID App instance ID of the app
246    #   @return Returns Z value if appID exists else returns -1
247    def getZvalue(self, appId):
248        if appId in self.hashAppStatusInfo:
249            return self.hashAppStatusInfo[appId].getZvalue()
250        else:
251            print("getZvalue: Invalid app instance ID")
252            return
253
254           
255    #----------------------------------------------------------------------
256
257
258    #   Set the Z value of the app
259    #   @arg appInstId App instance ID of the app
260    #   @arg value New Z value to be set
261    def setZvalue(self, appId, value):
262        if (appId in self.hashAppStatusInfo):
263            self.hashAppStatusInfo[appId].setZvalue(value)
264        else:
265            print ('setZvalue: Invalid app instance ID')
266        return
267
268
269    #----------------------------------------------------------------------
270
271
272    # returns the SageApp associated with the given appInstId
273    def getApp(self, appInstId):
274        return self.hashAppStatusInfo[appInstId]
275   
276
277    #----------------------------------------------------------------------
278
279   
280    ### (RJ 2005-01-15)
281    ### Returns a list of all the available apps
282    def getAvailableApps( self ):
283        return self.hashApps
284
285    ### (AKS 2004-10-23)
286    ### Get all app IDs
287    ### currently running on sage
288    ### @return list of app ids
289    def getAllAppIDs(self) :
290        return self.hashAppStatusInfo.keys()
291
292
293    #----------------------------------------------------------------------
294
295   
296    ### Returns a hash of all running apps
297    def getRunningApps( self ):
298        return self.hashAppStatusInfo
299
300
301    #----------------------------------------------------------------------
302
303
304    # checks all the apps and reports whether any one of them was
305    # hit with a click and which region was hit (corners or shape in general)
306    # if more than one shape was hit it returns the one on the top
307    def checkHits(self, x, y):
308        zHash = {}  #key=z value, value=SageApp
309
310        try:
311            for appId, sageApp in self.hashAppStatusInfo.items():
312                zHash[sageApp.getZvalue()] = sageApp
313
314            zKeys = zHash.keys()
315            zKeys.sort()
316
317            for z in zKeys:
318                hitResult = zHash[z].hitTest(x,y)
319                if hitResult >= 0:
320                    return (zHash[z], hitResult)
321        except:
322            pass
323        return (None, -1)
324
325
326    #----------------------------------------------------------------------
327
328
329    # returns (appId, zValue) or (-1,sys.maxint) if no apps
330    def getTopApp(self):
331        minZ = (-1, sys.maxint)
332        try:
333            for appId, app in self.hashAppStatusInfo.items():
334                if app.getZvalue() < minZ[1]:
335                    minZ = (appId, app.getZvalue())
336        except:
337            pass
338        return minZ
339       
Note: See TracBrowser for help on using the repository browser.