Skip to content

Commit 14ef460

Browse files
wrap the whole run() in try/catch so we can include the frame name (#145)
1 parent f19b49f commit 14ef460

File tree

1 file changed

+126
-122
lines changed

1 file changed

+126
-122
lines changed

src/main/java/org/inventivetalent/animatedframes/AnimatedFrame.java

Lines changed: 126 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -130,156 +130,160 @@ public AnimatedFrame(ItemFrame baseFrame, Vector3DDouble firstCorner, Vector3DDo
130130

131131
@Override
132132
public void run() {
133-
if (!imageLoaded) {
134-
MapManager mapManager = ((MapManagerPlugin) Bukkit.getPluginManager().getPlugin("MapManager")).getMapManager();
135-
try {
136-
File cacheDir = new File(new File(plugin.getDataFolder(), "cache"), this.name);
137-
if (!cacheDir.exists()) {
138-
cacheDir.mkdirs();
139-
140-
plugin.getLogger().info("Generating image data for " + getName() + "...");
141-
142-
File file = plugin.frameManager.downloadOrGetImage(this.imageSource);
143-
GifDecoder decoder = new GifDecoder();
144-
decoder.read(new FileInputStream(file));
145-
146-
if ((this.length = decoder.getFrameCount()) <= 0) {
147-
plugin.getLogger().info("Animation length for '" + getName() + "' is zero. Creating non-animated image.");
148-
this.length = 1;
149-
150-
BufferedImage image = ImageIO.read(file);
151-
if (image == null) {
152-
throw new RuntimeException("Failed to read the given image. Please make sure you're using a valid source");
133+
try {
134+
if (!imageLoaded) {
135+
MapManager mapManager = ((MapManagerPlugin) Bukkit.getPluginManager().getPlugin("MapManager")).getMapManager();
136+
try {
137+
File cacheDir = new File(new File(plugin.getDataFolder(), "cache"), this.name);
138+
if (!cacheDir.exists()) {
139+
cacheDir.mkdirs();
140+
141+
plugin.getLogger().info("Generating image data for " + getName() + "...");
142+
143+
File file = plugin.frameManager.downloadOrGetImage(this.imageSource);
144+
GifDecoder decoder = new GifDecoder();
145+
decoder.read(new FileInputStream(file));
146+
147+
if ((this.length = decoder.getFrameCount()) <= 0) {
148+
plugin.getLogger().info("Animation length for '" + getName() + "' is zero. Creating non-animated image.");
149+
this.length = 1;
150+
151+
BufferedImage image = ImageIO.read(file);
152+
if (image == null) {
153+
throw new RuntimeException("Failed to read the given image. Please make sure you're using a valid source");
154+
}
155+
image = scaleImage(image);
156+
MapWrapper mapWrapper = mapManager.wrapMultiImage(image, this.height, this.width);
157+
this.frameDelays = new int[] { 500 };
158+
this.mapWrappers = new MapWrapper[] { mapWrapper };
159+
image.flush();
160+
161+
File cacheFile = new File(cacheDir, this.name + "_0.afc");
162+
cacheFile.createNewFile();
163+
try (FileOutputStream out = new FileOutputStream(cacheFile)) {
164+
out.write(Ints.toByteArray(500));
165+
ArrayImage.writeMultiToSream(((MultiWrapper) mapWrapper).getMultiContent(), out);
166+
}
167+
} else {
168+
this.frameDelays = new int[this.length];
169+
this.mapWrappers = new MapWrapper[this.length];
170+
for (int i = 0; i < this.length; i++) {
171+
plugin.getLogger().info("Generating Frame " + (i + 1) + "/" + this.length + " for " + getName() + "...");
172+
173+
BufferedImage image = scaleImage(decoder.getFrame(i));
174+
int delay = decoder.getDelay(i);
175+
if (delay == 0) {
176+
plugin.getLogger().warning("Frame has no delay information, falling back to default (" + plugin.defaultDelay + ")");
177+
delay = plugin.defaultDelay;
178+
}
179+
this.frameDelays[i] = delay;
180+
MapWrapper wrapper = mapManager.wrapMultiImage(image, this.height, this.width);
181+
this.mapWrappers[i] = wrapper;
182+
image.flush();
183+
184+
File cacheFile = new File(cacheDir, this.name + "_" + i + ".afc");
185+
cacheFile.createNewFile();
186+
try (FileOutputStream out = new FileOutputStream(cacheFile)) {
187+
out.write(Ints.toByteArray(delay));
188+
ArrayImage.writeMultiToSream(((MultiWrapper) wrapper).getMultiContent(), out);
189+
}
190+
}
153191
}
154-
image = scaleImage(image);
155-
MapWrapper mapWrapper = mapManager.wrapMultiImage(image, this.height, this.width);
156-
this.frameDelays = new int[] { 500 };
157-
this.mapWrappers = new MapWrapper[] { mapWrapper };
158-
image.flush();
159-
160-
File cacheFile = new File(cacheDir, this.name + "_0.afc");
161-
cacheFile.createNewFile();
162-
try (FileOutputStream out = new FileOutputStream(cacheFile)) {
163-
out.write(Ints.toByteArray(500));
164-
ArrayImage.writeMultiToSream(((MultiWrapper) mapWrapper).getMultiContent(), out);
192+
193+
// Reset all images
194+
for (Object object : decoder.frames) {
195+
((GifDecoder.GifFrame) object).image.flush();
165196
}
197+
decoder.frames.clear();
198+
166199
} else {
200+
plugin.getLogger().info("Reading " + getName() + " from cache...");
201+
202+
String[] fileList = cacheDir.list();
203+
this.length = fileList.length;
167204
this.frameDelays = new int[this.length];
168205
this.mapWrappers = new MapWrapper[this.length];
169-
for (int i = 0; i < this.length; i++) {
170-
plugin.getLogger().info("Generating Frame " + (i + 1) + "/" + this.length + " for " + getName() + "...");
171206

172-
BufferedImage image = scaleImage(decoder.getFrame(i));
173-
int delay = decoder.getDelay(i);
174-
if (delay == 0) {
175-
plugin.getLogger().warning("Frame has no delay information, falling back to default (" + plugin.defaultDelay + ")");
176-
delay = plugin.defaultDelay;
177-
}
178-
this.frameDelays[i] = delay;
179-
MapWrapper wrapper = mapManager.wrapMultiImage(image, this.height, this.width);
180-
this.mapWrappers[i] = wrapper;
181-
image.flush();
207+
for (int i = 0; i < this.length; i++) {
208+
plugin.getLogger().info("Reading Frame " + (i + 1) + "/" + this.length + " of " + getName() + "...");
182209

183210
File cacheFile = new File(cacheDir, this.name + "_" + i + ".afc");
184211
cacheFile.createNewFile();
185-
try (FileOutputStream out = new FileOutputStream(cacheFile)) {
186-
out.write(Ints.toByteArray(delay));
187-
ArrayImage.writeMultiToSream(((MultiWrapper) wrapper).getMultiContent(), out);
212+
try (FileInputStream in = new FileInputStream(cacheFile)) {
213+
byte[] lengthBytes = new byte[4];
214+
in.read(lengthBytes, 0, 4);
215+
this.frameDelays[i] = Ints.fromByteArray(lengthBytes);
216+
217+
ArrayImage[][] images = ArrayImage.readMultiFromStream(in);
218+
this.mapWrappers[i] = mapManager.wrapMultiImage(images);
219+
} catch (IOException readE) {
220+
throw new RuntimeException("Your cached frame data appears to be invalid. Please delete the plugins/AnimatedFrames/cache directory and restart your server", readE);
188221
}
189222
}
190223
}
191224

192-
// Reset all images
193-
for (Object object : decoder.frames) {
194-
((GifDecoder.GifFrame) object).image.flush();
195-
}
196-
decoder.frames.clear();
197-
198-
} else {
199-
plugin.getLogger().info("Reading " + getName() + " from cache...");
200-
201-
String[] fileList = cacheDir.list();
202-
this.length = fileList.length;
203-
this.frameDelays = new int[this.length];
204-
this.mapWrappers = new MapWrapper[this.length];
205-
206-
for (int i = 0; i < this.length; i++) {
207-
plugin.getLogger().info("Reading Frame " + (i + 1) + "/" + this.length + " of " + getName() + "...");
208-
209-
File cacheFile = new File(cacheDir, this.name + "_" + i + ".afc");
210-
cacheFile.createNewFile();
211-
try (FileInputStream in = new FileInputStream(cacheFile)) {
212-
byte[] lengthBytes = new byte[4];
213-
in.read(lengthBytes, 0, 4);
214-
this.frameDelays[i] = Ints.fromByteArray(lengthBytes);
215-
216-
ArrayImage[][] images = ArrayImage.readMultiFromStream(in);
217-
this.mapWrappers[i] = mapManager.wrapMultiImage(images);
218-
} catch (IOException readE) {
219-
throw new RuntimeException("Your cached frame data appears to be invalid. Please delete the plugins/AnimatedFrames/cache directory and restart your server", readE);
220-
}
221-
}
225+
imageLoaded = true;
226+
} catch (IOException e) {
227+
plugin.getLogger().log(Level.SEVERE, "Failed to load image '" + getName() + "'", e);
228+
throw new RuntimeException("Failed to load image");
222229
}
223-
224-
imageLoaded = true;
225-
} catch (IOException e) {
226-
plugin.getLogger().log(Level.SEVERE, "Failed to load image '" + getName() + "'", e);
227-
throw new RuntimeException("Failed to load image");
228230
}
229-
}
230231

231-
while (!this.playing) {
232-
try {
233-
Thread.sleep(1000);
234-
} catch (InterruptedException e) {
235-
plugin.getLogger().warning("playing-delay for '" + getName() + "' has been interrupted");
236-
return;
237-
}
238-
}
239-
240-
if (AnimatedFramesPlugin.synchronizedStart) {
241-
while (System.currentTimeMillis() < AnimatedFramesPlugin.synchronizedTime) {
232+
while (!this.playing) {
242233
try {
243-
Thread.sleep(1);
234+
Thread.sleep(1000);
244235
} catch (InterruptedException e) {
245-
plugin.getLogger().warning("synchronized start delay for '" + getName() + "' has been interrupted");
236+
plugin.getLogger().warning("playing-delay for '" + getName() + "' has been interrupted");
246237
return;
247238
}
248239
}
249-
}
250240

251-
while (this.playing && this.plugin.isEnabled()) {
252-
if (startCallback != null) {
253-
startCallback.call(null);
254-
startCallback = null;
255-
}
256-
257-
if (timeSinceLastRefresh++ > 10000) {
258-
timeSinceLastRefresh = 0;
259-
refresh();
260-
}
261-
if (delayTicks++ >= this.frameDelays[this.currentFrame]) {
262-
delayTicks = 0;
263-
if (Bukkit.getOnlinePlayers().isEmpty()) {
241+
if (AnimatedFramesPlugin.synchronizedStart) {
242+
while (System.currentTimeMillis() < AnimatedFramesPlugin.synchronizedTime) {
264243
try {
265-
Thread.sleep(2000);
244+
Thread.sleep(1);
266245
} catch (InterruptedException e) {
267-
plugin.getLogger().warning("Animation thread for " + getName() + " interrupted");
246+
plugin.getLogger().warning("synchronized start delay for '" + getName() + "' has been interrupted");
247+
return;
268248
}
269-
continue;
249+
}
250+
}
251+
252+
while (this.playing && this.plugin.isEnabled()) {
253+
if (startCallback != null) {
254+
startCallback.call(null);
255+
startCallback = null;
270256
}
271257

272-
displayCurrentFrame();
258+
if (timeSinceLastRefresh++ > 10000) {
259+
timeSinceLastRefresh = 0;
260+
refresh();
261+
}
262+
if (delayTicks++ >= this.frameDelays[this.currentFrame]) {
263+
delayTicks = 0;
264+
if (Bukkit.getOnlinePlayers().isEmpty()) {
265+
try {
266+
Thread.sleep(2000);
267+
} catch (InterruptedException e) {
268+
plugin.getLogger().warning("Animation thread for " + getName() + " interrupted");
269+
}
270+
continue;
271+
}
273272

274-
this.currentFrame++;
275-
if (this.currentFrame >= this.length) { this.currentFrame = 0; }
276-
}
277-
try {
278-
Thread.sleep(1);
279-
} catch (InterruptedException e) {
280-
plugin.getLogger().log(Level.WARNING, "Frame interrupted", e);
281-
}
273+
displayCurrentFrame();
282274

275+
this.currentFrame++;
276+
if (this.currentFrame >= this.length) { this.currentFrame = 0; }
277+
}
278+
try {
279+
Thread.sleep(1);
280+
} catch (InterruptedException e) {
281+
plugin.getLogger().log(Level.WARNING, "Frame interrupted", e);
282+
}
283+
284+
}
285+
} catch (Throwable e) {
286+
throw new RuntimeException("Unexpected exception in AnimatedFrame " + name, e);
283287
}
284288
}
285289

@@ -468,7 +472,7 @@ public boolean isClickable() {
468472

469473
@Override
470474
public void handleClick(Player player, CursorPosition position, int action) {
471-
this.clickEvents.stream().filter(e -> e.contains(position.x, position.y)).forEach(e -> e.executeFor(player,this.plugin));
475+
this.clickEvents.stream().filter(e -> e.contains(position.x, position.y)).forEach(e -> e.executeFor(player, this.plugin));
472476
}
473477

474478
@Override

0 commit comments

Comments
 (0)