Skip to content

Commit

Permalink
Editor tiles, iterators, and async enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
GlennFolker committed Mar 15, 2024
1 parent 8657817 commit 2c57573
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 91 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ configure(project(':proc')){
outputs.dir out
outputs.file colors

outputs.upToDateWhen{false}

mainClass = 'confictura.proc.ConficturaProc'
classpath = sourceSets.main.runtimeClasspath
workingDir = temporaryDir
Expand Down
30 changes: 25 additions & 5 deletions proc/src/confictura/proc/ConficturaProc.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

import static arc.Core.*;
import static mindustry.Vars.*;

public class ConficturaProc{
protected static TaskQueue runs = new TaskQueue();
protected static final TaskQueue runs = new TaskQueue();
protected static final Proc[] procs = {new BlockProc()};

public static GenAtlas atlas;

public static ConficturaMod main;
Expand Down Expand Up @@ -91,9 +94,24 @@ public Fi get(String path, boolean safe){
}));
}));

wait(f -> BlockProc.init(run -> f.get(exec.submit(run))));
BlockProc.cleanup();
wait(f -> {
for(var proc : procs){
long started = Time.millis();

Seq<Runnable> runs = new Seq<>();
proc.init(runs::add);

var remaining = new AtomicInteger(runs.size);
runs.each(run -> f.get(exec.submit(() -> {
run.run();
if(remaining.addAndGet(-1) == 0){
Log.info("[Confictura-Proc] Total time taken for '@': @ms", proc.getClass().getSimpleName(), Time.timeSinceMillis(started));
}
})));
}
});

