Created
February 25, 2010 18:54
-
-
Save dgladkov/314898 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package haven; | |
import static haven.MCache.cmaps; | |
import static haven.MCache.tilesz; | |
import java.security.*; | |
import java.util.*; | |
import java.net.*; | |
import java.io.*; | |
import java.awt.image.BufferedImage; | |
import javax.imageio.ImageIO; | |
public class MiniMap extends Widget { | |
static Map<String, Tex> grids = new WeakHashMap<String, Tex>(); | |
static Set<String> loading = new HashSet<String>(); | |
static Loader loader = new Loader(); | |
public static final Tex bg = Resource.loadtex("gfx/hud/mmap/ptex"); | |
public static final Tex nomap = Resource.loadtex("gfx/hud/mmap/nomap"); | |
public static final Resource plx = Resource.load("gfx/hud/mmap/x"); | |
MapView mv; | |
static class Loader implements Runnable { | |
Thread me = null; | |
private InputStream getreal(String nm) throws IOException { | |
URL url = new URL(Config.mapurl, nm + ".png"); | |
URLConnection c = url.openConnection(); | |
c.addRequestProperty("User-Agent", "Haven/1.0"); | |
InputStream s = c.getInputStream(); | |
/* | |
* I've commented this out, since it seems that the JNLP | |
* PersistenceService (or at least Sun's implementation of | |
* it) is SLOWER THAN SNAILS, so this caused more problems | |
* than it solved. | |
* | |
if(ResCache.global != null) { | |
StreamTee tee = new StreamTee(s); | |
tee.setncwe(); | |
tee.attach(ResCache.global.store("mm/" + nm)); | |
s = tee; | |
} | |
*/ | |
return(s); | |
} | |
private InputStream getcached(String nm) throws IOException { | |
if(ResCache.global == null) | |
throw(new FileNotFoundException("No resource cache installed")); | |
return(ResCache.global.fetch("mm/" + nm)); | |
} | |
public void run() { | |
try { | |
while(true) { | |
String grid; | |
synchronized(grids) { | |
grid = null; | |
for(String cg : loading) { | |
grid = cg; | |
break; | |
} | |
} | |
if(grid == null) | |
break; | |
try { | |
InputStream in; | |
try { | |
in = getcached(grid); | |
} catch(FileNotFoundException e) { | |
in = in = new MiniMap.MapFragmentInputStream(getreal(grid), Config.mapdir + "/" + grid + ".png"); | |
} | |
BufferedImage img; | |
try { | |
img = ImageIO.read(in); | |
} finally { | |
Utils.readtileof(in); | |
in.close(); | |
} | |
Tex tex = new TexI(img); | |
synchronized(grids) { | |
grids.put(grid, tex); | |
loading.remove(grid); | |
} | |
} catch(IOException e) { | |
synchronized(grids) { | |
grids.put(grid, null); | |
loading.remove(grid); | |
} | |
} | |
} | |
} finally { | |
synchronized(this) { | |
me = null; | |
} | |
} | |
} | |
void start() { | |
synchronized(this) { | |
if(me == null) { | |
me = new HackThread(this, "Minimap loader"); | |
me.setDaemon(true); | |
me.start(); | |
} | |
} | |
} | |
void req(String nm) { | |
synchronized(grids) { | |
if(loading.contains(nm)) | |
return; | |
loading.add(nm); | |
start(); | |
} | |
} | |
} | |
public MiniMap(Coord c, Coord sz, Widget parent, MapView mv) { | |
super(c, sz, parent); | |
this.mv = mv; | |
} | |
public static Tex getgrid(final String nm) { | |
return(AccessController.doPrivileged(new PrivilegedAction<Tex>() { | |
public Tex run() { | |
synchronized(grids) { | |
if(grids.containsKey(nm)) { | |
return(grids.get(nm)); | |
} else { | |
loader.req(nm); | |
return(null); | |
} | |
} | |
} | |
})); | |
} | |
public void draw(GOut g) { | |
Coord tc = mv.mc.div(tilesz); | |
Coord ulg = tc.div(cmaps); | |
while((ulg.x * cmaps.x) - tc.x + (sz.x / 2) > 0) | |
ulg.x--; | |
while((ulg.y * cmaps.y) - tc.y + (sz.y / 2) > 0) | |
ulg.y--; | |
boolean missing = false; | |
g.image(bg, Coord.z); | |
outer: | |
for(int y = ulg.y; (y * cmaps.y) - tc.y + (sz.y / 2) < sz.y; y++) { | |
for(int x = ulg.x; (x * cmaps.x) - tc.x + (sz.x / 2) < sz.x; x++) { | |
Coord cg = new Coord(x, y); | |
MCache.Grid grid; | |
synchronized(ui.sess.glob.map.req) { | |
synchronized(ui.sess.glob.map.grids) { | |
grid = ui.sess.glob.map.grids.get(cg); | |
if(grid == null) | |
ui.sess.glob.map.request(cg); | |
} | |
} | |
if(grid == null) | |
continue; | |
if(grid.mnm == null) { | |
missing = true; | |
break outer; | |
} | |
MapFragmentCoordsWriter.getInstance().writeMapFragmentCoords(grid.mnm, cg); | |
Tex tex = getgrid(grid.mnm); | |
if(tex == null) | |
continue; | |
g.image(tex, cg.mul(cmaps).add(tc.inv()).add(sz.div(2))); | |
} | |
} | |
if(missing) { | |
g.image(nomap, Coord.z); | |
} else { | |
if(!plx.loading) { | |
synchronized(ui.sess.glob.party.memb) { | |
for(Party.Member m : ui.sess.glob.party.memb.values()) { | |
Coord ptc = m.getc(); | |
if(ptc == null) | |
continue; | |
ptc = ptc.div(tilesz).add(tc.inv()).add(sz.div(2)); | |
g.chcolor(m.col.getRed(), m.col.getGreen(), m.col.getBlue(), 128); | |
g.image(plx.layer(Resource.imgc).tex(), ptc.add(plx.layer(Resource.negc).cc.inv())); | |
g.chcolor(); | |
} | |
} | |
} | |
} | |
super.draw(g); | |
} | |
private static final class MapFragmentInputStream extends InputStream | |
{ | |
private InputStream input; | |
private FileOutputStream output; | |
public MapFragmentInputStream(InputStream mapInputStream, String fileName) | |
{ | |
try | |
{ | |
this.output = new FileOutputStream(fileName); | |
} catch (FileNotFoundException e) { | |
} | |
this.input = mapInputStream; | |
} | |
public int read() throws IOException { | |
int b = this.input.read(); | |
if (b != -1) { | |
this.output.write(b); | |
this.output.flush(); | |
} | |
return b; | |
} | |
} | |
public static final class MapFragmentCoordsWriter | |
{ | |
private static MapFragmentCoordsWriter _instance = new MapFragmentCoordsWriter(); | |
Hashtable coordsHash; | |
File coordsFile; | |
public MapFragmentCoordsWriter() | |
{ | |
this.coordsHash = new Hashtable(); | |
this.coordsFile = new File(Config.mapdir + "/fragdata" + System.currentTimeMillis() + ".txt"); } | |
public static MapFragmentCoordsWriter getInstance() { | |
return _instance; | |
} | |
public synchronized void writeMapFragmentCoords(String fragmentID, Coord coords) { | |
if (!(this.coordsHash.containsKey(fragmentID))) { | |
this.coordsHash.put(fragmentID, coords); | |
try { | |
FileWriter out = new FileWriter(this.coordsFile, true); | |
out.write(fragmentID + ";" + coords.x + "," + coords.y + "\n"); | |
out.flush(); | |
} catch (IOException e) { | |
} | |
} | |
} | |
public synchronized void beginNewSession() { | |
this.coordsFile = new File(Config.mapdir + "/fragdata" + System.currentTimeMillis() + ".txt"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment