feat(module): Add DemoModule with audio playback functionality and module service integration
This commit is contained in:
BIN
data/audio/race.ogg
Normal file
BIN
data/audio/race.ogg
Normal file
Binary file not shown.
@@ -12,6 +12,8 @@ public abstract class AbstractModule {
|
|||||||
|
|
||||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractModule.class);
|
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractModule.class);
|
||||||
|
|
||||||
|
private ModuleService moduleService;
|
||||||
|
|
||||||
public AbstractModule() {
|
public AbstractModule() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -40,6 +42,14 @@ public abstract class AbstractModule {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ModuleService getModuleService() {
|
||||||
|
return moduleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModuleService(ModuleService moduleService) {
|
||||||
|
this.moduleService = moduleService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.getClass().getSimpleName();
|
return this.getClass().getSimpleName();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class ModuleServiceAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
ModuleService moduleManager(final List<AbstractModule> initialModules, final RendererWorkingSet rendererWorkingSet) {
|
ModuleService moduleService(final List<AbstractModule> initialModules, final RendererWorkingSet rendererWorkingSet) {
|
||||||
return new ModuleServiceImpl(initialModules, rendererWorkingSet);
|
return new ModuleServiceImpl(initialModules, rendererWorkingSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug("Loading module " + clazz.getName());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final AbstractModule module = AbstractModule.class.cast(clazz.getDeclaredConstructor().newInstance());
|
final AbstractModule module = AbstractModule.class.cast(clazz.getDeclaredConstructor().newInstance());
|
||||||
this.load(module);
|
this.load(module);
|
||||||
@@ -97,12 +95,14 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void load(final AbstractModule module) {
|
private void load(final AbstractModule module) {
|
||||||
this.invokeSafe(module, m -> m.onLoad());
|
module.setModuleService(this);
|
||||||
this.modulesAll.add(module);
|
this.modulesAll.add(module);
|
||||||
this.sortModules(this.modulesAll);
|
this.sortModules(this.modulesAll);
|
||||||
synchronized (this.modulesAll) {
|
synchronized (this.modulesAll) {
|
||||||
this.modulesAllView = List.copyOf(this.modulesAll);
|
this.modulesAllView = List.copyOf(this.modulesAll);
|
||||||
}
|
}
|
||||||
|
LOGGER.info("Loaded module " + module.getClass().getName());
|
||||||
|
this.invokeSafe(module, m -> m.onLoad());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -130,7 +130,7 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
this.rendererWorkingSet.clear(clientModule.getClass());
|
this.rendererWorkingSet.clear(clientModule.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug("Unloaded module " + clazz.getName());
|
LOGGER.info("Unloaded module " + clazz.getName());
|
||||||
}
|
}
|
||||||
catch (final Exception e) {
|
catch (final Exception e) {
|
||||||
LOGGER.error("Error unloading module " + clazz.getName(), e);
|
LOGGER.error("Error unloading module " + clazz.getName(), e);
|
||||||
@@ -158,15 +158,14 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
if (module instanceof final AbstractClientModule clientModule) {
|
if (module instanceof final AbstractClientModule clientModule) {
|
||||||
this.changeDisplayState(clientModule.getClass(), false);
|
this.changeDisplayState(clientModule.getClass(), false);
|
||||||
}
|
}
|
||||||
this.invokeSafe(module, AbstractModule::onDeactivate);
|
|
||||||
this.modulesActive.remove(module);
|
this.modulesActive.remove(module);
|
||||||
this.sortModules(this.modulesActive);
|
this.sortModules(this.modulesActive);
|
||||||
synchronized (this.modulesActive) {
|
synchronized (this.modulesActive) {
|
||||||
this.modulesActiveView = List.copyOf(this.modulesActive);
|
this.modulesActiveView = List.copyOf(this.modulesActive);
|
||||||
this.modulesActiveClientModulesView = this.modulesActive.stream()
|
this.modulesActiveClientModulesView = this.modulesActive.stream()
|
||||||
.filter(m -> m instanceof AbstractClientModule)
|
.filter(m -> m instanceof AbstractClientModule)
|
||||||
.map(m -> (AbstractClientModule) m)
|
.map(m -> (AbstractClientModule) m)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
if (module instanceof final AbstractClientModule clientModule) {
|
if (module instanceof final AbstractClientModule clientModule) {
|
||||||
this.rendererWorkingSet.clear(clientModule.getClass());
|
this.rendererWorkingSet.clear(clientModule.getClass());
|
||||||
@@ -179,8 +178,9 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.invokeSafe(module, AbstractModule::onDeactivate);
|
||||||
|
|
||||||
LOGGER.debug("Deactivated " + clazz.getName());
|
LOGGER.info("Deactivated " + clazz.getName());
|
||||||
}
|
}
|
||||||
}, () -> {
|
}, () -> {
|
||||||
if (active) {
|
if (active) {
|
||||||
@@ -189,7 +189,6 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
.filter(module -> clazz.isAssignableFrom(module.getClass()))
|
.filter(module -> clazz.isAssignableFrom(module.getClass()))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.ifPresent(module -> {
|
.ifPresent(module -> {
|
||||||
this.invokeSafe(module, AbstractModule::onActivate);
|
|
||||||
if (module instanceof final AbstractClientModule clientModule && clientModule.isAlwaysDisplay()) {
|
if (module instanceof final AbstractClientModule clientModule && clientModule.isAlwaysDisplay()) {
|
||||||
this.changeDisplayState(clientModule.getClass(), true);
|
this.changeDisplayState(clientModule.getClass(), true);
|
||||||
}
|
}
|
||||||
@@ -198,9 +197,9 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
synchronized (this.modulesActive) {
|
synchronized (this.modulesActive) {
|
||||||
this.modulesActiveView = List.copyOf(this.modulesActive);
|
this.modulesActiveView = List.copyOf(this.modulesActive);
|
||||||
this.modulesActiveClientModulesView = this.modulesActive.stream()
|
this.modulesActiveClientModulesView = this.modulesActive.stream()
|
||||||
.filter(m -> m instanceof AbstractClientModule)
|
.filter(m -> m instanceof AbstractClientModule)
|
||||||
.map(m -> (AbstractClientModule) m)
|
.map(m -> (AbstractClientModule) m)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
synchronized (this.executorCallbackMap) {
|
synchronized (this.executorCallbackMap) {
|
||||||
final var subscriptions = module.executorCallbackSubscriptions();
|
final var subscriptions = module.executorCallbackSubscriptions();
|
||||||
@@ -210,8 +209,9 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.invokeSafe(module, AbstractModule::onActivate);
|
||||||
|
|
||||||
LOGGER.debug("Activated " + clazz.getName());
|
LOGGER.info("Activated " + clazz.getName());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,11 +249,13 @@ public class ModuleServiceImpl implements InitializingBean, ModuleService {
|
|||||||
if (doDisplay && !curDisplayed) {
|
if (doDisplay && !curDisplayed) {
|
||||||
this.modulesDisplayed.add(clientModule);
|
this.modulesDisplayed.add(clientModule);
|
||||||
clientModule.setDisplayed(true);
|
clientModule.setDisplayed(true);
|
||||||
|
LOGGER.info("Displayed {}", clazz.getName());
|
||||||
this.invokeSafe(clientModule, m -> ((AbstractClientModule) m).onShow());
|
this.invokeSafe(clientModule, m -> ((AbstractClientModule) m).onShow());
|
||||||
}
|
}
|
||||||
else if (!doDisplay && curDisplayed) {
|
else if (!doDisplay && curDisplayed) {
|
||||||
clientModule.setDisplayed(false);
|
clientModule.setDisplayed(false);
|
||||||
this.modulesDisplayed.removeIf(mod -> clazz.isAssignableFrom(mod.getClass()));
|
this.modulesDisplayed.removeIf(mod -> clazz.isAssignableFrom(mod.getClass()));
|
||||||
|
LOGGER.info("Hidden {}", clazz.getName());
|
||||||
this.invokeSafe(clientModule, m -> ((AbstractClientModule) m).onHide());
|
this.invokeSafe(clientModule, m -> ((AbstractClientModule) m).onHide());
|
||||||
}
|
}
|
||||||
this.modulesDisplayedClientModulesView = List.copyOf(this.modulesDisplayed);
|
this.modulesDisplayedClientModulesView = List.copyOf(this.modulesDisplayed);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import java.util.UUID;
|
|||||||
/**
|
/**
|
||||||
* Random implementation using the Xorshift+ (xorshift128plus) algorithm
|
* Random implementation using the Xorshift+ (xorshift128plus) algorithm
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public final class XorShift128Random extends Random {
|
public final class XorShift128Random extends Random {
|
||||||
|
|
||||||
private long state0;
|
private long state0;
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
package de.extio.game_engine;
|
package de.extio.game_engine;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Condition;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
|
|
||||||
|
import de.extio.game_engine.demo.DemoModule;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableAutoConfiguration
|
|
||||||
@ComponentScan
|
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
@@ -28,4 +32,22 @@ public class Main {
|
|||||||
builder.run(args);
|
builder.run(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Conditional(de.extio.game_engine.Main.StandaloneConfig.StandaloneCondition.class)
|
||||||
|
static class StandaloneConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
DemoModule demoModule() {
|
||||||
|
return new DemoModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class StandaloneCondition implements Condition {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) {
|
||||||
|
final String env = context.getEnvironment().getProperty("game-engine.env");
|
||||||
|
return "standalone".equals(env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
src/test/java/de/extio/game_engine/demo/DemoModule.java
Normal file
32
src/test/java/de/extio/game_engine/demo/DemoModule.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package de.extio.game_engine.demo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import de.extio.game_engine.audio.AudioController;
|
||||||
|
import de.extio.game_engine.module.AbstractClientModule;
|
||||||
|
import de.extio.game_engine.resource.StaticResource;
|
||||||
|
|
||||||
|
public class DemoModule extends AbstractClientModule {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AudioController audioController;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
this.getModuleService().changeActiveState(this.getClass(), true);
|
||||||
|
this.getModuleService().changeDisplayState(this.getClass(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onShow() {
|
||||||
|
this.audioController.playMusic(null, List.of(new StaticResource(List.of("audio"), "race.ogg")), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onHide() {
|
||||||
|
this.audioController.stopMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user