for(var proc : procs) proc.finish();
wait(f -> atlas.each(reg -> f.get(exec.submit(() -> {
var pix = reg.pixmap;
Pixmaps.bleed(pix);
Expand Down Expand Up @@ -158,6 +176,8 @@ public Fi get(String path, boolean safe){
}
}

prev.dispose();

var name = reg.file.name();
if(name.endsWith(".floor.png")){
new GenRegion(
Expand All @@ -175,10 +195,10 @@ public Fi get(String path, boolean safe){
Threads.await(exec);
}

protected static <T> Seq<T> wait(Cons<Cons<Future<? extends T>>> futures){
protected static <T> void wait(Cons<Cons<Future<? extends T>>> futures){
Seq<Future<? extends T>> array = new Seq<>();
futures.get(array::add);

return array.map(AsyncUtils::get);
array.each(AsyncUtils::get);
}
}
55 changes: 11 additions & 44 deletions proc/src/confictura/proc/GenAtlas.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import arc.struct.*;
import arc.util.*;
import confictura.proc.GenAtlas.*;
import confictura.util.*;

import java.util.concurrent.locks.*;

Expand All @@ -18,61 +19,25 @@ public class GenAtlas extends TextureAtlas implements Eachable<GenRegion>{

public GenAtlas(){}

private <T> T read(Prov<T> prov){
var read = lock.readLock();
read.lock();

var out = prov.get();

read.unlock();
return out;
}

private void read(Runnable run){
var read = lock.readLock();
read.lock();

run.run();
read.unlock();
}

private <T> T write(Prov<T> prov){
var write = lock.writeLock();
write.lock();

var out = prov.get();

write.unlock();
return out;
}

private void write(Runnable run){
var write = lock.writeLock();
write.lock();

run.run();
write.unlock();
}

public void addRegion(GenRegion region){
var old = write(() -> regions.put(region.name, region));
var old = AsyncUtils.write(lock, () -> regions.put(region.name, region));
if(old != null && old.found()) old.pixmap.dispose();
}

@Override
public GenRegion find(String name){
var reg = read(() -> regions.get(name));
var reg = AsyncUtils.read(lock, () -> regions.get(name));
if(reg == null){
var err = new GenRegion(name, null, null);
write(() -> regions.put(name, err));
AsyncUtils.write(lock, () -> regions.put(name, err));
return err;
}
return reg;
}

@Override
public GenRegion find(String name, TextureRegion def){
return read(() -> regions.get(name, conv(def)));
return AsyncUtils.read(lock, () -> regions.get(name, conv(def)));
}

@Override
Expand All @@ -88,14 +53,16 @@ public GenRegion conv(TextureRegion region){

@Override
public void each(Cons<? super GenRegion> cons){
for(var reg : regions.values()){
if(reg.found() && reg.file != null && !reg.file.path().contains("vanilla/")) cons.get(reg);
}
AsyncUtils.read(lock, () -> {
for(var reg : regions.values()){
if(reg.found() && reg.file != null && !reg.file.path().contains("vanilla/")) cons.get(reg);
}
});
}

@Override
public void dispose(){
write(() -> {
AsyncUtils.write(lock, () -> {
for(var region : regions.values()){
if(region.found()) region.pixmap.dispose();
}
Expand Down
9 changes: 9 additions & 0 deletions proc/src/confictura/proc/Proc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package confictura.proc;

import arc.func.*;

public interface Proc{
void init(Cons<Runnable> async);

void finish();
}
22 changes: 12 additions & 10 deletions proc/src/confictura/proc/list/BlockProc.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@
import java.nio.charset.*;

import static confictura.proc.ConficturaProc.*;
import static confictura.util.StructUtils.*;
import static mindustry.Vars.*;

public final class BlockProc{
private static Jval blockColors;
public class BlockProc implements Proc{
private Jval blockColors;

private BlockProc(){
throw new AssertionError();
}

public static void init(Cons<Runnable> async){
@Override
public void init(Cons<Runnable> async){
blockColors = Jval.newObject();

var packer = new GenPacker();
Expand All @@ -31,8 +29,10 @@ public static void init(Cons<Runnable> async){
block.load();

block.createIcons(packer);
block.load();

if(block instanceof Floor floor){
for(var variant : floor.variantRegions){
for(var variant : chain(iter(floor.variantRegions), iter(floor.editorVariantRegions()))){
var reg = atlas.conv(variant);
var pix = reg.pixmap();

Expand All @@ -55,7 +55,8 @@ public static void init(Cons<Runnable> async){
}
}

var icon = atlas.find("block-" + block.name + "-full").pixmap();
block.load();
var icon = atlas.conv(block.fullIcon).pixmap();

boolean hollow = false;
Color average = new Color(), col = new Color();
Expand Down Expand Up @@ -87,7 +88,8 @@ public static void init(Cons<Runnable> async){
}));
}

public static void cleanup(){
@Override
public void finish(){
var out = assetsDir.child("meta").child("confictura").child("block-colors.json");
try(var writer = new OutputStreamWriter(out.write(false, 4096), StandardCharsets.UTF_8)){
blockColors.writeTo(writer, Jformat.formatted);
Expand Down
74 changes: 47 additions & 27 deletions src/confictura/ConficturaMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.io.*;

import static arc.Core.*;
import static confictura.util.StructUtils.*;
import static mindustry.Vars.*;

/**
Expand Down Expand Up @@ -102,47 +103,66 @@ public Seq<AssetDescriptor> getDependencies(String fileName, Fi file, FreeTypeFo
cinematicEditor = new CinematicEditor();

assets.load(new Loadable(){
Texture texture;
Pixmap page;
ObjectMap<Texture, Pixmap> pixmaps;

@Override
public void loadAsync(){
page = AsyncUtils.postWait(() -> {
texture = atlas.find("stone1").texture;
pixmaps = new ObjectMap<>();
var regions = content.blocks().flatMap(b -> {
if(b instanceof CFloor floor){
return chain(iter(b.variantRegions), iter(b.editorVariantRegions()));
}else{
return empty();
}
});

var buffer = new FrameBuffer(texture.width, texture.height);
buffer.begin();
Draw.blit(texture, Shaders.screenspace);
regions.each(r -> pixmaps.put(r.texture, null));
AsyncUtils.postWait(() -> {
var buffer = new FrameBuffer(2, 2);
for(var texture : pixmaps.keys()){
buffer.resize(texture.width, texture.height);
buffer.begin();
Draw.blit(texture, Shaders.screenspace);

var pixels = ScreenUtils.getFrameBufferPixmap(0, 0, texture.width, texture.height);
buffer.end();
buffer.dispose();
var pixels = ScreenUtils.getFrameBufferPixmap(0, 0, texture.width, texture.height);
buffer.end();

return pixels;
// Generally it's a bad idea to modify a collection while iterating over it.
// However in this case, the map's inner hash tables are structurally unchanged, so it should be fine.
pixmaps.put(texture, pixels);
}
buffer.dispose();
});

content.blocks().each(b -> b instanceof CFloor, (CFloor b) -> {
for(var r : b.variantRegions){
int x = r.getX(), y = r.getY(), w = r.width, h = r.height;
page.draw(page, x, y + h - 1, w, 1, x, y - 1, w, 1, false);
page.draw(page, x, y, 1, h, x + w, y, 1, h, false);
page.draw(page, x, y, w, 1, x, y + h, w, 1, false);
page.draw(page, x + w - 1, y, 1, h, x - 1, y, 1, h, false);

page.setRaw(x - 1, y - 1, page.getRaw(x + w - 1, y + h - 1));
page.setRaw(x + w, y - 1, page.getRaw(x, y + h - 1));
page.setRaw(x + w, y + h, page.getRaw(x, y));
page.setRaw(x - 1, y + h, page.getRaw(x + w - 1, y));
}
regions.each(r -> {
var page = pixmaps.get(r.texture);
int x = r.getX(), y = r.getY(), w = r.width, h = r.height;

page.draw(page, x, y + h - 1, w, 1, x, y - 1, w, 1, false);
page.draw(page, x, y, 1, h, x + w, y, 1, h, false);
page.draw(page, x, y, w, 1, x, y + h, w, 1, false);
page.draw(page, x + w - 1, y, 1, h, x - 1, y, 1, h, false);

page.setRaw(x - 1, y - 1, page.getRaw(x + w - 1, y + h - 1));
page.setRaw(x + w, y - 1, page.getRaw(x, y + h - 1));
page.setRaw(x + w, y + h, page.getRaw(x, y));
page.setRaw(x - 1, y + h, page.getRaw(x + w - 1, y));
});
}

@Override
public void loadSync(){
texture.bind();
Gl.texImage2D(Gl.texture2d, 0, Gl.rgba, page.width, page.height, 0, Gl.rgba, Gl.unsignedByte, page.pixels);
for(var e : pixmaps){
var texture = e.key;
var page = e.value;

texture.bind();
Gl.texImage2D(Gl.texture2d, 0, Gl.rgba, page.width, page.height, 0, Gl.rgba, Gl.unsignedByte, page.pixels);
page.dispose();
}

page.dispose();
pixmaps.clear();
pixmaps = null;
}

@Override
Expand Down
8 changes: 5 additions & 3 deletions src/confictura/graphics/g3d/CMeshBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import mindustry.graphics.g3d.*;
import mindustry.graphics.g3d.PlanetGrid.*;

import static confictura.util.StructUtils.*;

/**
* Utilities for composing specialized OpenGL {@linkplain Mesh meshes}.
* @author GlennFolker
Expand Down Expand Up @@ -169,7 +171,7 @@ public Color getColor(Vec3 position){
}

public static Mesh gridDistance(PlanetGrid grid, HexMesher mesher, float radius, float intensity){
int totalVerts = StructUtils.sumi(grid.tiles, tile -> mesher.skip(tile.v) ? 0 : tile.corners.length) * 3;
int totalVerts = sumi(grid.tiles, tile -> mesher.skip(tile.v) ? 0 : tile.corners.length) * 3;
float[] progress = new float[grid.tiles.length];

int accum = 0;
Expand Down Expand Up @@ -212,8 +214,8 @@ public static Mesh gridDistance(PlanetGrid grid, HexMesher mesher, float radius,
c3.set(mesher.getColor(v3.set(b.v).nor())).a(0f);

vert(v1, nor.set(progress[tile.id], 0f, 0f), c1);
vert(a.v, nor.set(StructUtils.average(a.tiles, t -> progress[t.id]), 0f, 0f), c2);
vert(b.v, nor.set(StructUtils.average(b.tiles, t -> progress[t.id]), 0f, 0f), c3);
vert(a.v, nor.set(average(a.tiles, t -> progress[t.id]), 0f, 0f), c2);
vert(b.v, nor.set(average(b.tiles, t -> progress[t.id]), 0f, 0f), c3);
}

for(var corner : c) corner.v.nor();
Expand Down
Loading

0 comments on commit 2c57573

Please sign in to comment.