How to avoid garbage collection when using Json? - libgdx

I'm currently loading my level with the Json classes. Problem is, the application lags at the beginning which is probably due to the GarbageCollector removing all my unused JsonValue objects. I don't currently know, how to fix this, any advice would be appreciated,
the WorldLoader class with the json stuff, code looks like much, but is pretty straight forward:
package com.Sidescroll.game.Helpers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.Sidescroll.game.GameObjects.Background;
import com.Sidescroll.game.GameObjects.Platform;
import com.Sidescroll.game.GameObjects.Player;
import com.Sidescroll.game.GameWorld.GameWorld;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.JsonReader;
import com.badlogic.gdx.utils.JsonValue;
public final class WorldLoader {
private WorldLoader() {}
public static HashMap<String, GameWorld> worlds = new HashMap<String, GameWorld>();
private static JsonValue jsonPlatforms, jsonSpawn, jsonBackgrounds;
public static GameWorld loadWorld(String levelName) {
if(worlds.get(levelName) != null) return worlds.get(levelName);
//load json file
FileHandle handle = Gdx.files.internal("levels/" + levelName + ".json");
String fileContent = handle.readString();
JsonValue json = new JsonReader().parse(fileContent);
jsonPlatforms = json.get("platforms");
jsonBackgrounds = json.get("backgrounds");
jsonSpawn = json.get("spawn");
//loads platforms
List<Platform> platforms = new ArrayList<Platform>();
for(JsonValue pValue : jsonPlatforms.iterator()) {
Platform platform = new Platform(pValue.getInt("x"),
pValue.getInt("y"),
pValue.getInt("width"),
pValue.getInt("height"),
Platform.Type.valueOf(Platform.Type.class, pValue.getString("type")),
pValue.getString("variant"));
platforms.add(platform);
}
//create player
Vector2 vecSpawn = new Vector2(jsonSpawn.getInt("x"), jsonSpawn.getInt("y"));
Player player = new Player(vecSpawn, platforms);
//loads backgrounds
List<Background> backgrounds = new ArrayList<Background>();
for(JsonValue bgValue : jsonBackgrounds.iterator()) {
Background bg = new Background("bin/sprites/" + bgValue.getString("name") + ".png",
bgValue.getInt("x"),
bgValue.getInt("y"),
bgValue.getInt("width"),
bgValue.getInt("height"),
bgValue.getBoolean("front"));
backgrounds.add(bg);
}
worlds.put(levelName, new GameWorld(player, platforms, backgrounds));
return worlds.get(levelName);
}
}

Related

Problem at scale: Jackson unable to resolve circular reference inspite of #JsonIdentityInfo when number of objects becomes large

Consider the simplified Kotlin code below wherein a circular reference is resolved during JSONification via #JsonIdentityInfo, when using Jackson. A class Index contains a list indices of other Indexes
import com.fasterxml.jackson.annotation.JsonIdentityInfo
import com.fasterxml.jackson.annotation.ObjectIdGenerators
import com.fasterxml.jackson.databind.ObjectMapper
import java.util.UUID
fun main() {
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator::class, property = "id")
class Index() {
val id = UUID.randomUUID()
val neighbours = mutableListOf<Index>()
}
val n=1000 //does work for n=100
val indices = List(n) {Index()}
indices.forEach { it.neighbours.addAll(indices) }
ObjectMapper().writeValueAsString(indices)
}
The serialization fails for n=1000 but doesn't for n=100 hinting at a scaling issue.
I have gone through several SO answers as well as a very nice Baeldung blog (also found via SO) but those didn't help.
Why is there still a recursion error?
Interestingly the java version of the code works for both ns.
Is this a kotlin specific bug?
the gradle dependency being used
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.13.+"
java version
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class rough {
public static void main(String[] args) throws JsonProcessingException {
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
class Index {
public UUID id = UUID.randomUUID();
List<Index> neighbours = new ArrayList<>();
}
var n = 1000;
List<Index> indices = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
indices.add(new Index());
}
indices.forEach(index -> index.neighbours.addAll(indices));
new ObjectMapper().writeValueAsString(indices);
}
}

Adobe Animate Starling Error

I have created hungryherogame (recreate) in adobe animate using starling framework..
download from this address below :
( http://www.test.farsvila.ir/animate_starling_Error.rar )
package {
import flash.display3D.textures.Texture;
import flash.utils.Dictionary;
import flash.display.Bitmap;
import starling.textures.Texture;
import starling.display.Sprite;
import starling.events.Event;
import starling.display.Image;
import starling.display.Button;
import starling.core.Starling;
import starling.events.Event;
import screens.Welcome;
public class Assets {
[Embed(source = "media/graphics/bgWelcome.jpg")]
public static const BgWelcome: Class;
[Embed(source = "media/graphics/welcome_hero.png")]
public static const WelcomeHero: Class;
[Embed(source = "media/graphics/welcome_title.png")]
public static const WelcomeTitle: Class;
[Embed(source = "media/graphics/welcome_playButton.png")]
public static const WelcomePlayBtn: Class;
[Embed(source = "media/graphics/welcome_aboutButton.png")]
public static const WelcomeAboutBtn: Class;
private static var gameTextures: Dictionary = new Dictionary();
public static function getTexture(name: String): Texture {
if (gameTextures[name] == undefined) {
var bitmap: Bitmap = new Assets[name]();
gameTextures[name] = Texture.fromBitmap(bitmap);
}
return gameTextures[name];
}
}
}
Its made an error --> Call to a possibly undefined method fromBitmap through a reference with static type Class.
in first look, every thing is OK! according DOC fromBitmap is a public static member of starling.textures.Texture
but problem is because of import flash.display3D.textures.Texture which is out of code block in your post and make me hanged some minutes !
so in this case, we have same class names, two Textures. compiler get mixed up too (Ambiguous reference Error).
try it
Edited
public static function getTexture(name: String): starling.textures.Texture {
if (gameTextures[name] == undefined) {
var bitmap: Bitmap = new Assets[name]();
gameTextures[name] = starling.textures.Texture.fromBitmap(bitmap);
}
return gameTextures[name];
}
to make it clear for compiler, which Texture is your mean
Suggestion
i guess you don't really need import flash.display3D.textures.Texture;
so remove it from your default code (problem solved without changing Texture to starling.textures.Texture)

Is my code ineffecient or needing the garbage collector?

don't know if you're allowed to ask that here, but I wanted to know if my code is inefficient and leaves much work to the garbage collector, because I'm trying to find a source of lag in my game.
Heres the class, which loads the world through json files.
Worldloader.java:
package com.Sidescroll.game.Helpers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.Sidescroll.game.GameObjects.Background;
import com.Sidescroll.game.GameObjects.Platform;
import com.Sidescroll.game.GameObjects.Player;
import com.Sidescroll.game.GameWorld.GameWorld;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.JsonReader;
import com.badlogic.gdx.utils.JsonValue;
public final class WorldLoader {
private WorldLoader() {}
public static HashMap<String, GameWorld> worlds = new HashMap<String, GameWorld>();
private static JsonValue jsonPlatforms, jsonSpawn, jsonBackgrounds;
public static GameWorld loadWorld(String levelName) {
if(worlds.get(levelName) != null) return worlds.get(levelName);
//load json file
FileHandle handle = Gdx.files.internal("levels/" + levelName + ".json");
String fileContent = handle.readString();
JsonValue json = new JsonReader().parse(fileContent);
jsonPlatforms = json.get("platforms");
jsonBackgrounds = json.get("backgrounds");
jsonSpawn = json.get("spawn");
//loads platforms
List<Platform> platforms = new ArrayList<Platform>();
for(JsonValue pValue : jsonPlatforms.iterator()) {
Platform platform = new Platform(pValue.getInt("x"),
pValue.getInt("y"),
pValue.getInt("width"),
pValue.getInt("height"),
Platform.Type.valueOf(Platform.Type.class, pValue.getString("type")),
pValue.getString("variant"));
platforms.add(platform);
}
//create player
Vector2 vecSpawn = new Vector2(jsonSpawn.getInt("x"), jsonSpawn.getInt("y"));
Player player = new Player(vecSpawn, platforms);
//loads backgrounds
List<Background> backgrounds = new ArrayList<Background>();
for(JsonValue bgValue : jsonBackgrounds.iterator()) {
Background bg = new Background("bin/sprites/" + bgValue.getString("name") + ".png",
bgValue.getInt("x"),
bgValue.getInt("y"),
bgValue.getInt("width"),
bgValue.getInt("height"),
bgValue.getBoolean("front"));
backgrounds.add(bg);
}
worlds.put(levelName, new GameWorld(player, platforms, backgrounds));
return worlds.get(levelName);
}
}

How can I extract xades signed content in Java xades4j?

I have got xades XML as InputStream. I do not care if certyficates are valid, check sign, etc. I can't provide any CA or any other type of certificate storage/validation. What I need is just get documents embedded in xades file as streams or temporary files on disk so I can process them as they were plain files from disk. Could someone provide snippet that extracts embedded documents? TIA
To extract Base64-encoded signed content from XAdES signed file i use code like below. It doesn't use xades4j at all.
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.bouncycastle.util.encoders.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Utils {
/**
* extract ds:Object from .xades file
*
* #param xadesIn .xades file input stream
* #return base64 decoded bytes
* #throws Exception
*/
public static byte[] extractContentFromXadesSignedFile(InputStream xadesIn) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(xadesIn);
xadesIn.close();
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext(new SimpleNamespaceContext(new HashMap<String, String>() {{
put("ds", "http://www.w3.org/2000/09/xmldsig#");
}}));
XPathExpression expr = xpath.compile("//ds:SignedInfo/ds:Reference");
NodeList referenceNodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
/**
* loop over all Reference nodes
* i need to find Object node with Id that fits URI value of Reference
*/
for(int i=0;i<referenceNodes.getLength();i++){
Node referenceNode = referenceNodes.item(i);
NamedNodeMap attributes = referenceNode.getAttributes();
if(attributes != null) {
Node uri = attributes.getNamedItem("URI");
if(uri != null) {
String objectId = uri.getNodeValue();
XPathExpression expr2 = xpath.compile("//ds:Object[#Id='"+objectId.substring(1)+"']");
Node contentNode = (Node) expr2.evaluate(doc, XPathConstants.NODE);
if(contentNode != null) {
String base64 = contentNode.getFirstChild().getNodeValue();
return Base64.decode(base64);
}
}
}
}
return null;
}
/**
* http://stackoverflow.com/a/6392700/404395
*/
private static class SimpleNamespaceContext implements NamespaceContext {
private final Map<String, String> PREF_MAP = new HashMap<String, String>();
public SimpleNamespaceContext(final Map<String, String> prefMap) {
PREF_MAP.putAll(prefMap);
}
#Override
public String getNamespaceURI(String prefix) {
return PREF_MAP.get(prefix);
}
#Override
public String getPrefix(String uri) {
throw new UnsupportedOperationException();
}
#Override
public Iterator getPrefixes(String uri) {
throw new UnsupportedOperationException();
}
}
}
Sample usage of that:
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Test;
public class XadesExtractTest {
#Test
public void extract() throws Exception {
InputStream in = XadesExtractTest.class.getClassLoader().getResourceAsStream("test.xades");
byte[] bytes = Utils.extractContentFromXadesSignedFile(in);
Assert.assertNotNull(bytes);
in.close();
ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
File f = File.createTempFile("test", ".zip");
System.out.println(f.getAbsolutePath());
FileOutputStream fout = new FileOutputStream(f);
IOUtils.copy(bin, fout);
bin.close();
fout.close();
}
}

Converting a Jpeg into an uncompressed tiff image

I found this code on StackOverflow
import java.io.File;
import java.io.FileOutputStream;
import java.awt.image.RenderedImage;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.media.jai.NullOpImage;
import javax.media.jai.OpImage;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.TIFFDecodeParam;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.ImageCodec;
public class Main {
public static void main(String args[]) {
File file = new File("input.tif");
try {
SeekableStream s = new FileSeekableStream(file);
TIFFDecodeParam param = null;
ImageDecoder dec = ImageCodec.createImageDecoder("tiff", s, param);
RenderedImage op = new NullOpImage(dec.decodeAsRenderedImage(0),
null,
OpImage.OP_IO_BOUND,
null);
FileOutputStream fos = new FileOutputStream("output.jpg");
JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(fos);
jpeg.encode(op.getData());
fos.close();
}
catch (java.io.IOException ioe) {
System.out.println(ioe);
}
}
}
I have been trying to reverse this process - convert jpg to uncompressed tiff but but I cant seem to get it to work.
Any ideas?