Skip to content

Commit

Permalink
DataGeneration changes
Browse files Browse the repository at this point in the history
Fixes Ridanisaurus#223 for 1.21.1
Adds custom Progress Bar for the Data Generation, making it not hang the main window for soo long anymore.
Fixes errors caused by missing default directory when trying to look for Namespaces by the ResourceManager.
  • Loading branch information
Kanzaji committed Jan 8, 2025
1 parent c07a5f0 commit 6c8134d
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,12 @@
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import net.neoforged.neoforge.event.AddPackFindersEvent;
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.*;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;

// The value here should match an entry in the META-INF/neoforge.mods.toml file
@Mod(Reference.MOD_ID)
public class EmendatusEnigmatica {
// Directly reference a slf4j logger
public static final Logger logger = LogUtils.getLogger();
public static String VERSION = "0.0.0";
private static EmendatusEnigmatica instance;
Expand Down Expand Up @@ -89,25 +86,24 @@ public EmendatusEnigmatica(@NotNull IEventBus modEventBus, @NotNull ModContainer
EEConfig.setupStartup(modContainer);
Analytics.setup();

//TODO: Run in parallel
DataGeneratorFactory.init();
this.generator = DataGeneratorFactory.createEEDataGenerator();

this.loader = new EELoader();
this.loader.load();
this.loader.loadData();

EERegistrar.finalize(modEventBus);
CREATIVE_MODE_TABS.register(modEventBus);

this.loader.datagen(this.generator);
this.loader.registerDatagen(this.generator);
this.loader.finish();

// Creative Tab Item Registration.
modEventBus.addListener(this::addCreative);
modEventBus.addListener(this::populateCreativeTab);
// Virtual ResourcePack
modEventBus.addListener(this::addPackFinder);
// Generator check, we can't launch the game if the generator wasn't executed!
modEventBus.addListener(this::hasGenerated);
modEventBus.addListener(this::dataGenCheck);
// Registry Validation
modEventBus.addListener(this::commonSetup);
// Config screen
Expand All @@ -126,15 +122,17 @@ public EmendatusDataRegistry getDataRegistry() {
return loader.getDataRegistry();
}

private void addCreative(BuildCreativeModeTabContentsEvent event) {
private void populateCreativeTab(BuildCreativeModeTabContentsEvent event) {
EERegistrar.registerToCreativeTabs(event);
}

private void addPackFinder(@NotNull AddPackFindersEvent event) {
event.addRepositorySource(new EEPackFinder(event.getPackType()));
//TODO: Find more suitable place for running Data Generation.
//NOTE: CommonSetup is too late.
this.generator.run();
if (!loader.isFinished()) {
logger.error("Something is populating Pack Repository too early! Skipping running Data Generation.");
return;
}
generator.run();
}

private void commonSetup(FMLCommonSetupEvent event) {
Expand All @@ -144,7 +142,7 @@ private void commonSetup(FMLCommonSetupEvent event) {
throw new IllegalStateException("Registry validation failed! %s Validation Summary for more details.".formatted(EEConfig.startup.generateSummary.get()? "Check the": "Enable"));
}

private void hasGenerated(FMLLoadCompleteEvent event) {
private void dataGenCheck(FMLLoadCompleteEvent event) {
if (this.generator.hasExecuted()) return;
StartupNotificationManager.addModMessage("Emendatus Enigmatica - Missing Data Generation!");
throw new IllegalStateException("Mod loading finished, but Data Generation wasn't executed!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,16 @@
import net.minecraft.data.DataGenerator;
import net.minecraft.data.HashCache;
import net.neoforged.fml.ModLoader;
import net.neoforged.fml.loading.ImmediateWindowHandler;
import net.neoforged.fml.loading.progress.StartupNotificationManager;
import org.slf4j.Logger;

import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;

public class EEDataGenerator extends DataGenerator {
private static final Logger logger = LogUtils.getLogger();
private boolean alreadyExecuted = false;
private boolean executed = false;
private boolean crashed = false;

public EEDataGenerator(Path rootOutputFolder, WorldVersion version, boolean alwaysGenerate) {
Expand All @@ -49,14 +50,37 @@ public EEDataGenerator(Path rootOutputFolder, WorldVersion version, boolean alwa
@Override
public void run() {
//TODO: Add own caching logic. Currently entire DataGen has to be executed to even know what to cache.
if (alreadyExecuted) return;
alreadyExecuted = true;
if (executed) return;
executed = true;

ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
final Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setDaemon(true);
thread.setName("EmendatusEnigmatica-Data-Generation");
return thread;
});

try (executor) {
executor.submit(this::execute);
executor.shutdown();
do {
ImmediateWindowHandler.renderTick();
} while (!executor.awaitTermination(50, TimeUnit.MILLISECONDS));
} catch (Exception ex) {
throw new RuntimeException("EE Data Generation was interrupted!", ex);
}
}

public boolean hasExecuted() {
return executed && !crashed;
}

private void execute() {
try {
// Re-implementing the run logic here, to add our own analytics support.
// Run-Login reimplemented to add Custom Progress bar and own Analytics.
HashCache cache = new HashCache(this.rootOutputFolder, this.allProviderIds, this.version);
Stopwatch sMain = Stopwatch.createStarted();
Stopwatch sPerTask = Stopwatch.createUnstarted();
//TODO: As this is executed on a main thread, it will hang the Early Window, so the progress bar is not visible in the end :/
var bar = StartupNotificationManager.addProgressBar("Emendatus Enigmatica: Data Generation", this.providersToRun.size());
this.providersToRun.forEach((name, provider) -> {
logger.info("Starting provider: {}", name);
Expand All @@ -65,6 +89,7 @@ public void run() {
sPerTask.stop();
logger.info("{} finished after {} ms", name, sPerTask.elapsed(TimeUnit.MILLISECONDS));
sPerTask.reset();
bar.increment();
});
cache.purgeStaleAndWrite();
bar.complete();
Expand All @@ -83,8 +108,4 @@ public void run() {
throw new RuntimeException("Caught exception while running EE Data Generation!", e);
}
}

public boolean hasExecuted() {
return alreadyExecuted && !crashed;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@
import java.util.concurrent.TimeUnit;

public class EELoader {
public static final Logger LOADER_LOGGER = LogManager.getLogger(EELoader.class);
public static final Logger logger = LogManager.getLogger(EELoader.class);
private final EmendatusDataRegistry dataRegistry;
private final List<IEmendatusPlugin> plugins;
private boolean finished = false;

public EELoader() {
this.dataRegistry = new EmendatusDataRegistry();
Expand All @@ -65,7 +66,7 @@ private void scanForClasses(){
for (Class<?> annotatedClass : AnnotationUtil.getAnnotatedClasses(EmendatusPluginReference.class)) {
if (IEmendatusPlugin.class.isAssignableFrom(annotatedClass)) {
var annotation = (EmendatusPluginReference) annotatedClass.getAnnotation(EmendatusPluginReference.class);
LOADER_LOGGER.info("Registered plugin {}:{}", annotation.modid(), annotation.name());
logger.info("Registered plugin {}:{}", annotation.modid(), annotation.name());
try {
if (annotatedClass.equals(DefaultConfigPlugin.class)) {
this.plugins.addFirst((IEmendatusPlugin) annotatedClass.getDeclaredConstructor().newInstance());
Expand All @@ -74,34 +75,39 @@ private void scanForClasses(){
}
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
LOADER_LOGGER.error(e);
logger.error(e);
}
} else {
LOADER_LOGGER.error("{} has an annotation but it doesn't implement IEmendatusPlugin", annotatedClass.getName());
logger.error("{} has an annotation but it doesn't implement IEmendatusPlugin", annotatedClass.getName());
}
}
s.stop();
LOADER_LOGGER.info("Finished scanning for plugins, took " + s.elapsed(TimeUnit.MILLISECONDS) + "ms.");
logger.info("Finished scanning for plugins, took " + s.elapsed(TimeUnit.MILLISECONDS) + "ms.");
Analytics.addPerformanceAnalytic("Scanning and registration of addons", s);
}

public void load() {
public void loadData() {
this.plugins.forEach(iEmendatusPlugin -> iEmendatusPlugin.load(this.dataRegistry));

this.plugins.forEach(iEmendatusPlugin -> iEmendatusPlugin.registerMinecraft(this.dataRegistry.getMaterials(), this.dataRegistry.getStrata()));
}

public void datagen(DataGenerator dataGenerator) {
public void registerDatagen(DataGenerator dataGenerator) {
this.plugins.forEach(iEmendatusPlugin ->
iEmendatusPlugin.registerDynamicDataGen(dataGenerator, this.dataRegistry, CompletableFuture.supplyAsync(VanillaRegistries::createLookup, Util.backgroundExecutor()))
);
}

public void finish() {
this.plugins.forEach(iEmendatusPlugin -> iEmendatusPlugin.finish(this.dataRegistry));
this.finished = true;
}

public EmendatusDataRegistry getDataRegistry() {
return dataRegistry;
}

public boolean isFinished() {
return this.finished;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,13 @@ private void getChildResourceLocations(ResourceOutput rsOut, int depth, Path cur
@Override
public @NotNull Set<String> getNamespaces(@NotNull PackType type) {
Set<String> result = new HashSet<>();
try (Stream<Path> list = Files.list(path.resolve(type.getDirectory()))) {
for (Path resultingPath : list.toList()) result.add(resultingPath.getFileName().toString());
Path dir = path.resolve(type.getDirectory());
try {
if (Files.notExists(dir)) Files.createDirectories(dir);

try (Stream<Path> list = Files.list(dir)) {
for (Path resultingPath : list.toList()) result.add(resultingPath.getFileName().toString());
}
} catch (IOException e) {
logger.error("Exception caught while iterating generated resource folder!", e);
}
Expand Down

0 comments on commit 6c8134d

Please sign in to comment.