Skip to content

Commit 3b1dd69

Browse files
committed
♻️ introduce AssetSource annotation
1 parent 2cccb7a commit 3b1dd69

File tree

7 files changed

+139
-85
lines changed

7 files changed

+139
-85
lines changed

Diff for: CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Version 0.6.33
2+
3+
* [[#224](https://github.com/bitbrain/braingdx/issues/224)] introduce `@AssetSource` annotation
4+
5+
16
# Version 0.6.32
27

38
* simplify screens by making generic arguments optional

Diff for: core/src/main/java/de/bitbrain/braingdx/assets/SmartAssetLoader.java

+14-42
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,9 @@
1616
package de.bitbrain.braingdx.assets;
1717

1818
import com.badlogic.gdx.Gdx;
19-
import com.badlogic.gdx.audio.Music;
20-
import com.badlogic.gdx.audio.Sound;
21-
import com.badlogic.gdx.graphics.Texture;
22-
import com.badlogic.gdx.graphics.g2d.BitmapFont;
23-
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
24-
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
25-
import com.badlogic.gdx.maps.tiled.TiledMap;
19+
import de.bitbrain.braingdx.assets.annotations.AssetSource;
2620

2721
import java.lang.reflect.Field;
28-
import java.util.HashMap;
2922
import java.util.Map;
3023

3124
/**
@@ -39,61 +32,40 @@
3932
* <li>Particles</li>
4033
* <li>TiledMaps</li>
4134
* </ul>
42-
* In order to extend or change the list make use of the {@link SmartAssetLoaderConfiguration}.
4335
*
4436
* @author Miguel Gonzalez Sanchez
4537
*/
4638
public class SmartAssetLoader implements GameAssetLoader {
4739

48-
private final SmartAssetLoaderConfiguration configuration;
4940
private final Class<?> target;
50-
public SmartAssetLoader(Class<?> target) {
51-
this(target, defaultConfiguration());
52-
}
5341

54-
public SmartAssetLoader(Class<?> target, SmartAssetLoaderConfiguration configuration) {
42+
public SmartAssetLoader(Class<?> target) {
5543
this.target = target;
56-
this.configuration = configuration;
57-
}
58-
59-
public static SmartAssetLoaderConfiguration defaultConfiguration() {
60-
final Map<String, Class<?>> mapping = new HashMap<String, Class<?>>();
61-
mapping.put("Textures", Texture.class);
62-
mapping.put("Sounds", Sound.class);
63-
mapping.put("Musics", Music.class);
64-
mapping.put("BitmapFonts", BitmapFont.class);
65-
mapping.put("Fonts", FreeTypeFontGenerator.class);
66-
mapping.put("Particles", ParticleEffect.class);
67-
mapping.put("TiledMaps", TiledMap.class);
68-
return new SmartAssetLoaderConfiguration() {
69-
@Override
70-
public Map<String, Class<?>> getClassMapping() {
71-
return mapping;
72-
}
73-
};
7444
}
7545

7646
@Override
7747
public void put(Map<String, Class<?>> assets) {
7848
// for every sub-class, check for the given type
7949
for (Class<?> subclass : target.getDeclaredClasses()) {
80-
String categoryName = subclass.getSimpleName();
81-
Class<?> assetClassType = configuration.getClassMapping().get(categoryName);
82-
if (assetClassType != null) {
83-
putMembers(subclass, assets, assetClassType);
84-
} else {
85-
Gdx.app.log("WARN", "Asset category " + categoryName + " not defined in SmartAssetLoaderConfiguration!");
86-
}
50+
putMembers(subclass, assets, subclass.getAnnotation(AssetSource.class));
8751
}
52+
putMembers(target, assets, target.getAnnotation(AssetSource.class));
8853
}
8954

90-
private void putMembers(Class<?> subclass, Map<String, Class<?>> assets, Class<?> assetClassType) {
55+
private void putMembers(Class<?> subclass, Map<String, Class<?>> assets, AssetSource source) {
9156
for (Field field : subclass.getFields()) {
57+
if (field.getAnnotation(AssetSource.class) != null) {
58+
source = field.getAnnotation(AssetSource.class);
59+
}
60+
if (source == null) {
61+
Gdx.app.error("ERROR", "Field " + field.getName() + " does has a missing asset source. Ignoring!");
62+
continue;
63+
}
9264
try {
9365
Object path = field.get(null);
9466
if (path instanceof String) {
95-
assets.put((String) path, assetClassType);
96-
Gdx.app.log("INFO", "Registering asset: path=" + path + ", class=" + assetClassType.getName());
67+
assets.put(source.directory() + "/" + path, source.assetClass());
68+
Gdx.app.log("INFO", "Registering asset: path=" + path + ", class=" + source.assetClass().getName());
9769
} else {
9870
Gdx.app.log("WARN", "Invalid property type in '" + subclass.getName() + "::" + field.getName() + "! Only java.lang.String is allowed.");
9971
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package de.bitbrain.braingdx.assets.annotations;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Target({ElementType.TYPE, ElementType.FIELD})
9+
@Retention(RetentionPolicy.RUNTIME)
10+
public @interface AssetSource {
11+
String directory() default "";
12+
Class<?> assetClass();
13+
}

Diff for: core/src/test/java/de/bitbrain/braingdx/assets/CustomSampleValidAssets.java

-24
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* Copyright 2017 Miguel Gonzalez Sanchez
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
package de.bitbrain.braingdx.assets;
17+
18+
import com.badlogic.gdx.audio.Sound;
19+
import com.badlogic.gdx.graphics.Texture;
20+
import com.badlogic.gdx.graphics.g2d.BitmapFont;
21+
import com.badlogic.gdx.graphics.g2d.ParticleEmitter;
22+
import com.badlogic.gdx.maps.tiled.TiledMap;
23+
import de.bitbrain.braingdx.assets.annotations.AssetSource;
24+
25+
public interface SampleInvalidAssets {
26+
27+
String field1 = "texture-field1";
28+
@AssetSource(directory = "textures", assetClass = Texture.class) String field2 = "texture-field2";
29+
30+
@AssetSource(directory = "textures", assetClass = Texture.class)
31+
interface Textures {
32+
String field1 = "texture-field1";
33+
String field2 = "texture-field2";
34+
}
35+
36+
interface Musics {
37+
String field1 = "musics-field1";
38+
String field2 = "musics-field2";
39+
}
40+
41+
@AssetSource(directory = "sounds", assetClass = Sound.class)
42+
interface Sounds {
43+
String field1 = "sounds-field1";
44+
String field2 = "sounds-field2";
45+
int invalid = 39;
46+
}
47+
48+
@AssetSource(directory = "maps", assetClass = TiledMap.class)
49+
interface TiledMaps {
50+
String field1 = "tmx-field1";
51+
String field2 = "tmx-field2";
52+
}
53+
54+
@AssetSource(directory = "particles", assetClass = ParticleEmitter.class)
55+
interface Particles {
56+
String field1 = "particles-field1";
57+
String field2 = "particles-field2";
58+
}
59+
60+
@AssetSource(directory = "fonts", assetClass = BitmapFont.class)
61+
interface Fonts {
62+
String field1 = "fonts-field1";
63+
String field2 = "fonts-field2";
64+
}
65+
}

Diff for: core/src/test/java/de/bitbrain/braingdx/assets/SampleValidAssets.java

+17
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,51 @@
1515

1616
package de.bitbrain.braingdx.assets;
1717

18+
import com.badlogic.gdx.audio.Music;
19+
import com.badlogic.gdx.audio.Sound;
20+
import com.badlogic.gdx.graphics.Texture;
21+
import com.badlogic.gdx.graphics.g2d.BitmapFont;
22+
import com.badlogic.gdx.graphics.g2d.ParticleEmitter;
23+
import com.badlogic.gdx.maps.tiled.TiledMap;
24+
import de.bitbrain.braingdx.assets.annotations.AssetSource;
25+
1826
public interface SampleValidAssets {
1927

28+
@AssetSource(directory = "textures", assetClass = Texture.class)
29+
String field1 = "texture-field1";
30+
31+
@AssetSource(directory = "textures", assetClass = Texture.class)
2032
interface Textures {
2133
String field1 = "texture-field1";
2234
String field2 = "texture-field2";
2335
}
2436

37+
@AssetSource(directory = "music", assetClass = Music.class)
2538
interface Musics {
2639
String field1 = "musics-field1";
2740
String field2 = "musics-field2";
2841
}
2942

43+
@AssetSource(directory = "sounds", assetClass = Sound.class)
3044
interface Sounds {
3145
String field1 = "sounds-field1";
3246
String field2 = "sounds-field2";
3347
int invalid = 39;
3448
}
3549

50+
@AssetSource(directory = "maps", assetClass = TiledMap.class)
3651
interface TiledMaps {
3752
String field1 = "tmx-field1";
3853
String field2 = "tmx-field2";
3954
}
4055

56+
@AssetSource(directory = "particles", assetClass = ParticleEmitter.class)
4157
interface Particles {
4258
String field1 = "particles-field1";
4359
String field2 = "particles-field2";
4460
}
4561

62+
@AssetSource(directory = "fonts", assetClass = BitmapFont.class)
4663
interface Fonts {
4764
String field1 = "fonts-field1";
4865
String field2 = "fonts-field2";

Diff for: core/src/test/java/de/bitbrain/braingdx/assets/SmartAssetLoaderTest.java

+25-19
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@
1717

1818
import com.badlogic.gdx.Application;
1919
import com.badlogic.gdx.Gdx;
20-
import de.bitbrain.braingdx.assets.SmartAssetLoader.SmartAssetLoaderConfiguration;
21-
import org.assertj.core.api.Assertions;
2220
import org.junit.Before;
2321
import org.junit.Test;
24-
import org.mockito.Mockito;
22+
import org.mockito.invocation.InvocationOnMock;
23+
import org.mockito.stubbing.Answer;
2524

2625
import java.util.HashMap;
2726
import java.util.Map;
2827

28+
import static org.assertj.core.api.Assertions.assertThat;
29+
import static org.mockito.Matchers.anyString;
30+
import static org.mockito.Mockito.*;
31+
2932
/**
3033
* Test for {@link SmartAssetLoader}.
3134
*/
@@ -36,31 +39,34 @@ public class SmartAssetLoaderTest {
3639
@Before
3740
public void beforeTest() {
3841
assets = new HashMap<String, Class<?>>();
39-
Gdx.app = Mockito.mock(Application.class);
42+
Application application = mock(Application.class);
43+
doAnswer(new Answer<Void>() {
44+
@Override
45+
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
46+
String tag = (String) invocationOnMock.getArguments()[0];
47+
String message = (String) invocationOnMock.getArguments()[1];
48+
throw new RuntimeException("Unexpected error log found: tag=" + tag + ", message=" + message);
49+
}
50+
}).when(application).error(anyString(), anyString());
51+
Gdx.app = application;
52+
4053
}
4154

4255
@Test
4356
public void testDefaultTypes() {
4457
SmartAssetLoader loader = new SmartAssetLoader(SampleValidAssets.class);
4558
loader.put(assets);
46-
Assertions.assertThat(assets).hasSize(12);
47-
}
48-
49-
@Test
50-
public void testDefaultTypesWithAsdfTypes() {
51-
SmartAssetLoaderConfiguration config = SmartAssetLoader.defaultConfiguration();
52-
config.getClassMapping().put("AsdfType", Object.class);
53-
SmartAssetLoader loader = new SmartAssetLoader(CustomSampleValidAssets.class, config);
54-
loader.put(assets);
55-
Assertions.assertThat(assets).hasSize(2);
59+
assertThat(assets).hasSize(12);
5660
}
5761

5862
@Test
59-
public void testDefaultTypes_MissingType() {
60-
SmartAssetLoaderConfiguration config = SmartAssetLoader.defaultConfiguration();
61-
config.getClassMapping().put("AsdfType2", Object.class);
62-
SmartAssetLoader loader = new SmartAssetLoader(CustomSampleValidAssets.class, config);
63+
public void testProducesErrors_WithInvalidAssets() {
64+
Application application = mock(Application.class);
65+
doNothing().when(application).error(anyString(), anyString());
66+
Gdx.app = application;
67+
SmartAssetLoader loader = new SmartAssetLoader(SampleInvalidAssets.class);
6368
loader.put(assets);
64-
Assertions.assertThat(assets).hasSize(0);
69+
assertThat(assets).hasSize(10);
70+
verify(application, times(3)).error(anyString(), anyString());
6571
}
6672
}

0 commit comments

Comments
 (0)