Inter-operate between libGDX and jdkgdxds
There's several collection types in libGDX that have no convenient way to interoperate with the
JDK interfaces. ObjectMap doesn't implement Map, Array doesn't implement List, and in general nothing more than
Iterable is available. But, libGDX also provides its Json class and related code, which is a nice way of serializing
data so that all platforms can both read and write it.
The new jdkgdxds library takes the JDK interfaces like Map and List,
applies them to data structures closely derived from the libGDX ones, and then keeps going to extend the data structure
coverage to things like insertion-ordered long-to-float maps and case-insensitive sets of CharSequence items. It does
not have a way to serialize to JSON out-of-the-box, though things that can serialize the JDK interfaces can at least
write and read the all-Object types like ObjectList, ObjectObjectMap and ObjectOrderedSet.
Here's jdkgdxds_interop, for conversions both ways between jdkgdxds and libGDX data structures, and also to write the
jdkgdxds data structures using libGDX's Json. This consists of just three classes, all in the
com.github.tommyettinger.ds.interop package. ConversionToGDX has methods that take any class that implements one of
the JDK or one of jdkgdxds' interfaces, like Collection or PrimitiveCollection.OfLong, and converts it to a narrower
libGDX data structure. ConversionToJDK has methods that take a specific libGDX class, typically, and convert it to a
similar jdkgdxds data structure. JsonSupport is probably the star of the show, and allows registering serializers on a
Json object, so it can read and write jdkgdxds types. This registration could be all at once, using registerAll(),
or one at a time using any of its other methods.
The Json serialization also uses an especially-concise format to store each of the EnhancedRandom implementations in
juniper. Even though juniper is not a direct dependency of jdkgdxds, it used
to be part of that library, and its use is recommended with any of the randomized methods in jdkgdxds, so it still makes
sense to have here. These classes (DistinctRandom, LaserRandom, TricycleRandom, uhh... there's a lot in the
com.github.tommyettinger.random package) are sometimes serializable
without jdkgdxds-interop, but work regardless of JDK version if
you do use this library. Better still, you can register EnhancedRandom for serialization, so places that have an
EnhancedRandom but don't specify an implementation can still store one (which includes its implementing class) and
read an EnhancedRandom back. If you have your own class that extends java.util.Random, which is admittedly unlikely,
you should probably write your own serializer modeled after the serializer for the RandomXS128 class in libGDX here.
Java 17 and higher block libGDX's Json class from accessing the state of java.util.Random, which also prevents any
serialization of subclasses unless they use custom serialization. This also means that java.util.Random can't be
serialized or deserialized by libGDX Json on JDK 17 or higher, even with a custom serializer, unless some special
additional work happens (and even that might not work on future JDKs). digital's AlternateRandom class is also now
serializable here; its algorithm is the same as PasarRandom from juniper, but it doesn't have as many features, so
simply using PasarRandom is preferable if you depend on juniper anyway.
Starting with juniper 0.1.0, it now contains quite a few statistical distributions, each of which stores some parameter
or parameters and an EnhancedRandom to generate numbers. These can all be registered individually or as a group by
JsonSupport.registerDistribution(). Once registered, you can store a Distribution much like an EnhancedRandom, and
it uses a similar compact storage system. You can also store a Distribution and deserialize it as a Distribution,
allowing any implementation to be fit into that variable.
The digital library is a direct dependency of jdkgdxds, and it has the
Hasher, Interpolator, and AlternateRandom classes that can be registered, as well as a Base class. Base is
especially important here because you can
configure the numeral base that numbers are printed in by specifying one to JsonSupport.setNumeralBase(Base); this can
be handy to weakly obfuscate numbers if you pass a scrambled base (as Base can generate).
The Json flavor in libGDX allows specifying class tags as a kind of shorter alias for a package-qualified class name. As
of jdkgdxds-interop 1.1.1.1, when registering any class, this will add a very short class tag unless you had previously
called JsonSupport.setAddClassTags(false);. The class tags can be hard to read if you want human-readable JSON files,
but long packages add to file size and can also be strenuous to read repeatedly. Class tags are added by default.
The Gradle dependency, with the usual caveats about optionally replacing implementation with api if other dependency
lines do the same, is:
implementation "com.github.tommyettinger:jdkgdxds_interop:2.1.3.2"It's not unlikely that you might need api instead of implementation, especially if you are writing a library, or a
module that needs to be used from another section.
This library currently depends on libGDX 1.14.2, and uses its Json class heavily. Newer versions should be checked for
any breaking changes that can affect Json or the classes that ConversionToJDK/ConversionToGDX handle.
If you use GWT (libGDX's HTML target), then you also need this in your html/build.gradle file:
implementation "com.badlogicgames.gdx:gdx:1.14.2:sources"
implementation "com.github.tommyettinger:funderby:0.1.2:sources"
implementation "com.github.tommyettinger:digital:0.10.0:sources"
implementation "com.github.tommyettinger:juniper:0.10.3:sources"
implementation "com.github.tommyettinger:jdkgdxds:2.1.3:sources"
implementation "com.github.tommyettinger:jdkgdxds_interop:2.1.3.2:sources"Newer versions of funderby, digital, and possibly juniper and jdkgdxds may be usable as well.
You also need the GWT inherits in your GdxDefinition.gwt.xml file:
<inherits name="com.badlogic.gdx.backends.gdx_backends_gwt" />
<inherits name="com.github.tommyettinger.funderby" />
<inherits name="com.github.tommyettinger.digital" />
<inherits name="com.github.tommyettinger.juniper" />
<inherits name="com.github.tommyettinger.jdkgdxds" />
<inherits name="com.github.tommyettinger.jdkgdxds_interop" />I hope that's all you need! It's a small-ish simple library!