fixed formatting
This commit is contained in:
parent
e8f76d43fe
commit
dccec876c5
File diff suppressed because it is too large
Load Diff
@ -4,12 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.lwjgl3.utils;
|
package com.jme3.lwjgl3.utils;
|
||||||
|
|
||||||
import com.jme3.lwjgl3.utils.APIBuffer;
|
|
||||||
import org.lwjgl.system.linux.LinuxLibrary;
|
|
||||||
import org.lwjgl.system.macosx.MacOSXLibrary;
|
|
||||||
import org.lwjgl.system.windows.WindowsLibrary;
|
|
||||||
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -20,173 +14,205 @@ import java.util.regex.Pattern;
|
|||||||
/**
|
/**
|
||||||
* Utility class useful to API bindings. [INTERNAL USE ONLY]
|
* Utility class useful to API bindings. [INTERNAL USE ONLY]
|
||||||
*
|
*
|
||||||
* <p>Method names in this class are prefixed with {@code api} to avoid ambiguities when used with static imports.</p>
|
* <p>
|
||||||
|
* Method names in this class are prefixed with {@code api} to avoid ambiguities
|
||||||
|
* when used with static imports.</p>
|
||||||
*/
|
*/
|
||||||
public final class APIUtil {
|
public final class APIUtil {
|
||||||
|
|
||||||
private static final ThreadLocal<APIBuffer> API_BUFFERS = new ThreadLocal<APIBuffer>() {
|
private static final ThreadLocal<APIBuffer> API_BUFFERS = new ThreadLocal<APIBuffer>() {
|
||||||
@Override
|
@Override
|
||||||
protected APIBuffer initialValue() {
|
protected APIBuffer initialValue() {
|
||||||
return new APIBuffer();
|
return new APIBuffer();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private APIUtil() {
|
private APIUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a thread-local {@link APIBuffer} that has been reset.
|
||||||
|
*/
|
||||||
|
public static APIBuffer apiBuffer() {
|
||||||
|
return API_BUFFERS.get().reset();
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns a thread-local {@link APIBuffer} that has been reset. */
|
/**
|
||||||
public static APIBuffer apiBuffer() {
|
* Returns a thread-local {@link APIBuffer}, without resetting it. This
|
||||||
return API_BUFFERS.get().reset();
|
* makes the APIBuffer work like a stack when used in nested API calls. The
|
||||||
}
|
* user is responsible for resetting the {@link APIBuffer} to an appropriate
|
||||||
|
* state before the nested call returns.
|
||||||
|
*
|
||||||
|
* @see APIBuffer#pop
|
||||||
|
*/
|
||||||
|
public static APIBuffer apiStack() {
|
||||||
|
return API_BUFFERS.get().push();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a thread-local {@link APIBuffer}, without resetting it. This makes the APIBuffer work like a stack when used in nested API calls. The user is
|
* A data class for API versioning information.
|
||||||
* responsible for resetting the {@link APIBuffer} to an appropriate state before the nested call returns.
|
*/
|
||||||
*
|
public static class APIVersion {
|
||||||
* @see APIBuffer#pop
|
|
||||||
*/
|
|
||||||
public static APIBuffer apiStack() {
|
|
||||||
return API_BUFFERS.get().push();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A data class for API versioning information. */
|
/**
|
||||||
public static class APIVersion {
|
* Returns the API major version.
|
||||||
|
*/
|
||||||
|
public final int major;
|
||||||
|
/**
|
||||||
|
* Returns the API minor version.
|
||||||
|
*/
|
||||||
|
public final int minor;
|
||||||
|
|
||||||
/** Returns the API major version. */
|
/**
|
||||||
public final int major;
|
* Returns the API revision. May be null.
|
||||||
/** Returns the API minor version. */
|
*/
|
||||||
public final int minor;
|
public final String revision;
|
||||||
|
/**
|
||||||
|
* Returns the API implementation-specific versioning information. May
|
||||||
|
* be null.
|
||||||
|
*/
|
||||||
|
public final String implementation;
|
||||||
|
|
||||||
/** Returns the API revision. May be null. */
|
public APIVersion(int major, int minor) {
|
||||||
public final String revision;
|
this(major, minor, null, null);
|
||||||
/** Returns the API implementation-specific versioning information. May be null. */
|
}
|
||||||
public final String implementation;
|
|
||||||
|
|
||||||
public APIVersion(int major, int minor) {
|
public APIVersion(int major, int minor, String revision, String implementation) {
|
||||||
this(major, minor, null, null);
|
this.major = major;
|
||||||
}
|
this.minor = minor;
|
||||||
|
this.revision = revision;
|
||||||
|
this.implementation = implementation;
|
||||||
|
}
|
||||||
|
|
||||||
public APIVersion(int major, int minor, String revision, String implementation) {
|
}
|
||||||
this.major = major;
|
|
||||||
this.minor = minor;
|
|
||||||
this.revision = revision;
|
|
||||||
this.implementation = implementation;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Parses a version string. The version string must have the format
|
||||||
|
* {@code MAJOR.MINOR.REVISION IMPL}, where {@code MAJOR} is the major
|
||||||
|
* version (integer), {@code MINOR} is the minor version (integer),
|
||||||
|
* {@code REVISION} is the revision version (string, optional) and
|
||||||
|
* {@code IMPL} is implementation-specific information (string, optional).
|
||||||
|
*
|
||||||
|
* @param version the API version string
|
||||||
|
*
|
||||||
|
* @return the parsed {@link APIVersion}
|
||||||
|
*/
|
||||||
|
public static APIVersion apiParseVersion(String version) {
|
||||||
|
return apiParseVersion(version, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a version string. The version string must have the format {@code MAJOR.MINOR.REVISION IMPL}, where {@code MAJOR} is the major version (integer),
|
* Parses a version string. The version string must have the format
|
||||||
* {@code MINOR} is the minor version (integer), {@code REVISION} is the revision version (string, optional) and {@code IMPL} is implementation-specific
|
* {@code PREFIX MAJOR.MINOR.REVISION IMPL}, where {@code PREFIX} is the
|
||||||
* information (string, optional).
|
* specified prefix (string, optional), {@code MAJOR} is the major version
|
||||||
*
|
* (integer), {@code MINOR} is the minor version (integer), {@code REVISION}
|
||||||
* @param version the API version string
|
* is the revision version (string, optional) and {@code IMPL} is
|
||||||
*
|
* implementation-specific information (string, optional).
|
||||||
* @return the parsed {@link APIVersion}
|
*
|
||||||
*/
|
* @param version the version string
|
||||||
public static APIVersion apiParseVersion(String version) {
|
* @param prefix the version string prefix, may be null
|
||||||
return apiParseVersion(version, null);
|
*
|
||||||
}
|
* @return the parsed {@link APIVersion}
|
||||||
|
*/
|
||||||
|
public static APIVersion apiParseVersion(String version, String prefix) {
|
||||||
|
String pattern = "([0-9]+)[.]([0-9]+)([.]\\S+)?\\s*(.+)?";
|
||||||
|
if (prefix != null) {
|
||||||
|
pattern = prefix + "\\s+" + pattern;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
Matcher matcher = Pattern.compile(pattern).matcher(version);
|
||||||
* Parses a version string. The version string must have the format {@code PREFIX MAJOR.MINOR.REVISION IMPL}, where {@code PREFIX} is the specified prefix
|
if (!matcher.matches()) {
|
||||||
* (string, optional), {@code MAJOR} is the major version (integer), {@code MINOR} is the minor version (integer), {@code REVISION} is the revision version
|
throw new IllegalArgumentException(String.format("Malformed API version string [%s]", version));
|
||||||
* (string, optional) and {@code IMPL} is implementation-specific information (string, optional).
|
}
|
||||||
*
|
|
||||||
* @param version the version string
|
|
||||||
* @param prefix the version string prefix, may be null
|
|
||||||
*
|
|
||||||
* @return the parsed {@link APIVersion}
|
|
||||||
*/
|
|
||||||
public static APIVersion apiParseVersion(String version, String prefix) {
|
|
||||||
String pattern = "([0-9]+)[.]([0-9]+)([.]\\S+)?\\s*(.+)?";
|
|
||||||
if ( prefix != null )
|
|
||||||
pattern = prefix + "\\s+" + pattern;
|
|
||||||
|
|
||||||
Matcher matcher = Pattern.compile(pattern).matcher(version);
|
return new APIVersion(
|
||||||
if ( !matcher.matches() )
|
Integer.parseInt(matcher.group(1)),
|
||||||
throw new IllegalArgumentException(String.format("Malformed API version string [%s]", version));
|
Integer.parseInt(matcher.group(2)),
|
||||||
|
matcher.group(3),
|
||||||
|
matcher.group(4)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return new APIVersion(
|
public static String apiUnknownToken(int token) {
|
||||||
Integer.parseInt(matcher.group(1)),
|
return apiUnknownToken("Unknown", token);
|
||||||
Integer.parseInt(matcher.group(2)),
|
}
|
||||||
matcher.group(3),
|
|
||||||
matcher.group(4)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String apiUnknownToken(int token) {
|
public static String apiUnknownToken(String description, int token) {
|
||||||
return apiUnknownToken("Unknown", token);
|
return String.format("%s [0x%X]", description, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String apiUnknownToken(String description, int token) {
|
/**
|
||||||
return String.format("%s [0x%X]", description, token);
|
* Returns a map of public static final integer fields in the specified
|
||||||
}
|
* classes, to their String representations. An optional filter can be
|
||||||
|
* specified to only include specific fields. The target map may be null, in
|
||||||
|
* which case a new map is allocated and returned.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This method is useful when debugging to quickly identify values returned
|
||||||
|
* from an API.</p>
|
||||||
|
*
|
||||||
|
* @param filter the filter to use (optional)
|
||||||
|
* @param target the target map (optional)
|
||||||
|
* @param tokenClasses the classes to get tokens from
|
||||||
|
*
|
||||||
|
* @return the token map
|
||||||
|
*/
|
||||||
|
public static Map<Integer, String> apiClassTokens(TokenFilter filter, Map<Integer, String> target, Class<?>... tokenClasses) {
|
||||||
|
if (target == null) {
|
||||||
|
target = new HashMap<Integer, String>(64);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
|
||||||
* Returns a map of public static final integer fields in the specified classes, to their String representations. An optional filter can be specified to
|
|
||||||
* only include specific fields. The target map may be null, in which case a new map is allocated and returned.
|
|
||||||
*
|
|
||||||
* <p>This method is useful when debugging to quickly identify values returned from an API.</p>
|
|
||||||
*
|
|
||||||
* @param filter the filter to use (optional)
|
|
||||||
* @param target the target map (optional)
|
|
||||||
* @param tokenClasses the classes to get tokens from
|
|
||||||
*
|
|
||||||
* @return the token map
|
|
||||||
*/
|
|
||||||
public static Map<Integer, String> apiClassTokens(TokenFilter filter, Map<Integer, String> target, Class<?>... tokenClasses) {
|
|
||||||
if ( target == null )
|
|
||||||
target = new HashMap<Integer, String>(64);
|
|
||||||
|
|
||||||
int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
|
for (Class<?> tokenClass : tokenClasses) {
|
||||||
|
if (tokenClass == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for ( Class<?> tokenClass : tokenClasses ) {
|
for (Field field : tokenClass.getDeclaredFields()) {
|
||||||
if ( tokenClass == null )
|
// Get only <public static final int> fields.
|
||||||
continue;
|
if ((field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class) {
|
||||||
|
try {
|
||||||
|
int value = field.getInt(null);
|
||||||
|
if (filter != null && !filter.accept(field, value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for ( Field field : tokenClass.getDeclaredFields() ) {
|
String name = target.get(value);
|
||||||
// Get only <public static final int> fields.
|
target.put(value, name == null ? field.getName() : name + "|" + field.getName());
|
||||||
if ( (field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class ) {
|
} catch (IllegalAccessException e) {
|
||||||
try {
|
// Ignore
|
||||||
int value = field.getInt(null);
|
}
|
||||||
if ( filter != null && !filter.accept(field, value) )
|
}
|
||||||
continue;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String name = target.get(value);
|
return target;
|
||||||
target.put(value, name == null ? field.getName() : name + "|" + field.getName());
|
}
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return target;
|
public static Class<?> apiOptionalClass(String className) {
|
||||||
}
|
try {
|
||||||
|
return Class.forName(className);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<?> apiOptionalClass(String className) {
|
/**
|
||||||
try {
|
* Simple interface for Field filtering.
|
||||||
return Class.forName(className);
|
*/
|
||||||
} catch (ClassNotFoundException e) {
|
public interface TokenFilter {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Simple interface for Field filtering. */
|
/**
|
||||||
public interface TokenFilter {
|
* Should return true if the specified Field passes the filter.
|
||||||
|
*
|
||||||
|
* @param field the Field to test
|
||||||
|
* @param value the integer value of the field
|
||||||
|
*
|
||||||
|
* @return true if the Field is accepted
|
||||||
|
*/
|
||||||
|
boolean accept(Field field, int value);
|
||||||
|
|
||||||
/**
|
}
|
||||||
* Should return true if the specified Field passes the filter.
|
|
||||||
*
|
|
||||||
* @param field the Field to test
|
|
||||||
* @param value the integer value of the field
|
|
||||||
*
|
|
||||||
* @return true if the Field is accepted
|
|
||||||
*/
|
|
||||||
boolean accept(Field field, int value);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user