aboutsummaryrefslogtreecommitdiff
path: root/operationscore
diff options
context:
space:
mode:
authorGravatar Russell Cohen <rcoh@mit.edu>2010-11-24 01:09:12 -0500
committerGravatar Russell Cohen <rcoh@mit.edu>2010-11-24 01:09:12 -0500
commitb042647b68abdc82490ca6e059993b8eba28904c (patch)
treea9ee95a38e98b377c251b7b2e9af9cbd8056cf7c /operationscore
parent407ac922fc4178021cf3a16dfb1bd875b6083ac4 (diff)
Refactoring complete! Made modules/packages as appropriate. Finally.
Diffstat (limited to 'operationscore')
-rw-r--r--operationscore/Behavior.py33
-rw-r--r--operationscore/Input.py46
-rw-r--r--operationscore/LayoutEngine.py30
-rw-r--r--operationscore/PixelEvent.py13
-rw-r--r--operationscore/Renderer.py12
-rw-r--r--operationscore/SmootCoreObject.py23
-rw-r--r--operationscore/__init__.py0
7 files changed, 157 insertions, 0 deletions
diff --git a/operationscore/Behavior.py b/operationscore/Behavior.py
new file mode 100644
index 0000000..f29430f
--- /dev/null
+++ b/operationscore/Behavior.py
@@ -0,0 +1,33 @@
+#Abstract class for a behavior. On every time step, the behavior is passed the
+#inputs from all sensors it is bound to as well as any recursive inputs that it
+#spawned during the last time step. Inheriting classes MUST define
+#processResponse. processResponse should return a list of dictionaries which
+#define the properties of the light response. They must give a location and
+#color. They may define a function pointer which defines a custom mapping.
+#[More on this later. Bug Russell if you want to do it].
+#recursiveResponse to queue a input on the next iteration with a dictionary
+#argument. This will be passed in via recursive inputs.
+import pdb
+from operationscore.SmootCoreObject import *
+#timeStep is called on every iteration of the LightInstallation
+#addInput is called on each individual input received, and the inputs queue
+class Behavior(SmootCoreObject):
+ def init(self):
+ self.validateArgs('Behavior.params')
+ if type(self['Inputs']) != type([]):
+ self['Inputs'] = [self['Inputs']]
+ self.recursiveResponseQueue = []
+ self.sensorResponseQueue = []
+ self.outGoingQueue = []
+ def processResponse(self, sensorInputs, recursiveInputs):
+ pass
+ def addInput(self, sensorInputs):
+ self.sensorResponseQueue.append(sensorInputs)
+ def recursiveReponse(self, args):
+ self.responseQueue.append(args)
+ def timeStep(self):
+ responses = self.processResponse(self.sensorResponseQueue, \
+ self.recursiveResponseQueue)
+ self.sensorResponseQueue = []
+ self.recursiveResponseQueue = []
+ return responses
diff --git a/operationscore/Input.py b/operationscore/Input.py
new file mode 100644
index 0000000..1ba4528
--- /dev/null
+++ b/operationscore/Input.py
@@ -0,0 +1,46 @@
+import threading,time,Util
+#Abstract class for inputs. Inheriting classes should call "respond" to raise
+#their event. Inheriting classes MUST define sensingLoop. Called at the
+#interval specified in RefreshInterval while the input is active. For example, if you are writing
+#webserver, this is where the loop should go.
+#Inheriting classes MAY define inputInit. This is called before the loop
+#begins.
+import pdb
+class Input(threading.Thread):
+ #Event scope is a function pointer the function that will get called when
+ #an Parent is raised.
+ def __init__(self, argDict):
+ self.eventQueue = []
+ self.parentScope = argDict['parentScope']
+ self.argDict = argDict
+ if not 'InputId' in argDict:
+ raise Exception('InputId must be defined in config xml')
+ if not 'RefreshInterval' in argDict:
+ print 'RefreshInterval not defined. Defaulting to .5s.'
+ self.argDict['RefreshInterval'] = 500
+ self.inputInit()
+ threading.Thread.__init__(self)
+ self.daemon = True #This kills this thread when the main thread stops
+ def respond(self, eventDict):
+ #if eventDict != []:
+ #pdb.set_trace()
+ self.parentScope.processResponse(self.argDict, eventDict)
+ def newEvent(self, event): #Mostly just useful for grabbing events from the
+ #computer running the sim (key presses, clicks etc.)
+ self.eventQueue.append(event)
+ def parentAlive(self):
+ try:
+ parentAlive = self.parentScope.alive()
+ return parentAlive
+ except:
+ return False
+ def run(self):
+ while self.parentAlive():
+ time.sleep(self.argDict['RefreshInterval']/float(1000))
+ self.sensingLoop()
+ def sensingLoop(self):
+ pass
+ def inputInit(self):
+ pass
+
+
diff --git a/operationscore/LayoutEngine.py b/operationscore/LayoutEngine.py
new file mode 100644
index 0000000..700b554
--- /dev/null
+++ b/operationscore/LayoutEngine.py
@@ -0,0 +1,30 @@
+from operationscore.SmootCoreObject import *
+import Util
+import pdb
+class LayoutEngine(SmootCoreObject):
+ def init(self):
+ self.validateArgs('LayoutEngine.params')
+ self.initLayout()
+ def layoutFunc(self, lastLocation): #Must be defined by inheriting class.
+ #Returns tuple pair (x,y)
+ pass
+ def getPixelLocations(self): #returns a complete list of locations of Pixels
+ #for a strip
+ locations = [self.argDict['originLocation']]
+ for pixelIndex in range(self['numPixels']-1): #-1 because origin
+ #already exists
+ newLocation = self.layoutFunc(locations[-1])
+ if newLocation == None:
+ raise Exception('Location cannot be null. layoutFunc not \
+ defined or improperly defined.')
+ if Util.dist(newLocation, locations[-1]) > \
+ self['pixelToPixelSpacing']:
+ raise Exception('Illegal pixel location. Distance \
+ between adjacent pixels must be less than \
+ pixelToPixelSpacing.')
+ locations.append(newLocation)
+ return locations
+ def initLayout(self):
+ pass
+ def getStripArgs(self): #TODO: triage and remove
+ return self.argDict
diff --git a/operationscore/PixelEvent.py b/operationscore/PixelEvent.py
new file mode 100644
index 0000000..07669cd
--- /dev/null
+++ b/operationscore/PixelEvent.py
@@ -0,0 +1,13 @@
+#Class defining a light response. Inheriting classes should define lightState,
+#which should return a color, or None if the response is complete. Consider
+#requiring a generate event.
+from operationscore.SmootCoreObject import *
+class PixelEvent(SmootCoreObject):
+ def init(self):
+ self.validateArgs('PixelEvent.params')
+ self.initEvent()
+ def initEvent(self):
+ pass
+ def state(self,timeDelay):
+ pass
+
diff --git a/operationscore/Renderer.py b/operationscore/Renderer.py
new file mode 100644
index 0000000..11fd8ca
--- /dev/null
+++ b/operationscore/Renderer.py
@@ -0,0 +1,12 @@
+#Renderer abstract class. Doesn't do much now, but might do more later.
+#Inheriting classes MUST define render which takes a light system and renders it.
+#Inheriting classes may define initRenderer which is called after the dictionary
+#is pulled from config.
+from operationscore.SmootCoreObject import *
+class Renderer(SmootCoreObject):
+ def init(self):
+ self.initRenderer()
+ def render(lightSystem):
+ pass
+ def initRenderer(self):
+ pass
diff --git a/operationscore/SmootCoreObject.py b/operationscore/SmootCoreObject.py
new file mode 100644
index 0000000..2901ef6
--- /dev/null
+++ b/operationscore/SmootCoreObject.py
@@ -0,0 +1,23 @@
+import Util
+import pdb
+class SmootCoreObject:
+ def __init__(self, argDict):
+ self.argDict = argDict
+ self.init() #call init of inheriting class
+ def init(self):
+ pass
+ def __setitem__(self,k, item):
+ self.argDict[k] = item
+ def __getitem__(self, item):
+ if item in self.argDict:
+ return self.argDict[item]
+ else:
+ return None
+ def __getiter__(self):
+ return self.argDict.__getiter__()
+ def validateArgs(self, argFileName):
+ self.validateArgDict(Util.loadParamRequirementDict(argFileName))
+ def validateArgDict(self, validationDict):
+ for item in validationDict:
+ if not item in self.argDict:
+ raise Exception(validationDict[item])
diff --git a/operationscore/__init__.py b/operationscore/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/operationscore/__init__.py