Skip to content

Instantly share code, notes, and snippets.

@MobiDevelop
Created April 7, 2013 13:41
Show Gist options
  • Save MobiDevelop/5330543 to your computer and use it in GitHub Desktop.
Save MobiDevelop/5330543 to your computer and use it in GitHub Desktop.
Add a pluggable ChooserStrategy to the LibGDX ResolutionFileResolver, to allow the choosing algorithm to be changed by the user.
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.assets.loaders.resolvers;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.assets.loaders.resolvers.ResolutionFileResolver.Resolution;
import com.badlogic.gdx.files.FileHandle;
public class ResolutionFileResolver implements FileHandleResolver {
public static class Resolution {
public final int portraitWidth;
public final int portraitHeight;
public final String suffix;
public Resolution (int portraitWidth, int portraitHeight, String suffix) {
this.portraitWidth = portraitWidth;
this.portraitHeight = portraitHeight;
this.suffix = suffix;
}
}
protected final FileHandleResolver baseResolver;
protected final ChooserStrategy chooserStrategy;
protected final Resolution[] descriptors;
public ResolutionFileResolver (FileHandleResolver baseResolver, Resolution... descriptors) {
this.baseResolver = baseResolver;
this.chooserStrategy = ChooserStrategy.PreferLowerChooserStrategy;
this.descriptors = descriptors;
}
public ResolutionFileResolver (FileHandleResolver baseResolver, ChooserStrategy chooserStrategy, Resolution... descriptors) {
this.baseResolver = baseResolver;
this.chooserStrategy = chooserStrategy;
this.descriptors = descriptors;
}
@Override
public FileHandle resolve (String fileName) {
Resolution bestDesc = chooserStrategy.choose(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), descriptors);
FileHandle originalHandle = new FileHandle(fileName);
FileHandle handle = baseResolver.resolve(resolve(originalHandle, bestDesc.suffix));
if (!handle.exists()) handle = baseResolver.resolve(fileName);
return handle;
}
protected String resolve (FileHandle originalHandle, String suffix) {
return originalHandle.parent() + "/" + suffix + "/" + originalHandle.name();
}
public interface ChooserStrategy {
/**
* Chooses the Resolution which best matches the given dimensions.
* @param w the width
* @param h the height
* @param descriptors the resolutions to test against
*/
public Resolution choose(int w, int h, Resolution... descriptors);
/**
* Implementation of ChooserStrategy which chooses the Resolution,
* which most closely matches the given dimensions,
* without going above the given dimensions.
*/
public static ChooserStrategy PreferLowerChooserStrategy = new ChooserStrategy() {
@Override
public Resolution choose (int w, int h, Resolution... descriptors) {
if (descriptors == null) throw new IllegalArgumentException("descriptors cannot be null.");
Resolution best = descriptors[0];
if (w < h) {
for (int i = 0, n = descriptors.length; i < n; i++) {
Resolution other = descriptors[i];
if (w >= other.portraitWidth && other.portraitWidth >= best.portraitWidth && h >= other.portraitHeight
&& other.portraitHeight >= best.portraitHeight) best = descriptors[i];
}
} else {
for (int i = 0, n = descriptors.length; i < n; i++) {
Resolution other = descriptors[i];
if (w >= other.portraitHeight && other.portraitHeight >= best.portraitHeight && h >= other.portraitWidth
&& other.portraitWidth >= best.portraitWidth) best = descriptors[i];
}
}
return best;
}
};
/**
* Implementation of ChooserStrategy which chooses the Resolution,
* which most closely matches the given dimensions,
* without going below the given dimensions.
*/
public static ChooserStrategy PreferHigherChooserStrategy = new ChooserStrategy() {
@Override
public Resolution choose (int w, int h, Resolution... descriptors) {
if (descriptors == null) throw new IllegalArgumentException("descriptors cannot be null.");
Resolution best = descriptors[descriptors.length - 1];
if (w < h) {
for (int i = 0, n = descriptors.length; i < n; i++) {
Resolution other = descriptors[i];
if (w <= other.portraitWidth && other.portraitWidth <= best.portraitWidth &&
h <= other.portraitHeight && other.portraitHeight <= best.portraitHeight)
best = descriptors[i];
}
} else {
for (int i = 0, n = descriptors.length; i < n; i++) {
Resolution other = descriptors[i];
if (w <= other.portraitHeight && other.portraitHeight <= best.portraitHeight &&
h <= other.portraitWidth && other.portraitWidth <= best.portraitWidth)
best = descriptors[i];
}
}
return best;
}
};
/**
* Implementation of ChooserStrategy which chooses the Resolution,
* which most closely matches the given dimensions.
*/
public ChooserStrategy PreferClosestChooserStrategy = new ChooserStrategy() {
@Override
public Resolution choose (int w, int h, Resolution... descriptors) {
if (descriptors == null) throw new IllegalArgumentException("descriptors cannot be null.");
Resolution best = descriptors[0];
if (w < h) {
for (int i = 0, n = descriptors.length; i < n; i++) {
Resolution other = descriptors[i];
int dstWtoBPW = Math.abs(w - best.portraitWidth);
int dstWtoRPW = Math.abs(w - other.portraitWidth);
if (dstWtoRPW <= dstWtoBPW) {
int dstHtoBPH = Math.abs(h - best.portraitHeight);
int dstHtoRPH = Math.abs(h - other.portraitHeight);
if (dstHtoRPH <= dstHtoBPH) {
best = descriptors[i];
}
}
}
} else {
for (int i = 0, n = descriptors.length; i < n; i++) {
Resolution other = descriptors[i];
int dstHtoBPW = Math.abs(h - best.portraitWidth);
int dstHtoRPW = Math.abs(h - other.portraitWidth);
if (dstHtoRPW <= dstHtoBPW) {
int dstWtoBPH = Math.abs(w - best.portraitHeight);
int dstWtoRPH = Math.abs(w - other.portraitHeight);
if (dstWtoRPH <= dstWtoBPH) {
best = descriptors[i];
}
}
}
}
return best;
}
};
}
// Tester
public static void main(String[] args) {
Resolution[] resolutions = new Resolution[] {
new Resolution(320, 480, "320"),
new Resolution(480, 800, "480"),
new Resolution(768, 1280, "768"),
};
Resolution resolution1 = ChooserStrategy.PreferLowerChooserStrategy.choose(1920, 1080, resolutions);
Resolution resolution2 = ChooserStrategy.PreferHigherChooserStrategy.choose(1920, 1080, resolutions);
Resolution resolution3 = ChooserStrategy.PreferClosestChooserStrategy.choose(1920, 1080, resolutions);
System.out.println(resolution1.suffix);
System.out.println(resolution2.suffix);
System.out.println(resolution3.suffix);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment