/*
* Copyright 2011 Uwe Krueger.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mandelsoft.mand.srv;
import com.mandelsoft.mand.MandelSpec;
import com.mandelsoft.mand.calc.AreaCalculator;
import com.mandelsoft.mand.calc.CalculationContext;
import com.mandelsoft.mand.calc.SimpleAreaCalculator;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import com.mandelsoft.util.ChangeListener;
import com.mandelsoft.util.StateChangeSupport;
/**
*
* @author Uwe Krueger
*/
public class CalcRequest extends CalculationContext implements Request {
static private AreaCalculator calc=new SimpleAreaCalculator();
static private final int VERSION=1;
private int version; // found version
private long reqid;
private int[] data; // iteration data
static volatile long lastid=0;
public CalcRequest()
{
this.version=VERSION;
//reqid=System.currentTimeMillis();
reqid=0;
if (reqid<=lastid) reqid=lastid+1;
lastid=reqid;
}
public CalcRequest(MandelSpec spec, int sx, int sy,
int nx, int ny)
{
this();
setSpec(spec);
setSX(sx);
setSY(sy);
setNX(nx);
setNY(ny);
}
public CalcRequest(MandelSpec spec, int sx, int sy,
int nx, int ny,
int[] data)
{
this(spec,sx,sy,nx,ny);
this.data=data;
}
public long getReqId()
{
return reqid;
}
public int[] getData()
{
return data;
}
private void setReqId(long id)
{
reqid=id;
}
public void setData(int[] data)
{
this.data=data;
}
///////////////////////////////////////////////////////////////
// calculation
///////////////////////////////////////////////////////////////
public int getIndexAbs(int x, int y)
{
return (x-getSX())+(y-getSY())*getNX();
}
public int getIndexRel(int x, int y)
{
return x+y*getNX();
}
public void createData()
{
if (data==null) {
data=new int[getNX()*getNY()];
}
}
@Override
protected void resetData()
{
data=null;
}
public int getDataRel(int x, int y)
{
return data[getIndexRel(x,y)];
}
@Override
public void setDataRel(int x, int y, int it)
{
data[getIndexRel(x,y)]=it;
}
public void calc()
{
calc.calc(this);
}
///////////////////////////////////////////////////////////////
// io
///////////////////////////////////////////////////////////////
public void write(DataOutputStream dos) throws IOException
{
write(dos,VERSION);
}
public void write(DataOutputStream dos, boolean verbose) throws IOException
{
write(dos,VERSION,verbose);
}
public void write(DataOutputStream dos, int v) throws IOException
{
write(dos,v,true);
}
public void write(DataOutputStream dos, int v, boolean verbose)
throws IOException
{
if (verbose) System.out.println(" writing info ("+v+") ...");
switch (v) {
case 1: dos.writeInt(v);
writeV1(dos);
break;
default: throw new IOException("unknown calc req version "+v);
}
}
private void writeV1(DataOutputStream dos) throws IOException
{
dos.writeLong(reqid);
dos.writeUTF(getXM().toString());
dos.writeUTF(getYM().toString());
dos.writeUTF(getDX().toString());
dos.writeUTF(getDY().toString());
dos.writeInt(getRX());
dos.writeInt(getRY());
dos.writeInt(getLimitIt());
dos.writeInt(getSX());
dos.writeInt(getSY());
dos.writeInt(getNX());
dos.writeInt(getNY());
dos.writeInt(getMinIt());
dos.writeInt(getMaxIt());
dos.writeLong(getNumIt());
dos.writeLong(getMTime());
dos.writeLong(getMCnt());
dos.writeLong(getCCnt());
if (data==null) dos.writeInt(0);
else {
dos.writeInt(data.length);
for (int i=0; i<data.length; i++)
dos.writeInt(data[i]);
}
}
public void read(DataInputStream dis) throws IOException
{
read(dis,true);
}
public void read(DataInputStream dis, boolean verbose) throws IOException
{
if (verbose) System.out.println(" reading info ...");
version=dis.readInt();
switch (version) {
case 1: readV1(dis);
break;
default: throw new IOException("unknown calc req version "+version);
}
}
private void readV1(DataInputStream dis) throws IOException
{
setReqId(dis.readLong());
// fixed format
setXM(new BigDecimal(dis.readUTF()));
setYM(new BigDecimal(dis.readUTF()));
setDX(new BigDecimal(dis.readUTF()));
setDY(new BigDecimal(dis.readUTF()));
setRX(dis.readInt());
setRY(dis.readInt());
setLimitIt(dis.readInt());
setSX(dis.readInt());
setSY(dis.readInt());
setNX(dis.readInt());
setNY(dis.readInt());
setMinIt(dis.readInt());
setMaxIt(dis.readInt());
setNumIt(dis.readLong());
setMTime(dis.readLong());
setMCnt(dis.readLong());
setCCnt(dis.readLong());
int len=dis.readInt();
if (len==0) data=null;
else {
data=new int[len];
for (int i=0; i<len; i++)
data[i]=dis.readInt();
}
}
/////////////////////////////////////////////////////////////
// State Change
/////////////////////////////////////////////////////////////
public void send(Server server)
{
server.sendRequest(this);
}
private StateChangeSupport listeners=new StateChangeSupport();
public void removeChangeListener(ChangeListener h)
{
listeners.removeChangeListener(h);
}
public void fireChangeEvent()
{
listeners.fireChangeEvent(this);
}
public void addChangeListener(ChangeListener h)
{
listeners.addChangeListener(h);
}
/////////////////////////////////////////////////////////////
// hash
/////////////////////////////////////////////////////////////
@Override
public boolean equals(Object obj)
{
if (obj==null) return false;
if (getClass()!=obj.getClass()) return false;
final CalcRequest other=(CalcRequest)obj;
if (this.reqid!=other.reqid) return false;
return true;
}
@Override
public int hashCode()
{
int hash=5;
hash=31*hash+(int)(this.reqid^(this.reqid>>>32));
return hash;
}
}