summaryrefslogtreecommitdiff
path: root/lib/Kratos/DFADriver/Model.pm
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2017-04-06 16:42:48 +0200
committerDaniel Friesel <derf@finalrewind.org>2017-04-06 16:42:48 +0200
commit83549eb94e055d02002bf6c46a25d0ad0aed24c7 (patch)
tree00e3ffc19210199b78a1bb069f8114b7a2132b2f /lib/Kratos/DFADriver/Model.pm
parentc4a4ca14987b2a9e4857b4d85a4437dd10e4bf5c (diff)
refactoring, no more special treatment for timeout (mostly)
Diffstat (limited to 'lib/Kratos/DFADriver/Model.pm')
-rw-r--r--lib/Kratos/DFADriver/Model.pm376
1 files changed, 153 insertions, 223 deletions
diff --git a/lib/Kratos/DFADriver/Model.pm b/lib/Kratos/DFADriver/Model.pm
index bf57c49..ff5757f 100644
--- a/lib/Kratos/DFADriver/Model.pm
+++ b/lib/Kratos/DFADriver/Model.pm
@@ -32,6 +32,44 @@ sub new {
return $self;
}
+sub parse_xml_property {
+ my ($self, $node, $property_name) = @_;
+
+ my $xml = $self->{xml};
+ my $ret = {
+ static => 0
+ };
+
+ my ($property_node) = $node->findnodes("./${property_name}");
+ if (not $property_node) {
+ return $ret;
+ }
+
+ for my $static_node ( $property_node->findnodes('./static') ) {
+ $ret->{static} = 0 + $static_node->textContent;
+ }
+ for my $function_node ( $property_node->findnodes('./function/*') ) {
+ my $name = $function_node->nodeName;
+ my $function = $function_node->textContent;
+ $function =~ s{^ \n* \s* }{}x;
+ $function =~ s{\s* \n* $}{}x;
+ $function =~ s{ [\n\t]+ }{}gx;
+
+ $ret->{function}{$name}{raw} = $function;
+ $ret->{function}{$name}{node} = $function_node;
+
+ my $param_idx = 0;
+ while ( $function_node->hasAttribute("param${param_idx}") ) {
+ push( @{ $ret->{function}{$name}{params} },
+ $function_node->getAttribute("param${param_idx}") );
+ $param_idx++;
+ }
+ }
+
+ return $ret;
+}
+
+
sub parse_xml {
my ($self) = @_;
@@ -45,33 +83,11 @@ sub parse_xml {
my $name = $state_node->getAttribute('name');
my $power = $state_node->getAttribute('power') // 0;
$self->{states}{$name} = {
- power => { static => 0+$power },
+ power => $self->parse_xml_property($state_node, 'power'),
id => $state_index,
node => $state_node,
};
- for my $fun_node ( $state_node->findnodes('./powerfunction/*') ) {
- my $fname = $fun_node->nodeName;
- my $powerfunction = $fun_node->textContent;
- $powerfunction =~ s{^ \n* \s* }{}x;
- $powerfunction =~ s{\s* \n* $}{}x;
- $powerfunction =~ s{ [\n\t]+ }{}gx;
- $self->{states}{$name}{power}{function}{$fname}{raw}
- = $powerfunction;
- $self->{states}{$name}{power}{function}{$fname}{node} = $fun_node;
- my $attrindex = 0;
-
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{
- $self->{states}{$name}{power}{function}{$fname}{params}
- },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
$state_index++;
}
@@ -118,10 +134,11 @@ sub parse_xml {
my $transition = {
name => $transition_node->getAttribute('name'),
- duration => { static => 0+($transition_node->getAttribute('duration') // 0) },
- energy => { static => 0+($transition_node->getAttribute('energy') // 0) },
- rel_energy_prev => { static => 0+($transition_node->getAttribute('rel_energy_prev') // 0) },
- rel_energy_next => { static => 0+($transition_node->getAttribute('rel_energy_next') // 0) },
+ duration => $self->parse_xml_property($transition_node, 'duration'),
+ energy => $self->parse_xml_property($transition_node, 'energy'),
+ rel_energy_prev => $self->parse_xml_property($transition_node, 'rel_energy_prev'),
+ rel_energy_next => $self->parse_xml_property($transition_node, 'rel_energy_next'),
+ timeout => $self->parse_xml_property($transition_node, 'timeout'),
parameters => [@parameters],
origins => [@source_states],
destination => $dst_node->textContent,
@@ -131,96 +148,6 @@ sub parse_xml {
node => $transition_node,
};
- for my $fun_node ( $transition_node->findnodes('./timeoutfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{timeout}{function}{$name}{raw} = $function;
- $transition->{timeout}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{timeout}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
- for my $fun_node ( $transition_node->findnodes('./durationfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{duration}{function}{$name}{raw} = $function;
- $transition->{duration}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{duration}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
- for my $fun_node ( $transition_node->findnodes('./energyfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{energy}{function}{$name}{raw} = $function;
- $transition->{energy}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{energy}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
- for my $fun_node ( $transition_node->findnodes('./rel_energy_prevfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{rel_energy_prev}{function}{$name}{raw} = $function;
- $transition->{rel_energy_prev}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{rel_energy_prev}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
- for my $fun_node ( $transition_node->findnodes('./rel_energy_nextfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{rel_energy_next}{function}{$name}{raw} = $function;
- $transition->{rel_energy_next}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{rel_energy_next}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
push( @{ $self->{transitions} }, $transition );
$transition_index++;
@@ -246,61 +173,112 @@ sub parse_xml {
return $self;
}
-sub reset {
- my ($self) = @_;
+sub reset_property {
+ my ($self, $node, $name) = @_;
- for my $state (values %{$self->{states}}) {
- $state->{node}->removeAttribute('power');
- for my $list_node (@{$state->{node}->findnodes('./powerfunction')}) {
- for my $fun_name (keys %{$state->{power}{function}}) {
- my $fun_node = $state->{power}{function}{$fun_name}{node};
- if ($fun_node->nodeName eq 'user') {
- for my $attrnode ($fun_node->attributes) {
+ my ($property_node) = $node->findnodes("./${name}");
+
+ if ($property_node) {
+ for my $static_node ($property_node->findnodes('./static')) {
+ $property_node->removeChild($static_node);
+ }
+ for my $function_parent ($property_node->findnodes('./function')) {
+ for my $function_node ($function_parent->childNodes) {
+ if ($function_node->nodeName eq 'user') {
+ for my $attrnode ($function_node->attributes) {
$attrnode->setValue(1);
}
}
else {
- $list_node->removeChild($fun_node);
+ $function_parent->removeChild($function_node);
}
}
}
}
+}
+
+sub reset {
+ my ($self) = @_;
+
+ for my $state (values %{$self->{states}}) {
+ for my $property (qw(power)) {
+ $self->reset_property($state->{node}, $property);
+ }
+ }
+
for my $transition (@{$self->{transitions}}) {
- $transition->{node}->removeAttribute('duration');
- $transition->{node}->removeAttribute('energy');
- $transition->{node}->removeAttribute('rel_energy_prev');
- $transition->{node}->removeAttribute('rel_energy_next');
- for my $list_node (@{$transition->{node}->findnodes('./timeoutfunction')}) {
- for my $fun_name (keys %{$transition->{timeout}{function}}) {
- my $fun_node = $transition->{timeout}{function}{$fun_name}{node};
- if ($fun_node->nodeName eq 'user') {
- for my $attrnode ($fun_node->attributes) {
- $attrnode->setValue(1);
- }
- }
- else {
- $list_node->removeChild($fun_node);
- }
- }
+ for my $property (qw(duration energy rel_energy_prev rel_energy_next timeout)) {
+ $self->reset_property($transition->{node}, $property);
}
}
}
sub set_state_power {
my ( $self, $state, $power ) = @_;
+ my $state_node = $self->{states}{$state}{node};
$power = sprintf( '%.f', $power );
+ $self->{states}{$state}{power}{static} = $power;
printf( "state %-16s: adjust power %d -> %d µW\n",
$state, $self->{states}{$state}{power}{static}, $power );
- $self->{states}{$state}{power}{static} = $power;
- $self->{states}{$state}{node}->setAttribute( 'power', $power );
+ my ($static_parent) = $state_node->findnodes('./power');
+ if (not $static_parent) {
+ $static_parent = XML::LibXML::Element->new('power');
+ $state_node->appendChild($static_parent);
+ }
+
+ for my $static_node ($static_parent->findnodes('./static')) {
+ $static_parent->removeChild($static_node);
+ }
+
+ my $static_node = XML::LibXML::Element->new('static');
+ my $text_node = XML::LibXML::Text->new($power);;
+
+ $text_node->setData($power);
+ $static_node->appendChild($text_node);
+ $static_parent->appendChild($static_node);
+}
+
+sub set_transition_property {
+ my ( $self, $transition_name, $property, $value ) = @_;
+
+ if (not defined $value) {
+ return;
+ }
+
+ my $transition = $self->get_transition_by_name($transition_name);
+ my $transition_node = $transition->{node};
+ $value = sprintf('%.f', $value);
+
+ printf( "transition %-16s: adjust %s %d -> %d\n",
+ $transition->{name}, $property, $transition->{$property}{static}, $value);
+
+ $transition->{$property}{static} = $value;
+
+ my ($static_parent) = $transition_node->findnodes("./${property}");
+ if (not $static_parent) {
+ $static_parent = XML::LibXML::Element->new($property);
+ $transition_node->appendChild($static_parent);
+ }
+
+ for my $static_node ($static_parent->findnodes('./static')) {
+ $static_parent->removeChild($static_node);
+ }
+
+ my $static_node = XML::LibXML::Element->new('static');
+ my $text_node = XML::LibXML::Text->new($value);
+
+ $text_node->setData($value);
+ $static_node->appendChild($text_node);
+ $static_parent->appendChild($static_node);
}
sub set_state_params {
my ( $self, $state, $fun_name, $function, @params ) = @_;
my $old_params = 'None';
+ my $state_node = $self->{states}{$state}{node};
if ( exists $self->{states}{$state}{power}{function}{$fun_name} ) {
$old_params = join( q{ },
@@ -310,42 +288,35 @@ sub set_state_params {
printf( "state %-16s: adjust %s power function parameters [%s] -> [%s]\n",
$state, $fun_name, $old_params, join( q{ }, @params ) );
- if ( not defined $self->{states}{$state}{power}{function}{$fun_name}{node} )
- {
- my ($fun_node)
- = $self->{states}{$state}{node}->findnodes('./powerfunction');
- if ($fun_node) {
- my $new_node = XML::LibXML::Element->new($fun_name);
- $self->{states}{$state}{power}{function}{$fun_name}{node}
- = $new_node;
- $fun_node->appendChild($new_node);
- }
- else {
- say
- ' skipping XML write-back because of missing powerfunction node';
- return;
- }
+ my ($function_parent) = $state_node->findnodes('./power/function');
+
+ if (not $function_parent) {
+ my ($power_node) = $state_node->findnodes('./power');
+ $function_parent = XML::LibXML::Element->new('function');
+ $power_node->appendChild($function_parent);
}
- if ( defined $function ) {
- my $cdata_node = XML::LibXML::CDATASection->new($function);
- $self->{states}{$state}{power}{function}{$fun_name}{node}
- ->removeChildNodes;
- $self->{states}{$state}{power}{function}{$fun_name}{node}
- ->appendChild($cdata_node);
+ for my $function_node ($function_parent->findnodes("./${fun_name}")) {
+ $function_parent->removeChild($function_node);
}
+ my $function_node = XML::LibXML::Element->new($fun_name);
+ my $function_content = XML::LibXML::CDATASection->new($function);
+
+ $function_node->appendChild($function_content);
+ $function_parent->appendChild($function_node);
+
for my $i ( 0 .. $#params ) {
$self->{states}{$state}{power}{function}{$fun_name}{params}[$i]
= $params[$i];
- $self->{states}{$state}{power}{function}{$fun_name}{node}
- ->setAttribute( "param$i", $params[$i] );
+ $function_node->setAttribute( "param$i", $params[$i] );
}
}
sub set_transition_params {
my ( $self, $transition_name, $fun_type, $fun_name, $function, @params ) = @_;
my $transition = $self->get_transition_by_name($transition_name);
+ my $transition_node = $transition->{node};
my $old_params = 'None';
if ( exists $transition->{$fun_type}{function}{$fun_name} ) {
@@ -357,69 +328,28 @@ sub set_transition_params {
"transition %-16s: adjust %s %s function parameters [%s] -> [%s]\n",
$transition_name, $fun_name, $fun_type, $old_params, join( q{ }, @params ) );
- if ( not defined $transition->{$fun_type}{function}{$fun_name}{node} ) {
- my ($fun_node) = $transition->{node}->findnodes("./${fun_type}function");
- if ($fun_node) {
- my $new_node = XML::LibXML::Element->new($fun_name);
- $transition->{$fun_type}{function}{$fun_name}{node} = $new_node;
- $fun_node->appendChild($new_node);
- }
- else {
- say
-" skipping XML write-back because of missing ${fun_type}function node";
- return;
- }
- }
+ my ($function_parent) = $transition_node->findnodes("./${fun_type}/function");
- if ( defined $function ) {
- my $cdata_node = XML::LibXML::CDATASection->new($function);
- $transition->{$fun_type}{function}{$fun_name}{node}->removeChildNodes;
- $transition->{$fun_type}{function}{$fun_name}{node}
- ->appendChild($cdata_node);
+ if (not $function_parent) {
+ my ($property_node) = $transition_node->findnodes("./${fun_type}");
+ $function_parent = XML::LibXML::Element->new('function');
+ $property_node->appendChild($function_parent);
}
- for my $i ( 0 .. $#params ) {
- $transition->{$fun_type}{function}{$fun_name}{params}[$i] = $params[$i];
- $transition->{$fun_type}{function}{$fun_name}{node}
- ->setAttribute( "param$i", $params[$i] );
+ for my $function_node ($function_parent->findnodes("./${fun_name}")) {
+ $function_parent->removeChild($function_node);
}
-}
-
-sub set_transition_data {
- my ( $self, $transition_name, $duration, $energy, $rel_energy_prev, $rel_energy_next ) = @_;
-
- my $transition = $self->get_transition_by_name($transition_name);
- $duration = sprintf( '%.f', $duration );
- $energy = sprintf( '%.f', $energy );
-
- printf( 'transition %-16s: adjust duration %d -> %d µs',
- $transition->{name}, $transition->{duration}{static}, $duration);
- $transition->{duration}{static} = $duration;
- $transition->{node}->setAttribute('duration', $duration);
- printf( ', absolute energy %d -> %d pJ',
- $transition->{energy}{static}, $energy );
+ my $function_node = XML::LibXML::Element->new($fun_name);
+ my $function_content = XML::LibXML::CDATASection->new($function);
- $transition->{energy}{static} = $energy;
- $transition->{node}->setAttribute( 'energy', $energy );
+ $function_node->appendChild($function_content);
+ $function_parent->appendChild($function_node);
- if (defined $rel_energy_prev) {
- $rel_energy_prev = sprintf('%.f', $rel_energy_prev);
- printf( ", relative_prev energy %d -> %d pJ",
- $transition->{rel_energy_prev}{static}, $rel_energy_prev );
-
- $transition->{rel_energy_prev}{static} = $rel_energy_prev;
- $transition->{node}->setAttribute( 'rel_energy_prev', $rel_energy_prev );
- }
- if (defined $rel_energy_next) {
- $rel_energy_next = sprintf('%.f', $rel_energy_next);
- printf( ", relative_next energy %d -> %d pJ",
- $transition->{rel_energy_next}{static}, $rel_energy_next );
-
- $transition->{rel_energy_next}{static} = $rel_energy_next;
- $transition->{node}->setAttribute( 'rel_energy_next', $rel_energy_next );
+ for my $i ( 0 .. $#params ) {
+ $transition->{$fun_type}{function}{$fun_name}{params}[$i] = $params[$i];
+ $function_node->setAttribute( "param$i", $params[$i] );
}
- print("\n");
}
sub save {