/** * Create a new loading task. This task is meant to be executed concurrently. It will request the * required textures from the parent texture manager once the loading is progressed to this point. * * @param parserFactory the parser factory * @param atlasName the name of the atlas files * @param textureManager the parent texture manager * @param progressMonitor the monitor of the loading progress * @param taskExecutor the executor that takes care for executing further tasks. */ public TextureAtlasListXmlLoadingTask( @Nonnull final XmlPullParserFactory parserFactory, @Nonnull final String atlasName, @Nonnull final AbstractTextureManager<T> textureManager, @Nonnull final ProgressMonitor progressMonitor, @Nullable final Executor taskExecutor) { this.parserFactory = parserFactory; this.atlasName = atlasName; this.textureManager = textureManager; this.progressMonitor = progressMonitor; this.taskExecutor = taskExecutor; done = false; progressMonitor.setProgress(0.f); }
@Override public void run() { InputStream xmlStream = null; try { final XmlPullParser parser = parserFactory.newPullParser(); final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); xmlStream = classLoader.getResourceAsStream(atlasName + "-atlas.xml"); parser.setInput(xmlStream, "UTF-8"); int currentEvent = parser.nextTag(); int expectedAtlasCount = 0; @Nullable TextureAtlasFinalizeTask<T> currentTextureTask = null; while (currentEvent != XmlPullParser.END_DOCUMENT) { if (currentEvent == XmlPullParser.START_TAG) { final String tagName = parser.getName(); switch (tagName) { case "atlasList": expectedAtlasCount = getExpectedAtlasCount(parser, expectedAtlasCount); if (expectedAtlasCount > 0) { progressMonitor.setWeight(expectedAtlasCount); } break; case "atlas": @Nullable final String currentAtlasName = getAtlasTextureName(parser); if (currentAtlasName != null) { final FutureTask<T> preLoadTask = new FutureTask<>( new TextureAtlasPreLoadTask<>(textureManager, currentAtlasName)); if (taskExecutor == null) { preLoadTask.run(); } else { taskExecutor.execute(preLoadTask); } final float progressToAdd = (expectedAtlasCount == 0) ? 0.f : (1.f / expectedAtlasCount); currentTextureTask = new TextureAtlasFinalizeTask<>( preLoadTask, currentAtlasName, textureManager, progressMonitor, progressToAdd); } break; case "sprite": if (currentTextureTask != null) { transferSpriteData(parser, currentTextureTask); } break; } } else if (currentEvent == XmlPullParser.END_TAG) { final String tagName = parser.getName(); if ("atlas".equals(tagName)) { if (currentTextureTask != null) { textureManager.addUpdateTask(currentTextureTask); textureManager.addLoadingTask(currentTextureTask); currentTextureTask = null; } } else if ("atlasList".equals(tagName)) { break; } } currentEvent = parser.nextTag(); } } catch (@Nonnull final XmlPullParserException e) { LOGGER.error("Failed to load requested texture atlas: " + atlasName, e); } catch (@Nonnull final IOException e) { LOGGER.error("Reading error while loading texture atlas: " + atlasName, e); } finally { done = true; if (xmlStream != null) { try { xmlStream.close(); } catch (@Nonnull final IOException ignored) { } } } }