package mpe;
import java.io.File;
import java.net.UnknownHostException;
// XML parser library includes
import xmlcomponents.Jocument;
import xmlcomponents.Jode;
import processing.core.PApplet;
/**
* An object that encapsulates the configuration context of the display system.
* @author Brandt Westing TACC
*
*/
public class Configuration {
private PApplet applet_;
private String file_;
private String server_ = null;
private int port_;
private int[] localDim_;
private int[] masterDim_;
private int[] offsets_;
private int[] tileRes_;
private int[] numTiles_;
private int[] bezels_;
private int[] windowLocation_;
private String display_;
private int rank_;
private boolean debug_ = true;
// are we the leader process?
boolean isLeader_ = false;
// the number of follower processes (total num processes - 1)
int numFollowers_;
// this constructor is in case you forget the file location or just omit it
public Configuration(PApplet p)
{
this("configuration.xml", p);
}
// We assume that a head process is launched from the processing GUI, and the rank is not declared
// if the rank is declared in the environment, we assume the process was launched via command line
public Configuration(String _file, PApplet _p)
{
// the processing applet that we are taking care of!
applet_ = _p;
file_ = _file;
tileRes_ = new int[2];
numTiles_ = new int[2];
bezels_ = new int[2];
localDim_ = new int[2];
masterDim_ = new int[2];
offsets_ = new int[2];
windowLocation_ = new int[2];
// set up the pipeline for reading XML
Jode root = null;
File file = new File(_file);
if (file.isAbsolute()) {
if(debug_)
System.out.println("Configuration: loading config: " + file.getPath());
root = Jocument.load(_file);
} else {
if(debug_)
System.out.println("Configuration: loading config: " + _p.dataPath(_file));
root = Jocument.load(_p.dataPath(_file));
}
// my DISPLAY identifier
display_ = System.getenv("DISPLAY");
if(System.getenv("RANK") != null)
rank_ = Integer.valueOf(System.getenv("RANK"));
else rank_ = -1; // head node in auto-start
System.out.println("loading XML configuration node");
Jode config = root.single("configuration");
System.out.println("loading XML dimensions node");
Jode dimensions = config.single("dimensions");
System.out.println("loading XML dimensions node, screenWidth");
tileRes_[0] = Integer.parseInt(dimensions.attribute("screenWidth").v);
tileRes_[1] = Integer.parseInt(dimensions.attribute("screenHeight").v);
numTiles_[0] = Integer.parseInt(dimensions.attribute("numTilesWidth").v);
numTiles_[1] = Integer.parseInt(dimensions.attribute("numTilesHeight").v);
bezels_[0] = Integer.parseInt(dimensions.attribute("mullionWidth").v);
System.out.println("loading XML dimensions node, mullionHeight");
bezels_[1] = Integer.parseInt(dimensions.attribute("mullionHeight").v);
System.out.println("loading XML dimensions node, debug");
debug_ = Integer.parseInt(dimensions.attribute("debug").v) == 1;
numFollowers_ = config.children().getLength() - 3;
System.out.println("numFollowers_ = " + numFollowers_);
System.out.println("loading XML dimensions node, head");
Jode head = config.first("head");
if(head != null)
{
server_ = head.attribute("host").v;
port_ = Integer.parseInt(head.attribute("port").v);
if(debug_)
System.out.println("Server: "+ server_ + ":" + Integer.toString(port_));
}
else
{
System.out.println("Couldn't get head! Setting default as localhost");
server_ = "localhost";
}
// we are the head node
if(rank_ == -1)
{
Jode headChild = head.first();
localDim_[0] = Integer.parseInt(headChild.attribute("width").v);
localDim_[1] = Integer.parseInt(headChild.attribute("height").v);
masterDim_[0] = localDim_[0];
masterDim_[1] = localDim_[1];
// offsets
offsets_[0] = 0;
offsets_[1] = 0;
isLeader_ = true;
return;
}
Jode child = null;
// find the entry for the correct host
for(Jode configChild: config.children())
{
if(configChild.hasAttribute("rank"))
{
if(Integer.parseInt(configChild.attribute("rank").v) == rank_)
{
child = configChild;
break; // we found our xml entry!
}
}
}
if(child == null)
{
System.out.println("ERROR: Couldn't find my entry in the configuration. Exiting.");
System.exit(-1);
}
// child corresponds to entry with the correct hostName here
Jode childi;
childi = child.first();
int mini = Integer.parseInt(childi.attribute("i").v);
int maxi = Integer.parseInt(childi.attribute("i").v);
int minj = Integer.parseInt(childi.attribute("j").v);
int maxj = Integer.parseInt(childi.attribute("j").v);
// note: this won't work generically -- only when addressing multiple screens in one display (ala xinerama) -- add tag for this?
windowLocation_[0] = (mini)*tileRes_[0];
windowLocation_[1] = 0;
try
{
windowLocation_[0] = Integer.parseInt(childi.attribute("x").v);
System.out.println("!!!! x: "+childi.attribute("x").v);
}
catch (Exception e)
{
if (debug_) System.out.println("no x attribute found for rank "+rank_);
}
try
{
windowLocation_[1] = Integer.parseInt(childi.attribute("y").v);
}
catch (Exception e)
{
if (debug_) System.out.println("no y attribute found for rank "+rank_);
}
for(int i = 0; i < child.children().getLength(); i++)
{
childi = child.children().get(i);
if(Integer.parseInt(childi.attribute("i").v) < mini)
mini = Integer.parseInt(childi.attribute("i").v);
if(Integer.parseInt(childi.attribute("i").v) > maxi)
maxi = Integer.parseInt(childi.attribute("i").v);
if(Integer.parseInt(childi.attribute("j").v) < minj)
minj = Integer.parseInt(childi.attribute("j").v);
if(Integer.parseInt(childi.attribute("j").v) > maxj)
maxj = Integer.parseInt(childi.attribute("j").v);
}
//windowLocation_[0] = 0;
//windowLocation_[1] = 0;
// this get the size of the monitor array for this host in screens
int rangei = maxi - mini + 1;
int rangej = maxj - minj + 1;
if (debug_)
System.out.println("maxi: "+maxi+" mini: "+mini+" rangei: "+rangei);
int totalMullionsX = (rangei - 1)*bezels_[0];
int totalMullionsY = (rangej - 1)*bezels_[1];
localDim_[0] = rangei*tileRes_[0] + totalMullionsX;
localDim_[1] = rangej*tileRes_[1] + totalMullionsY;
masterDim_[0] = numTiles_[0]*tileRes_[0] + (numTiles_[0] - 1)*bezels_[0];
masterDim_[1] = numTiles_[1]*tileRes_[1] + (numTiles_[1] - 1)*bezels_[1];
if (debug_)
{
System.out.println("masterDim_[0]: "+masterDim_[0]+"masterDim_[1]: "+masterDim_[1]);
System.out.println("localDim_[0]: "+localDim_[0]+"localDim_[1]: "+localDim_[1]);
}
// offsets
offsets_[0] = (mini)*tileRes_[0] + mini*bezels_[0];
offsets_[1] = (minj)*tileRes_[1] + minj*bezels_[1];
//set the initial window location of the processing sketch
//_p.frame.setLocation(0,0);
if(debug_)
printSettings();
}
public PApplet getApplet()
{
return applet_;
}
public String getServer() {
return server_;
}
public int getPort() {
return port_;
}
public int[] getLocalDim() {
return localDim_;
}
// special for processing
public int getLWidth()
{
return localDim_[0];
}
// special for processing
public int getLHeight()
{
return localDim_[1];
}
public int[] getMasterDim() {
return masterDim_;
}
public int getMWidth(){
return numTiles_[0]*tileRes_[0] + (numTiles_[0] - 1)*bezels_[0];
}
public int getMHeight(){
return numTiles_[1]*tileRes_[1] + (numTiles_[1] - 1)*bezels_[1];
}
public int[] getOffsets() {
return offsets_;
}
// Returns an array containing the (x,y) location of the sketch window
public int[] getWindowLocation() {
return windowLocation_;
}
public int getNumFollowers()
{
return numFollowers_;
}
public boolean isLeader()
{
return isLeader_;
}
public boolean getDebug()
{
return debug_;
}
public int getRank()
{
return rank_;
}
public String getFilename()
{
return file_;
}
public void printSettings()
{
System.out.println("Settings: Rank: " + rank_ +
", offsets: " + offsets_[0] + "," + offsets_[1] +
", lDims: " + localDim_[0] + "," + localDim_[1] +
", mDims: " + masterDim_[0] + "," + masterDim_[1] +
", windowLocation: " + windowLocation_[0] + "," + windowLocation_[1]);
}
}