package RadioMobile::NetsUnits;
use strict;
use warnings;
use Class::Container;
use Params::Validate qw(:types);
use base qw(Class::Container RadioMobile::Utils::Matrix);
__PACKAGE__->valid_params();
__PACKAGE__->contained_objects();
use RadioMobile::NetUnit;
our $VERSION = '0.10';
sub new {
my $package = shift;
my $s = $package->SUPER::new(@_);
# non sono convinto di questa cosa...dovrebbe farlo gia' il new sopra
$s->SUPER::_init(@_);
return $s;
}
sub parse {
# read net_role
# NET_ROLE shows in which network is associated an unit
# and its role (master/slave/node/terminal)
# it's a vector of byte with size $header->networkCount * $header->unitCount
# Given A,B,C... units and 1,2,3 Network so A1 is a byte
# indicate if unit A is in network 1 and its role
# It's structure is
# A1 A2 A3 ... B1 B2 B3 ... C1 C2 C3 ...
# The following code traslate this in a AoA with this structure
# [
# [A1 B1 C1 ... ]
# [A2 B2 C2 ....]
# [A3 B3 C3 ... ]
# ]
# like _NetData.csv
# Every byte it's so used A1 = aaaabbbb where aaaa is the first four bits
# and bbbb the others. aaaa is 1000 if the unit A
# belongs to network 1, 0000 else.
# bbbb is an integer 0..127 setting its role index
# Example: (\x00 first role, no belong, \x01 second role, no belong,
# \x80 (128) first role, belong to network, \x81 (129) second role, belong
my $s = shift;
my $f = $s->container->bfile;
my $h = $s->container->header;
my $len = $h->unitCount * $h->networkCount;
my $b = $f->get_bytes($len);
my $skip = 'x[' . ($h->networkCount-1) . ']';
my @netRole;
foreach (0..$h->networkCount-1) {
my $format = 'x[' . $_ . '](C' . $skip . ')' . ($h->unitCount-1) . 'C';
push @netRole, [unpack($format,$b)];
}
# First generate NetUnit items and extract network isIn
foreach my $netIdx (0..$h->networkCount-1) {
my @unitNetwork;
my @isInNetwork = map {$_ > 127 ? 1 : 0} @{$netRole[$netIdx]};
my $net = $s->container->nets->at($netIdx);
foreach my $unitIdx (0..$h->unitCount-1) {
my $unit = $s->container->units->at($unitIdx);
my $netunit = new RadioMobile::NetUnit(unit => $unit, net => $net);
$netunit->isIn($isInNetwork[$unitIdx]);
push @unitNetwork, $netunit;
}
$s->addRow(@unitNetwork);
}
# now add Roles
foreach my $netIdx (0..$h->networkCount-1) {
foreach my $unitIdx (0..$h->unitCount-1) {
my $role = $netRole[$netIdx]->[$unitIdx];
$s->at($netIdx,$unitIdx)->role($role > 127 ? $role - 128 : $role);
}
}
#my @unitRole;
#foreach my $item (@netRole) {
#push @unitRole, [map {$_ > 127 ? $_-128 : $_ } @$item]
#}
}
sub write {
my $s = shift;
my $f = $s->container->bfile;
my $h = $s->container->header;
foreach my $unitIdx (0..$h->unitCount-1) {
foreach my $netIdx (0..$h->networkCount-1) {
my $netunit = $s->at($netIdx,$unitIdx);
my $byte = $netunit->isIn ? 0x80 : 0x00;
$byte |= $netunit->role;
$f->put_bytes(pack("C",$byte));
}
}
}
sub dump {
my $s = shift;
return $s->SUPER::dump unless (@_);
my $method = shift;
my $ret = '';
foreach (0..$s->rowsCount-1) {
my @row = $s->rows->at($_)->list;
my @func = map {$_->$method} @row;
@func = map(defined $_ ? $_ : '',@func);
$ret .= '| ' . join(' | ',@func) . " |\n";
}
return $ret;
}
sub sync {
my $s = shift;
my $h = $s->container->header;
foreach my $unitIdx (0..$h->unitCount-1) {
foreach my $netIdx (0..$h->networkCount-1) {
my $netunit = $s->at($netIdx,$unitIdx);
unless (defined $netunit) {
# se non esiste creo l'elemento
$s->resetNetUnit($unitIdx,$netIdx);
}
}
}
}
sub resetNetUnit {
my $s = shift;
my $unitIdx = shift;
my $netIdx = shift;
my $unit = $s->container->units->at($unitIdx);
my $net = $s->container->nets->at($netIdx);
my $netunit = new RadioMobile::NetUnit(unit => $unit, net => $net);
$netunit->system($s->container->systems->at(0));
$s->at($netIdx,$unitIdx,$netunit);
}
1;
__END__