/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: DemandTemplateHandler.java
* Written by: Alexander Herzog (Team 4)
*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*
* Electric(tm) is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Electric(tm) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Electric(tm); see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, Mass 02111-1307, USA.
*/
package com.sun.electric.tool.routing.experimentalLeeMoore2;
import java.util.ArrayList;
import java.util.Iterator;
public class DemandTemplateHandler {
GlobalRouterThreadV3 grt;
public DemandTemplateHandler(GlobalRouterThreadV3 gr_thread){
grt = gr_thread;
}
int max_demand_estimate = 8;
class DemandEstimationJob{
public Vector2i pos;
public RegionDirection dir;
public int demand_increment;
public DemandEstimationJob(Vector2i pos, RegionDirection dir, int demand_inc){
this.pos = pos;
this.dir = dir;
this.demand_increment = demand_inc;
}
}
public void AddDemandEstimate(Vector2i start, Vector2i end){
ArrayList<DemandEstimationJob> template = CalcDemandTemplate(start, end);
ApplyDemandTemplate(template, true);
}
public void DecrementDemandEstimate(Vector2i start, Vector2i end){
ArrayList<DemandEstimationJob> template = CalcDemandTemplate(start, end);
ApplyDemandTemplate(template, false);
}
private ArrayList<DemandEstimationJob> CalcDemandTemplate(Vector2i start, Vector2i end){
ArrayList<DemandEstimationJob> demand_job_queue = new ArrayList<DemandEstimationJob>();
/** go to end point in horizontal direction */
int hor_dir = end.x - start.x >= 0 ? 1 : -1;
int ver_dir = end.y - start.y >= 0 ? 1 : -1;
RegionDirection curr_dir = (hor_dir == 1 ? RegionDirection.rd_right : RegionDirection.rd_left);
Vector2i it = new Vector2i(start.x, start.y);
for(;it.x != end.x; it.x += hor_dir){
int s_dist = max_demand_estimate - Math.abs(it.x - start.x) + 1;
s_dist = s_dist >= 0 ? s_dist : 0;
int e_dist = max_demand_estimate - Math.abs(it.x - end.x) + 1;
e_dist = e_dist >= 0 ? e_dist : 0;
int dist = e_dist + s_dist;
Vector2i pos = new Vector2i(it);
RegionDirection dir = curr_dir;
demand_job_queue.add(new DemandEstimationJob(pos, dir, dist));
}
/** go to end point in vertical direction */
curr_dir = (ver_dir == 1 ? RegionDirection.rd_up : RegionDirection.rd_down);
for(; it.y != end.y; it.y += ver_dir){
int s_dist = max_demand_estimate - Math.abs(it.y - start.y) + 1;
s_dist = s_dist >= 0 ? s_dist : 0;
int e_dist = max_demand_estimate - Math.abs(it.y - end.y) + 1;
e_dist = e_dist >= 0 ? e_dist : 0;
int dist = e_dist + s_dist;
Vector2i pos = new Vector2i(it);
RegionDirection dir = curr_dir;
demand_job_queue.add(new DemandEstimationJob(pos, dir, dist));
}
/** flip direction and go back to start in horizontal direction */
hor_dir -= 2 * hor_dir;
ver_dir -= 2 * ver_dir;
curr_dir = (hor_dir == 1 ? RegionDirection.rd_right : RegionDirection.rd_left);
for(;it.x != start.x; it.x += hor_dir){
int s_dist = max_demand_estimate - Math.abs(it.x - start.x) + 1;
s_dist = s_dist >= 0 ? s_dist : 0;
int e_dist = max_demand_estimate - Math.abs(it.x - end.x) + 1;
e_dist = e_dist >= 0 ? e_dist : 0;
int dist = e_dist + s_dist;
Vector2i pos = new Vector2i(it);
RegionDirection dir = curr_dir;
demand_job_queue.add(new DemandEstimationJob(pos, dir, dist));
}
/** go to start in vertical direction */
curr_dir = (ver_dir == 1 ? RegionDirection.rd_up : RegionDirection.rd_down);
for(; it.y != start.y; it.y += ver_dir){
int s_dist = max_demand_estimate - Math.abs(it.y - start.y) + 1;
s_dist = s_dist >= 0 ? s_dist : 0;
int e_dist = max_demand_estimate - Math.abs(it.y - end.y) + 1;
e_dist = e_dist >= 0 ? e_dist : 0;
int dist = e_dist + s_dist;
Vector2i pos = new Vector2i(it);
RegionDirection dir = curr_dir;
demand_job_queue.add(new DemandEstimationJob(pos, dir, dist));
}
return demand_job_queue;
}
private void ApplyDemandTemplate(ArrayList<DemandEstimationJob> template, boolean is_inc){
Iterator<DemandEstimationJob> it = template.iterator();
while(it.hasNext()){
DemandEstimationJob job = it.next();
if(is_inc){
grt.rm.RegionAt(job.pos.x, job.pos.y).GetRegionBorder(job.dir).IncDemand();
}else{
grt.rm.RegionAt(job.pos.x, job.pos.y).GetRegionBorder(job.dir).DecDemand();
}
}
}
}