From 7f272fd0b8ab96f5a9511dd2493f1414b2c03678 Mon Sep 17 00:00:00 2001 From: Matthew Barth Date: Tue, 12 Sep 2017 16:16:56 -0500 Subject: Set speed event parser updates Added some optimizations in the event yaml format to nest set speed events that have the same preconditions and allow multiple actions to be taken within a single set speed event. Change-Id: I21ec395b6c9686e1efd5abc1be48d563480fec5f Signed-off-by: Matthew Barth --- control/gen-fan-zone-defs.py | 345 +++++++++++++++++++++++++------------------ 1 file changed, 202 insertions(+), 143 deletions(-) (limited to 'control/gen-fan-zone-defs.py') diff --git a/control/gen-fan-zone-defs.py b/control/gen-fan-zone-defs.py index a2a49a8..a95920b 100755 --- a/control/gen-fan-zone-defs.py +++ b/control/gen-fan-zone-defs.py @@ -11,7 +11,70 @@ import yaml from argparse import ArgumentParser from mako.template import Template -tmpl = '''/* This is a generated file. */ +tmpl = ''' +<%! +def indent(str, depth): + return ''.join(4*' '*depth+line for line in str.splitlines(True)) +%> +<%def name="genSSE(event)" buffered="True"> +Group{ +%for member in event['group']: +{ + "${member['name']}", + {"${member['interface']}", + "${member['property']}"} +}, +%endfor +}, +std::vector{ +%for a in event['action']: +make_action(action::${a['name']}( +%for i, p in enumerate(a['parameters']): +%if (i+1) != len(a['parameters']): + static_cast<${p['type']}>(${p['value']}), +%else: + static_cast<${p['type']}>(${p['value']}) +%endif +%endfor +)), +%endfor +}, +Timer{ + ${event['timer']['interval']} +}, +std::vector{ +%for s in event['signal']: + PropertyChange{ + interfacesAdded("${s['obj_path']}"), + make_handler(objectSignal<${s['type']}>( + "${s['path']}", + "${s['interface']}", + "${s['property']}", + handler::setProperty<${s['type']}>( + "${s['path']}", + "${s['interface']}", + "${s['property']}" + ) + )) + }, + PropertyChange{ + propertiesChanged( + "${s['path']}", + "${s['interface']}"), + make_handler(propertySignal<${s['type']}>( + "${s['interface']}", + "${s['property']}", + handler::setProperty<${s['type']}>( + "${s['path']}", + "${s['interface']}", + "${s['property']}" + ) + )) + }, +%endfor +} + +/* This is a generated file. */ #include #include "manager.hpp" #include "functor.hpp" @@ -79,9 +142,11 @@ const std::vector Manager::_zoneLayouts }, %endfor }, + std::vector{ + %for i, a in enumerate(event['pc']['pcact']): make_action( - precondition::${event['pc']['pcact']['name']}( - %for i, p in enumerate(event['pc']['pcact']['params']): + precondition::${a['name']}( + %for p in a['params']: ${p['type']}${p['open']} %for j, v in enumerate(p['values']): %if (j+1) != len(p['values']): @@ -92,63 +157,24 @@ const std::vector Manager::_zoneLayouts %endfor ${p['close']}, %endfor - %endif - SetSpeedEvent{ - Group{ - %for member in event['group']: - { - "${member['name']}", - {"${member['interface']}", - "${member['property']}"} - }, - %endfor - }, - make_action(action::${event['action']['name']}( - %for i, p in enumerate(event['action']['parameters']): - %if (i+1) != len(event['action']['parameters']): - static_cast<${p['type']}>(${p['value']}), - %else: - static_cast<${p['type']}>(${p['value']}) - %endif - %endfor + %if (i+1) != len(event['pc']['pcact']): )), - Timer{ - ${event['timer']['interval']} - }, - std::vector{ - %for s in event['signal']: - PropertyChange{ - interfacesAdded("${s['obj_path']}"), - make_handler(objectSignal<${s['type']}>( - "${s['path']}", - "${s['interface']}", - "${s['property']}", - handler::setProperty<${s['type']}>( - "${s['path']}", - "${s['interface']}", - "${s['property']}" - ) - )) - }, - PropertyChange{ - propertiesChanged( - "${s['path']}", - "${s['interface']}"), - make_handler(propertySignal<${s['type']}>( - "${s['interface']}", - "${s['property']}", - handler::setProperty<${s['type']}>( - "${s['path']}", - "${s['interface']}", - "${s['property']}" - ) - )) - }, + %endif %endfor - } + std::vector{ + %for pcevt in event['pc']['pcevts']: + SetSpeedEvent{\ + ${indent(genSSE(event=pcevt), 6)}\ + }, + %endfor + %else: + SetSpeedEvent{\ + ${indent(genSSE(event=event), 6)} + %endif %if ('pc' in event) and (event['pc'] is not None): } )), + }, Timer{ ${event['pc']['pctime']['interval']} }, @@ -206,7 +232,104 @@ def convertToMap(listOfDict): return listOfDict -def addPrecondition(event, events_data): +def getEvent(zone_num, zone_conditions, e, events_data): + """ + Parses the sections of an event and populates the properties + that construct an event within the generated source. + """ + event = {} + # Zone numbers are optional in the events yaml but skip if this + # zone's zone number is not in the event's zone numbers + if all('zones' in z and + z['zones'] is not None and + zone_num not in z['zones'] + for z in e['zone_conditions']): + return + + # Zone conditions are optional in the events yaml but skip + # if this event's condition is not in this zone's conditions + if all('name' in z and z['name'] is not None and + not any(c['name'] == z['name'] for c in zone_conditions) + for z in e['zone_conditions']): + return + + # Add set speed event group + group = [] + groups = next(g for g in events_data['groups'] + if g['name'] == e['group']) + for member in groups['members']: + members = {} + members['obj_path'] = groups['type'] + members['name'] = (groups['type'] + + member) + members['interface'] = e['interface'] + members['property'] = e['property']['name'] + group.append(members) + event['group'] = group + + # Add set speed actions and function parameters + action = [] + for eActions in e['actions']: + actions = {} + eAction = next(a for a in events_data['actions'] + if a['name'] == eActions['name']) + actions['name'] = eAction['name'] + params = [] + for p in eAction['parameters']: + param = {} + if type(eActions[p]) is not dict: + if p == 'property': + param['value'] = str(eActions[p]).lower() + param['type'] = str( + e['property']['type']).lower() + else: + # Default type to 'size_t' when not given + param['value'] = str(eActions[p]).lower() + param['type'] = 'size_t' + params.append(param) + else: + param['type'] = str(eActions[p]['type']).lower() + if p != 'map': + param['value'] = str( + eActions[p]['value']).lower() + else: + emap = convertToMap(str(eActions[p]['value'])) + param['value'] = param['type'] + emap + params.append(param) + actions['parameters'] = params + action.append(actions) + event['action'] = action + + # Add property change signal handler + signal = [] + for path in group: + signals = {} + signals['obj_path'] = path['obj_path'] + signals['path'] = path['name'] + signals['interface'] = e['interface'] + signals['property'] = e['property']['name'] + signals['type'] = e['property']['type'] + signal.append(signals) + event['signal'] = signal + + # Add optional action call timer + timer = {} + interval = "static_cast" + if ('timer' in e) and \ + (e['timer'] is not None): + timer['interval'] = (interval + + "(" + + str(e['timer']['interval']) + + ")") + else: + timer['interval'] = (interval + + "(" + str(0) + ")") + event['timer'] = timer + + return event + + +def addPrecondition(zNum, zCond, event, events_data): """ Parses the precondition section of an event and populates the necessary structures to generate a precondition for a set speed event. @@ -229,13 +352,14 @@ def addPrecondition(event, events_data): group.append(members) precond['pcgrp'] = group - # Add set speed event precondition action - pc = {} - pc['name'] = event['precondition']['name'] - pcs = next(p for p in events_data['preconditions'] + # Add set speed event precondition actions + pc = [] + pcs = {} + pcs['name'] = event['precondition']['name'] + epc = next(p for p in events_data['preconditions'] if p['name'] == event['precondition']['name']) params = [] - for p in pcs['parameters']: + for p in epc['parameters']: param = {} if p == 'groups': param['type'] = "std::vector" @@ -255,9 +379,18 @@ def addPrecondition(event, events_data): values.append(value) param['values'] = values params.append(param) - pc['params'] = params + pcs['params'] = params + pc.append(pcs) precond['pcact'] = pc + pcevents = [] + for pce in event['precondition']['events']: + pcevent = getEvent(zNum, zCond, pce, events_data) + if not pcevent: + continue + pcevents.append(pcevent) + precond['pcevts'] = pcevents + # Add precondition property change signal handler signal = [] for member in group: @@ -296,92 +429,18 @@ def getEventsInZone(zone_num, zone_conditions, events_data): if 'events' in events_data: for e in events_data['events']: - - # Zone numbers are optional in the events yaml but skip if this - # zone's zone number is not in the event's zone numbers - if all('zones' in z and z['zones'] is not None and - zone_num not in z['zones'] for z in e['zone_conditions']): - continue - - # Zone conditions are optional in the events yaml but skip if this - # event's condition is not in this zone's conditions - if all('name' in z and z['name'] is not None and - not any(c['name'] == z['name'] for c in zone_conditions) - for z in e['zone_conditions']): - continue - event = {} # Add precondition if given if ('precondition' in e) and \ (e['precondition'] is not None): - event['pc'] = addPrecondition(e, events_data) - - # Add set speed event group - group = [] - groups = next(g for g in events_data['groups'] - if g['name'] == e['group']) - for member in groups['members']: - members = {} - members['obj_path'] = groups['type'] - members['name'] = (groups['type'] + - member) - members['interface'] = e['interface'] - members['property'] = e['property']['name'] - group.append(members) - event['group'] = group - - # Add set speed action and function parameters - action = {} - actions = next(a for a in events_data['actions'] - if a['name'] == e['action']['name']) - action['name'] = actions['name'] - params = [] - for p in actions['parameters']: - param = {} - if type(e['action'][p]) is not dict: - if p == 'property': - param['value'] = str(e['action'][p]).lower() - param['type'] = str(e['property']['type']).lower() - else: - # Default type to 'size_t' when not given - param['value'] = str(e['action'][p]).lower() - param['type'] = 'size_t' - params.append(param) - else: - param['type'] = str(e['action'][p]['type']).lower() - if p != 'map': - param['value'] = str(e['action'][p]['value']).lower() - else: - emap = convertToMap(str(e['action'][p]['value'])) - param['value'] = param['type'] + emap - params.append(param) - action['parameters'] = params - event['action'] = action - - # Add property change signal handler - signal = [] - for path in group: - signals = {} - signals['obj_path'] = path['obj_path'] - signals['path'] = path['name'] - signals['interface'] = e['interface'] - signals['property'] = e['property']['name'] - signals['type'] = e['property']['type'] - signal.append(signals) - event['signal'] = signal - - # Add optional action call timer - timer = {} - interval = "static_cast" - if ('timer' in e) and \ - (e['timer'] is not None): - timer['interval'] = (interval + - "(" + str(e['timer']['interval']) + ")") + event['pc'] = addPrecondition(zone_num, + zone_conditions, + e, + events_data) else: - timer['interval'] = (interval + - "(" + str(0) + ")") - event['timer'] = timer - + event = getEvent(zone_num, zone_conditions, e, events_data) + if not event: + continue events.append(event) return events -- cgit v1.2.1