From b45b9079c5decd720d8275378bb0d6dc172c6234 Mon Sep 17 00:00:00 2001 From: rcoh Date: Wed, 9 Feb 2011 12:14:27 -0500 Subject: Early stages of support for interbehavior interactions. Fixed a bug in the config eval and added some new tests. --- Profile.py | 2 +- operationscore/Behavior.py | 8 +++++--- operationscore/Input.py | 2 +- tests/TestConfigLoaders.py | 7 +++++++ util/Config.py | 13 ++++++++----- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Profile.py b/Profile.py index a1eb581..40c2d0a 100644 --- a/Profile.py +++ b/Profile.py @@ -1,4 +1,4 @@ import cProfile from LightInstallation import main -command = """main(['', 'config/Demo.xml'])""" +command = """main(['', 'config/FireflyDemo.xml'])""" cProfile.runctx(command, globals(), locals(), filename="smootlight.profile") diff --git a/operationscore/Behavior.py b/operationscore/Behavior.py index 6424842..97fa020 100644 --- a/operationscore/Behavior.py +++ b/operationscore/Behavior.py @@ -1,9 +1,6 @@ - import pdb from operationscore.SmootCoreObject import * from logger import main_log -#timeStep is called on every iteration of the LightInstallation -#addInput is called on each individual input received, and the inputs queue class Behavior(SmootCoreObject): """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 @@ -44,6 +41,11 @@ class Behavior(SmootCoreObject): else: self.addInput(sensorInputs) #private + def getLastOutput(self): + return self.lastState + def setLastOutput(self, output): + """Override to modify state.""" + self.lastState = output def addMapperToResponse(self, responses): if self['Mapper'] != None: if type(responses) == type(tuple): diff --git a/operationscore/Input.py b/operationscore/Input.py index d3d5644..5a835ec 100644 --- a/operationscore/Input.py +++ b/operationscore/Input.py @@ -17,7 +17,7 @@ class Input(ThreadedSmootCoreObject): self.inputInit() def respond(self, eventDict): - #if eventDict != []: + eventDict['InputId'] = self['Id'] self.parentScope.lock.acquire() self.parentScope.processResponse(self.argDict, eventDict) self.parentScope.lock.release() diff --git a/tests/TestConfigLoaders.py b/tests/TestConfigLoaders.py index c7e2b7a..02c8865 100644 --- a/tests/TestConfigLoaders.py +++ b/tests/TestConfigLoaders.py @@ -37,5 +37,12 @@ class TestConfigLoaders(unittest.TestCase): assert singleLayerLambda({'Val':2}) == 10 doubleLayerLambda = Config.attemptEval("${Val1}$*'${Val2}$'") assert doubleLayerLambda({'Val1':3})({'Val2':7}) == 21 + + conditional = Config.attemptEval("${Val1}$*5=='${Val2}$'") + assert conditional({'Val1':5})({'Val2':25}) == True + assert conditional({'Val1':5})({'Val2':26}) == False + + onlyDouble = Config.attemptEval("'${Val1}$'*'${Val2}$'") + assert onlyDouble({})({'Val1':3, 'Val2':7}) == 21 if __name__ == '__main__': unittest.main() diff --git a/util/Config.py b/util/Config.py index 4153313..25018a8 100644 --- a/util/Config.py +++ b/util/Config.py @@ -113,17 +113,20 @@ def pullArgsFromItem(parentNode): return args def attemptEval(val): + """Runs an eval if possible, or converts into a lambda expression if indicated. Otherwise, + leaves as a string.""" try: if '${' in val and '}$' in val: #TODO: this could be a little cleaner - dictVal = re.sub("'\$\{(.+)\}\$'", "b['\\1']", val) #replace all expressions like {blah} with a['blah'] - dictVal = re.sub("\$\{(.+)\}\$", "a['\\1']", dictVal) #replace all expressions like {blah} with a['blah'] + dictVal = re.sub("'\$\{(.+?)\}\$'", "b['\\1']", val) #replace expressions '${blah}$' with b['blah'] + dictVal = re.sub("\$\{(.+?)\}\$", "a['\\1']", dictVal) #replace all expressions like {blah} with a['blah'] if "'${" and "}$'" in val: #nested lambda madness lambdaVal = eval('lambda a: lambda b: ' + dictVal) else: lambdaVal = eval('lambda a:'+dictVal) #TODO: nested lambdas - return lambdaVal #convert referential objects to lambda expressions which resolve - #dynamically - val = eval(val) + return lambdaVal #convert referential objects to lambda expressions which can be + #resolved dynamically. + else: + val = eval(val) except (NameError, SyntaxError): val = str(val) return val -- cgit v1.2.3