Matter loader

This commit is contained in:
cyberpwn 2021-09-11 12:04:48 -04:00
parent 930469a006
commit 2d7bc59db4
2 changed files with 248 additions and 1 deletions

View File

@ -0,0 +1,229 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.core.loader;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.object.IrisObject;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.matter.IrisMatter;
import com.volmit.iris.util.matter.Matter;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import java.io.File;
import java.util.concurrent.atomic.AtomicInteger;
public class MatterResourceLoader extends ResourceLoader<IrisMatter> {
private final ChronoLatch useFlip = new ChronoLatch(2222);
private final KMap<String, Long> useCache = new KMap<>();
private final ChronoLatch cl;
private final AtomicInteger unload;
public MatterResourceLoader(File root, IrisData idm, String folderName, String resourceTypeName) {
super(root, idm, folderName, resourceTypeName, IrisMatter.class);
cl = new ChronoLatch(30000);
unload = new AtomicInteger(0);
}
public boolean supportsSchemas() {
return false;
}
public int getSize() {
return loadCache.size();
}
public int getTotalStorage() {
return getSize();
}
public void clean() {
if (useFlip.flip()) {
unloadLast(30000);
}
}
public void unloadLast(long age) {
String v = getOldest();
if (v == null) {
return;
}
if (M.ms() - useCache.get(v) > age) {
unload(v);
}
}
private String getOldest() {
long min = M.ms();
String v = null;
for (String i : useCache.k()) {
long t = useCache.get(i);
if (t < min) {
min = t;
v = i;
}
}
return v;
}
private void unload(String v) {
lock.lock();
useCache.remove(v);
loadCache.remove(v);
lock.unlock();
unload.getAndIncrement();
if (unload.get() == 1) {
cl.flip();
}
if (cl.flip()) {
J.a(() -> {
Iris.verbose("Unloaded " + C.WHITE + unload.get() + " " + resourceTypeName + (unload.get() == 1 ? "" : "s") + C.GRAY + " to optimize memory usage." + " (" + Form.f(getLoadCache().size()) + " " + resourceTypeName + (loadCache.size() == 1 ? "" : "s") + " Loaded)");
unload.set(0);
});
}
}
public IrisMatter loadFile(File j, String key, String name) {
lock.lock();
try {
PrecisionStopwatch p = PrecisionStopwatch.start();
IrisMatter t = (IrisMatter) Matter.read(j);
loadCache.put(key, t);
t.setLoadKey(name);
t.setLoader(manager);
t.setLoadFile(j);
logLoad(j, t);
lock.unlock();
tlt.addAndGet(p.getMilliseconds());
return t;
} catch (Throwable e) {
Iris.reportError(e);
lock.unlock();
Iris.warn("Couldn't read " + resourceTypeName + " file: " + j.getPath() + ": " + e.getMessage());
return null;
}
}
public String[] getPossibleKeys() {
if (possibleKeys != null) {
return possibleKeys;
}
Iris.debug("Building " + resourceTypeName + " Possibility Lists");
KSet<String> m = new KSet<>();
for (File i : getFolders()) {
for (File j : i.listFiles()) {
if (j.isFile() && j.getName().endsWith(".matter")) {
m.add(j.getName().replaceAll("\\Q.matter\\E", ""));
} else if (j.isDirectory()) {
for (File k : j.listFiles()) {
if (k.isFile() && k.getName().endsWith(".matter")) {
m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.matter\\E", ""));
} else if (k.isDirectory()) {
for (File l : k.listFiles()) {
if (l.isFile() && l.getName().endsWith(".matter")) {
m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.matter\\E", ""));
}
}
}
}
}
}
}
KList<String> v = new KList<>(m);
possibleKeys = v.toArray(new String[0]);
return possibleKeys;
}
public File findFile(String name) {
lock.lock();
for (File i : getFolders(name)) {
for (File j : i.listFiles()) {
if (j.isFile() && j.getName().endsWith(".matter") && j.getName().split("\\Q.\\E")[0].equals(name)) {
lock.unlock();
return j;
}
}
File file = new File(i, name + ".matter");
if (file.exists()) {
lock.unlock();
return file;
}
}
Iris.warn("Couldn't find " + resourceTypeName + ": " + name);
lock.unlock();
return null;
}
public IrisMatter load(String name) {
return load(name, true);
}
public IrisMatter load(String name, boolean warn) {
String key = name + "-" + objectClass.getCanonicalName();
if (loadCache.containsKey(key)) {
IrisMatter t = loadCache.get(key);
useCache.put(key, M.ms());
return t;
}
lock.lock();
for (File i : getFolders(name)) {
for (File j : i.listFiles()) {
if (j.isFile() && j.getName().endsWith(".matter") && j.getName().split("\\Q.\\E")[0].equals(name)) {
useCache.put(key, M.ms());
lock.unlock();
return loadFile(j, key, name);
}
}
File file = new File(i, name + ".matter");
if (file.exists()) {
useCache.put(key, M.ms());
lock.unlock();
return loadFile(file, key, name);
}
}
Iris.warn("Couldn't find " + resourceTypeName + ": " + name);
lock.unlock();
return null;
}
}

View File

@ -19,10 +19,13 @@
package com.volmit.iris.util.matter; package com.volmit.iris.util.matter;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisRegistrant;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.plugin.VolmitSender;
import lombok.Getter; import lombok.Getter;
public class IrisMatter implements Matter { public class IrisMatter extends IrisRegistrant implements Matter {
protected static final KMap<Class<?>, MatterSlice<?>> slicers = buildSlicers(); protected static final KMap<Class<?>, MatterSlice<?>> slicers = buildSlicers();
@Getter @Getter
@ -74,4 +77,19 @@ public class IrisMatter implements Matter {
return null; return null;
} }
@Override
public String getFolderName() {
return "matter";
}
@Override
public String getTypeName() {
return "matter";
}
@Override
public void scanForErrors(JSONObject p, VolmitSender sender) {
}
} }