Make it compile against java-gi changes (and some patches)

This commit is contained in:
Johannes Frohnmeyer 2023-01-10 21:20:01 +01:00
parent 71faae3b9a
commit 8af7c214d2
Signed by: Johannes
GPG Key ID: E76429612C2929F4
28 changed files with 245 additions and 421 deletions

View File

@ -1,5 +1,6 @@
package io.gitlab.jfronny.inceptum.cli;
import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta.GC_InstanceMeta;
import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
@ -27,29 +28,33 @@ public abstract class BaseInstanceCommand extends Command {
}
@Override
protected void invoke(CommandArgs args) {
protected void invoke(CommandArgs args) throws Exception {
if (args.length == 0) {
Utils.LOGGER.error("You must specify an instance to commit in");
return;
}
Path instancePath = MetaHolder.INSTANCE_DIR.resolve(args[0]);
if (!Files.exists(instancePath)) {
Utils.LOGGER.error("Invalid instance: \"" + args[0] + "\"");
return;
}
Instance instance;
try {
instance = InstanceList.read(instancePath);
} catch (IOException e) {
Utils.LOGGER.error("Could not read instance metadata", e);
return;
}
try {
invoke(args.subArgs(), instance);
} catch (Exception e) {
Utils.LOGGER.error("Could not execute command", e);
return;
Path normalPath = Path.of(args[0]);
if (Files.exists(normalPath.resolve(InstanceList.INSTANCE_CONFIG_NAME))) {
instance = new Instance(normalPath, GC_InstanceMeta.read(normalPath.resolve(InstanceList.INSTANCE_CONFIG_NAME)));
} else {
Path instancePath = MetaHolder.INSTANCE_DIR.resolve(args[0]).normalize();
if (!instancePath.startsWith(MetaHolder.INSTANCE_DIR)) {
Utils.LOGGER.error("Specified instance path doesn't exist");
return;
}
if (!Files.exists(instancePath)) {
Utils.LOGGER.error("Invalid instance: \"" + args[0] + "\"");
return;
}
try {
instance = InstanceList.read(instancePath);
} catch (IOException e) {
Utils.LOGGER.error("Could not read instance metadata", e);
return;
}
}
invoke(args.subArgs(), instance);
}
protected abstract void invoke(CommandArgs args, Instance instance) throws Exception;

View File

@ -47,6 +47,8 @@ public class CliMain {
try {
command.invoke();
} catch (Exception e) {
Utils.LOGGER.error("Could not execute command", e);
} finally {
LauncherEnv.terminate();
}

View File

@ -23,7 +23,7 @@ public class ListCommand extends Command {
List<Path> paths = JFiles.list(MetaHolder.INSTANCE_DIR);
if (paths.isEmpty) System.out.println("No instances are currently present");
for (Path path : paths) {
if (!Files.exists(path.resolve("instance.json"))) {
if (!Files.exists(path.resolve(InstanceList.INSTANCE_CONFIG_NAME))) {
System.out.println("- Invalid instance: " + path + " (no instance metadata)");
continue;
}

View File

@ -51,7 +51,7 @@ public enum GtkEnvBackend implements LauncherEnv.EnvBackend { //TODO test
Box box = dialog.contentArea;
box.append(new Label(details));
Entry entry = new Entry();
Editable entryEditable = Editable.castFrom(entry);
Editable entryEditable = (Editable) entry;
entryEditable.text = defaultValue;
box.append(entry);
dialog.addButton(I18n.get("ok"), ResponseType.OK.getValue());
@ -77,7 +77,7 @@ public enum GtkEnvBackend implements LauncherEnv.EnvBackend { //TODO test
}
private Dialog.Response processResponses(Dialog dialog, @Nullable Runnable ok, @Nullable Runnable cancel) {
return ($, response_id) -> {
return response_id -> {
switch (ResponseType.of(response_id)) {
case OK -> {
dialog.close();

View File

@ -34,11 +34,11 @@ public class GtkMain {
public static int showGui(String[] args) throws IOException {
var app = new Application(ID, ApplicationFlags.FLAGS_NONE);
app.onActivate($ -> {
app.onActivate(() -> {
GtkMenubar.create(app);
var window = new MainWindow(app);
window.show();
GLib.idleAdd(data -> {
GLib.idleAdd(() -> {
Runnable r;
while ((r = SCHEDULED.poll()) != null) {
try {
@ -48,9 +48,9 @@ public class GtkMain {
}
}
return true;
}, null);
});
GtkEnvBackend.INSTANCE.dialogParent = window;
window.onCloseRequest($1 -> {
window.onCloseRequest(() -> {
GtkEnvBackend.INSTANCE.dialogParent = null;
app.quit();
return false;

View File

@ -7,7 +7,7 @@ import io.gitlab.jfronny.commons.ref.R;
public class TestStart {
public static void main(String[] args) {
var app = new Application(GtkMain.ID, ApplicationFlags.FLAGS_NONE);
app.onActivate($ -> {
app.onActivate(() -> {
var button = Button.newWithLabel("Test");
button.onClicked(TestStart::test);
@ -17,7 +17,7 @@ public class TestStart {
window.child = button;
window.show();
GtkEnvBackend.INSTANCE.dialogParent = window;
window.onCloseRequest($1 -> {
window.onCloseRequest(() -> {
GtkEnvBackend.INSTANCE.dialogParent = null;
return false;
});
@ -25,7 +25,7 @@ public class TestStart {
System.exit(app.run(args.length, args));
}
private static void test(Button $) {
private static void test() {
GtkEnvBackend backend = GtkEnvBackend.INSTANCE;
backend.getInput("Ae", "IoU\naee", "Def", R::nop, R::nop);

View File

@ -1,20 +0,0 @@
package io.gitlab.jfronny.inceptum.gtk.callback;
import io.github.jwharm.javagi.Interop;
import org.jetbrains.annotations.ApiStatus;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public interface DisposeCallback {
void upcall(MemoryAddress pointer);
@ApiStatus.Internal
FunctionDescriptor DESCRIPTOR = FunctionDescriptor.ofVoid(Interop.valueLayout.ADDRESS);
@ApiStatus.Internal
MethodHandle HANDLE = Interop.getHandle(DisposeCallback.class, DESCRIPTOR);
default MemoryAddress toCallback() {
return Linker.nativeLinker().upcallStub(HANDLE.bindTo(this), DESCRIPTOR, Interop.getScope()).address();
}
}

View File

@ -1,19 +0,0 @@
package io.gitlab.jfronny.inceptum.gtk.callback;
import io.github.jwharm.javagi.Interop;
import org.jetbrains.annotations.ApiStatus;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
@FunctionalInterface
public interface GetItemCallback {
Addressable upcall(MemoryAddress inst, int position);
@ApiStatus.Internal FunctionDescriptor DESCRIPTOR = FunctionDescriptor.of(Interop.valueLayout.ADDRESS, Interop.valueLayout.ADDRESS, Interop.valueLayout.C_INT);
@ApiStatus.Internal MethodHandle HANDLE = Interop.getHandle(GetItemCallback.class, DESCRIPTOR);
default MemoryAddress toCallback() {
return Linker.nativeLinker().upcallStub(HANDLE.bindTo(this), DESCRIPTOR, Interop.getScope()).address();
}
}

View File

@ -1,20 +0,0 @@
package io.gitlab.jfronny.inceptum.gtk.callback;
import io.github.jwharm.javagi.Interop;
import org.jetbrains.annotations.ApiStatus;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public interface GetItemTypeCallback {
long upcall(MemoryAddress address);
@ApiStatus.Internal
FunctionDescriptor DESCRIPTOR = FunctionDescriptor.of(Interop.valueLayout.C_LONG, Interop.valueLayout.ADDRESS);
@ApiStatus.Internal
MethodHandle HANDLE = Interop.getHandle(GetItemTypeCallback.class, DESCRIPTOR);
default MemoryAddress toCallback() {
return Linker.nativeLinker().upcallStub(HANDLE.bindTo(this), DESCRIPTOR, Interop.getScope()).address();
}
}

View File

@ -1,20 +0,0 @@
package io.gitlab.jfronny.inceptum.gtk.callback;
import io.github.jwharm.javagi.Interop;
import org.jetbrains.annotations.ApiStatus;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public interface GetNItemsCallback {
int upcall(MemoryAddress inst);
@ApiStatus.Internal
FunctionDescriptor DESCRIPTOR = FunctionDescriptor.of(Interop.valueLayout.C_INT, Interop.valueLayout.ADDRESS);
@ApiStatus.Internal
MethodHandle HANDLE = Interop.getHandle(GetNItemsCallback.class, DESCRIPTOR);
default MemoryAddress toCallback() {
return Linker.nativeLinker().upcallStub(HANDLE.bindTo(this), DESCRIPTOR, Interop.getScope()).address();
}
}

View File

@ -1,29 +0,0 @@
package io.gitlab.jfronny.inceptum.gtk.callback;
import io.github.jwharm.javagi.Interop;
import io.github.jwharm.javagi.Ownership;
import org.gtk.gobject.*;
import org.jetbrains.annotations.ApiStatus;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public interface GetPropertyCallback {
void invoke(GObject object, int propertyId, Value value, ParamSpec paramSpec);
default void upcall(MemoryAddress object, int propertyId, MemoryAddress value, MemoryAddress pspec) {
invoke(GObject.fromAddress.marshal(object, Ownership.NONE),
propertyId,
Value.fromAddress.marshal(value, Ownership.NONE),
ParamSpec.fromAddress.marshal(pspec, Ownership.NONE));
}
@ApiStatus.Internal
FunctionDescriptor DESCRIPTOR = FunctionDescriptor.ofVoid(Interop.valueLayout.ADDRESS, Interop.valueLayout.C_INT, Interop.valueLayout.ADDRESS, Interop.valueLayout.ADDRESS);
@ApiStatus.Internal
MethodHandle HANDLE = Interop.getHandle(GetPropertyCallback.class, DESCRIPTOR);
default MemoryAddress toCallback() {
return Linker.nativeLinker().upcallStub(HANDLE.bindTo(this), DESCRIPTOR, Interop.getScope()).address();
}
}

View File

@ -1,29 +0,0 @@
package io.gitlab.jfronny.inceptum.gtk.callback;
import io.github.jwharm.javagi.Interop;
import io.github.jwharm.javagi.Ownership;
import org.gtk.gobject.*;
import org.jetbrains.annotations.ApiStatus;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public interface SetPropertyCallback {
void invoke(GObject object, int propertyId, Value value, ParamSpec paramSpec);
default void upcall(MemoryAddress object, int propertyId, MemoryAddress value, MemoryAddress pspec) {
invoke(GObject.fromAddress.marshal(object, Ownership.NONE),
propertyId,
Value.fromAddress.marshal(value, Ownership.NONE),
ParamSpec.fromAddress.marshal(pspec, Ownership.NONE));
}
@ApiStatus.Internal
FunctionDescriptor DESCRIPTOR = FunctionDescriptor.ofVoid(Interop.valueLayout.ADDRESS, Interop.valueLayout.C_INT, Interop.valueLayout.ADDRESS, Interop.valueLayout.ADDRESS);
@ApiStatus.Internal
MethodHandle HANDLE = Interop.getHandle(SetPropertyCallback.class, DESCRIPTOR);
default MemoryAddress toCallback() {
return Linker.nativeLinker().upcallStub(HANDLE.bindTo(this), DESCRIPTOR, Interop.getScope()).address();
}
}

View File

@ -1,8 +1,8 @@
package io.gitlab.jfronny.inceptum.gtk.control;
import io.gitlab.jfronny.inceptum.gtk.util.ListIndex;
import org.gtk.gtk.*;
import io.gitlab.jfronny.inceptum.gtk.util.ListIndexItem;
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import org.gtk.gtk.*;
import org.pango.EllipsizeMode;
import org.pango.WrapMode;
@ -12,7 +12,7 @@ public class InstanceGridEntryFactory extends SignalListItemFactory {
public InstanceGridEntryFactory(List<Instance> instanceList) {
super();
//TODO better design
onSetup(($, item) -> {
onSetup(item -> {
var box = new Box(Orientation.VERTICAL, 5);
var thumbnail = new InstanceThumbnail();
@ -49,11 +49,11 @@ public class InstanceGridEntryFactory extends SignalListItemFactory {
// openDir.setHasTooltip(GTK.TRUE);
// box.append(openDir);
ListItem.castFrom(item).setChild(box);
((ListItem) item).setChild(box);
//TODO server launch with network-server-symbolic
//TODO kill current instance
});
onBind(($, item) -> {
onBind(item -> {
// Label label = new Label(item.getChild().getFirstChild().cast());
// Button launch = new Button(label.getNextSibling().cast());
// Button openDir = new Button(launch.getNextSibling().cast());
@ -62,13 +62,13 @@ public class InstanceGridEntryFactory extends SignalListItemFactory {
// launch.onClicked(() -> GtkMenubar.launch(instance));
// openDir.onClicked(() -> Utils.openFile(instance.path().toFile()));
ListItem li = ListItem.castFrom(item);
ListItem li = (ListItem) item;
Box box = Box.castFrom(li.getChild());
InstanceThumbnail thumbnail = InstanceThumbnail.castFrom(box.firstChild);
Label label = Label.castFrom(thumbnail.nextSibling);
Box box = (Box) li.getChild();
InstanceThumbnail thumbnail = (InstanceThumbnail) box.firstChild;
Label label = (Label) thumbnail.nextSibling;
Instance instance = instanceList.get(ListIndex.toIndex(li));
Instance instance = instanceList.get(((ListIndexItem) li.getItem()).getIntValue());
thumbnail.bind(instance);
label.text = instance.toString();
//TODO right click menu + double click action

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.inceptum.gtk.control;
import io.gitlab.jfronny.inceptum.gtk.util.ListIndex;
import io.gitlab.jfronny.inceptum.gtk.util.ListIndexItem;
import org.gnome.adw.ActionRow;
import org.gtk.gtk.*;
import io.gitlab.jfronny.inceptum.common.Utils;
@ -13,7 +13,7 @@ import java.util.List;
public class InstanceListEntryFactory extends SignalListItemFactory {
public InstanceListEntryFactory(List<Instance> instanceList) {
super();
onSetup(($, item) -> {
onSetup(item -> {
var thumbnail = new InstanceThumbnail();
thumbnail.name = "inceptum-thumbnail";
@ -36,22 +36,22 @@ public class InstanceListEntryFactory extends SignalListItemFactory {
row.addSuffix(launch);
row.addSuffix(openDir);
ListItem.castFrom(item).setChild(row);
((ListItem) item).setChild(row);
//TODO server launch with network-server-symbolic
//TODO kill current instance
});
onBind(($, item) -> {
ListItem li = ListItem.castFrom(item);
onBind(item -> {
ListItem li = (ListItem) item;
Instance instance = instanceList.get(ListIndex.toIndex(li));
ActionRow row = ActionRow.castFrom(li.child);
Box prefixes = Box.castFrom(row.firstChild.firstChild);
Box suffixes = Box.castFrom(row.firstChild.lastChild);
Instance instance = instanceList.get(((ListIndexItem) li.getItem()).getIntValue());
ActionRow row = (ActionRow) li.child;
Box prefixes = (Box) row.firstChild.firstChild;
Box suffixes = (Box) row.firstChild.lastChild;
InstanceThumbnail thumbnail = InstanceThumbnail.castFrom(prefixes.firstChild);
Button launch = Button.castFrom(suffixes.firstChild);
Button openDir = Button.castFrom(launch.nextSibling);
InstanceThumbnail thumbnail = InstanceThumbnail.castFrom((Stack) prefixes.firstChild);
Button launch = (Button) suffixes.firstChild;
Button openDir = (Button) launch.nextSibling;
row.title = instance.toString();
// InstanceThumbnail thumbnail = new InstanceThumbnail(row.getFirstChild().cast());
@ -61,8 +61,8 @@ public class InstanceListEntryFactory extends SignalListItemFactory {
thumbnail.bind(instance);
// label.setText(new Str(instance.toString()));
launch.onClicked($1 -> GtkMenubar.launch(instance));
openDir.onClicked($1 -> Utils.openFile(instance.path().toFile()));
launch.onClicked(() -> GtkMenubar.launch(instance));
openDir.onClicked(() -> Utils.openFile(instance.path().toFile()));
//TODO why the hell does this crash the VM?
//TODO GestureClick.setButton(GDK_BUTTON_SECONDARY)

View File

@ -1,11 +1,7 @@
package io.gitlab.jfronny.inceptum.gtk.control;
import io.github.jwharm.javagi.Ownership;
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import org.gtk.gobject.*;
import org.gtk.gtk.Image;
import org.gtk.gtk.Spinner;
import org.gtk.gtk.Stack;
import org.gtk.gtk.*;
import java.lang.foreign.Addressable;
@ -14,16 +10,12 @@ public class InstanceThumbnail extends Stack {
private static final String IMAGE = "image";
private static final String GENERIC = "generic";
private InstanceThumbnail(Addressable address, Ownership ownership) {
super(address, ownership);
private InstanceThumbnail(Addressable address) {
super(address);
}
public static InstanceThumbnail castFrom(org.gtk.gobject.GObject gobject) {
if (GObjects.typeCheckInstanceIsA(TypeInstance.fromAddress.marshal(gobject.handle(), Ownership.NONE), Stack.getType())) {
return new InstanceThumbnail(gobject.handle(), gobject.yieldOwnership());
} else {
throw new ClassCastException("Object type is not an instance of GtkStack");
}
public static InstanceThumbnail castFrom(Stack stack) {
return new InstanceThumbnail(stack.handle());
}
public InstanceThumbnail() {
@ -41,9 +33,9 @@ public class InstanceThumbnail extends Stack {
}
public void bind(Instance entry) {
var spinner = Spinner.castFrom(getChildByName(SPINNER));
var image = Image.castFrom(getChildByName(IMAGE)); //TODO
var generic = Image.castFrom(getChildByName(GENERIC));
var spinner = (Spinner) getChildByName(SPINNER);
var image = (Image) getChildByName(IMAGE); //TODO
var generic = (Image) getChildByName(GENERIC);
//TODO mark instance being played
if (entry.isSetupLocked) {
visibleChild = spinner;

View File

@ -28,7 +28,7 @@ public class MenuBuilder {
app.menubar = menu;
return menu;
} else {
return Menu.castFrom(currentMenu);
return (Menu) currentMenu;
}
}
}
@ -57,7 +57,7 @@ public class MenuBuilder {
internalName = prefix + internalName;
SimpleAction sAct = new SimpleAction(internalName, null);
addAction(internalName, sAct);
sAct.onActivate(($, variant) -> {
sAct.onActivate(variant -> {
try {
onClick.run();
} catch (Throwable e) {
@ -72,7 +72,7 @@ public class MenuBuilder {
name = prefix + name;
SimpleAction sAct = SimpleAction.newStateful(name, null, Variant.newBoolean(initial));
addAction(name, sAct);
sAct.onActivate(($, variant) -> {
sAct.onActivate(variant -> {
boolean state = !sAct.getState().getBoolean();
sAct.state = Variant.newBoolean(state);
action.accept(state);
@ -90,7 +90,7 @@ public class MenuBuilder {
name = prefix + name;
SimpleAction sAct = SimpleAction.newStateful(name, new VariantType("i"), Variant.newInt32(options.indexOf(initial)));
addAction(name, sAct);
sAct.onActivate(($, variant) -> {
sAct.onActivate(variant -> {
sAct.state = variant;
action.accept(options.get(variant.getInt32()));
});

View File

@ -1,192 +0,0 @@
package io.gitlab.jfronny.inceptum.gtk.util;
import io.github.jwharm.javagi.*;
import io.gitlab.jfronny.inceptum.gtk.GtkMain;
import io.gitlab.jfronny.inceptum.gtk.callback.*;
import org.gtk.gio.ListModel;
import org.gtk.gio.ListModelInterface;
import org.gtk.glib.Type;
import org.gtk.gobject.*;
import org.gtk.gtk.*;
import java.lang.foreign.*;
import java.lang.invoke.VarHandle;
public class ListIndex extends GObject {
private static final int PROP_ITEM_TYPE = 1;
private static final String PROP_NAME = "item-type";
private static final String TYPE_NAME = "ListIndex";
private static final Type PARENT_TYPE = GObject.getType();
private static final MemoryLayout memoryLayout = MemoryLayout.structLayout(
GObject.getMemoryLayout().withName("parent_instance"),
Interop.valueLayout.C_INT.withName("index"),
Interop.valueLayout.C_INT.withName("size")
).withName(TYPE_NAME);
private static Type type;
public static Type getType() {
if (type == null) {
// Register the new gtype
type = GObjects.typeRegisterStaticSimple(
PARENT_TYPE,
TYPE_NAME,
(short) ObjectClass.getMemoryLayout().byteSize(),
classInit,
(short) memoryLayout.byteSize(),
instanceInit,
TypeFlags.NONE
);
GObjects.typeAddInterfaceStatic(type, ListModel.getType(), InterfaceInfo.builder()
.setInterfaceInit(interfaceInit)
.setInterfaceData(null)
.setInterfaceFinalize(null)
.build());
}
return type;
}
private static final VarHandle index = memoryLayout.varHandle(MemoryLayout.PathElement.groupElement("index"));
private static final VarHandle size = memoryLayout.varHandle(MemoryLayout.PathElement.groupElement("size"));
public static ListIndex castFrom(GObject gobject) {
if (GObjects.typeCheckInstanceIsA(TypeInstance.fromAddress.marshal(gobject.handle(), Ownership.NONE), getType())) {
return new ListIndex(gobject.handle(), gobject.yieldOwnership());
} else {
throw new ClassCastException("Object type is not an instance of ListIndex");
}
}
public static final Marshal<Addressable, ListIndex> fromAddress = (input, ownership) -> input.equals(MemoryAddress.NULL) ? null : new ListIndex(input, ownership);
protected ListIndex(Addressable address, Ownership ownership) {
super(address, ownership);
}
public ListIndex(int size) {
this();
setSizeIntenal(size);
}
public ListIndex() {
super(new GObject(getType(), PROP_NAME, getType()).handle(),
Ownership.FULL);
}
private static final InstanceInitFunc instanceInit = (instance, gClass) -> fromAddress.marshal(instance.handle(), Ownership.NONE).initInstance();
private void initInstance() {
setIndex(0);
setSizeIntenal(0);
}
private static TypeClass parentClass = null;
private static final DisposeCallback instanceDispose = pointer -> {
if (parentClass == null) System.out.println("ListIndex::instanceDispose (no parent)");
else {
InteropException ie = new InteropException("Could not dispose ListIndex");
GtkMain.schedule(() -> {
try {
var func = (MemoryAddress) ObjectClass.getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("dispose"))
.get(MemorySegment.ofAddress(parentClass.handle().address(), ObjectClass.getMemoryLayout().byteSize(), Interop.getScope()));
var linked = Linker.nativeLinker().downcallHandle(func, DisposeCallback.DESCRIPTOR);
linked.invoke(pointer);
} catch (Throwable e) {
throw (InteropException) ie.initCause(e);
}
});
}
};
private static final SetPropertyCallback setProperty = (object, propertyId, value, paramSpec) -> {
if (propertyId != PROP_ITEM_TYPE) System.out.println("ListIndex::setProperty (unknown property)");
};
private static final GetPropertyCallback getProperty = (object, propertyId, value, paramSpec) -> {
if (propertyId == PROP_ITEM_TYPE) value.setGtype(getType());
else System.out.println("ListIndex::getProperty (unknown property)");
};
private static final ClassInitFunc classInit = (klass, data) -> {
System.out.println("ListIndex::classInit");
parentClass = klass.peekParent();
ObjectClass objectClass = ObjectClass.fromAddress.marshal(GObjects.typeCheckClassCast(klass, PARENT_TYPE).handle(), Ownership.NONE);
objectClass.setDispose(instanceDispose.toCallback());
objectClass.setGetProperty(getProperty.toCallback());
objectClass.setSetProperty(setProperty.toCallback());
ParamSpec paramType = GObjects.paramSpecGtype(PROP_NAME, "", "", PARENT_TYPE,
ParamFlags.CONSTRUCT
.or(ParamFlags.READWRITE,
ParamFlags.STATIC_NAME,
ParamFlags.STATIC_NICK,
ParamFlags.STATIC_BLURB)
);
objectClass.installProperty(PROP_ITEM_TYPE, paramType);
};
private static final GetItemTypeCallback getItemType = address -> {
System.out.println("ListIndex::getItemType");
return getType().getValue();
};
private static final GetNItemsCallback getNItems = address -> fromAddress.marshal(address, Ownership.NONE).getSize();
private static final GetItemCallback getItem = (inst, position) -> {
ListIndex item = fromAddress.marshal(inst, Ownership.NONE).getItem(position);
if (item == null) return MemoryAddress.NULL;
return item.handle();
};
public ListIndex getItem(int position) {
if (position >= getSize() || position <= -1) return null;
ListIndex result = new ListIndex(getSize());
result.setIndex(position);
return result;
}
private static final InterfaceInitFunc interfaceInit = (iface, data) -> {
System.out.println("ListIndex::interfaceInit");
ListModelInterface lmi = ListModelInterface.fromAddress.marshal(iface.handle(), Ownership.NONE);
lmi.setGetItem(getItem.toCallback());
lmi.setGetNItems(getNItems.toCallback());
lmi.setGetItemType(getItemType.toCallback());
};
public int getIndex() {
return (int) ListIndex.index.get(MemorySegment.ofAddress((MemoryAddress) handle(), memoryLayout.byteSize(), Interop.getScope()));
}
public void setIndex(int index) {
ListIndex.index.set(MemorySegment.ofAddress((MemoryAddress) handle(), memoryLayout.byteSize(), Interop.getScope()), index);
}
public int getSize() {
return (int) ListIndex.size.get(MemorySegment.ofAddress((MemoryAddress) handle(), memoryLayout.byteSize(), Interop.getScope()));
}
public void setSize(int size) {
int oldSize = getSize();
setSizeIntenal(size);
asListModel().itemsChanged(0, oldSize, size);
}
private void setSizeIntenal(int size) {
ListIndex.size.set(MemorySegment.ofAddress((MemoryAddress) handle(), memoryLayout.byteSize(), Interop.getScope()), size);
}
public ListModel asListModel() {
return ListModel.castFrom(this);
}
public SingleSelection inSingleSelection() {
return new SingleSelection(asListModel());
}
public SelectionModel inSelectionModel() {
return SelectionModel.castFrom(inSingleSelection());
}
public static int toIndex(ListItem item) {
return castFrom(item.getItem()).getIndex();
}
}

View File

@ -0,0 +1,59 @@
package io.gitlab.jfronny.inceptum.gtk.util;
import io.github.jwharm.javagi.Interop;
import io.github.jwharm.javagi.Marshal;
import org.gtk.glib.Type;
import org.gtk.gobject.*;
import java.lang.foreign.*;
public class ListIndexItem extends GObject {
protected ListIndexItem(Addressable address) {
super(address);
}
public static final Marshal<Addressable, ListIndexItem> fromAddress =
(input, scope) -> input.equals(MemoryAddress.NULL) ? null : new ListIndexItem(input);
public static MemoryLayout getMemoryLayout() {
return MemoryLayout.structLayout(
GObject.getMemoryLayout().withName("parent_instance"),
Interop.valueLayout.C_INT.withName("int_value")
).withName("ListIndexModel");
}
private static Type type;
public static Type getType() {
if (type == null) {
// Register the new gtype
type = GObjects.typeRegisterStaticSimple(
GObject.getType(),
"ListIndexItem",
(short) ObjectClass.getMemoryLayout().byteSize(),
gclass -> {},
(short) getMemoryLayout().byteSize(),
(inst, gclass) -> {},
TypeFlags.NONE
);
}
Interop.register(type, fromAddress);
return type;
}
public void setIntValue(int value) {
getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("int_value"))
.set(MemorySegment.ofAddress((MemoryAddress) handle(), getMemoryLayout().byteSize(), MemorySession.openImplicit()), value);
}
public int getIntValue() {
return (int) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("int_value"))
.get(MemorySegment.ofAddress((MemoryAddress) handle(), getMemoryLayout().byteSize(), MemorySession.openImplicit()));
}
public ListIndexItem(int value) {
super(getType(), null);
setIntValue(value);
}
}

View File

@ -0,0 +1,87 @@
package io.gitlab.jfronny.inceptum.gtk.util;
import io.github.jwharm.javagi.Interop;
import io.github.jwharm.javagi.Marshal;
import org.gtk.gio.ListModel;
import org.gtk.gio.ListModelInterface;
import org.gtk.glib.Type;
import org.gtk.gobject.*;
import java.lang.foreign.*;
public class ListIndexModel extends GObject implements ListModel {
protected ListIndexModel(Addressable address) {
super(address);
}
public static final Marshal<Addressable, ListIndexModel> fromAddress =
(input, scope) -> input.equals(MemoryAddress.NULL) ? null : new ListIndexModel(input);
public static MemoryLayout getMemoryLayout() {
return MemoryLayout.structLayout(
GObject.getMemoryLayout().withName("parent_instance"),
Interop.valueLayout.C_INT.withName("size")
).withName("ListIndexModel");
}
private static Type type;
public static Type getType() {
if (type == null) {
// Register the new gtype
type = GObjects.typeRegisterStaticSimple(
GObject.getType(),
"ListIndexModel",
(short) ObjectClass.getMemoryLayout().byteSize(),
gclass -> {},
(short) getMemoryLayout().byteSize(),
(inst, gclass) -> {},
TypeFlags.NONE
);
GObjects.typeAddInterfaceStatic(type, ListModel.getType(), InterfaceInfo.builder()
.setInterfaceInit(iface -> {
ListModelInterface lmi = ListModelInterface.fromAddress.marshal(iface.handle(), null);
lmi.setGetItemType(ListModel::getItemType);
lmi.setGetNItems(ListModel::getNItems);
lmi.setGetItem(ListModel::getItem);
})
.setInterfaceData(null)
.setInterfaceFinalize(null)
.build());
}
Interop.register(type, fromAddress);
return type;
}
private ListIndexModel() {
super(getType(), null);
}
public ListIndexModel(int size) {
this();
setSize(size);
}
public void setSize(int size) {
getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("size"))
.set(MemorySegment.ofAddress((MemoryAddress) handle(), getMemoryLayout().byteSize(), MemorySession.openImplicit()), size);
}
@Override
public Type getItemType() {
return ListIndexItem.getType();
}
@Override
public int getNItems() {
return (int) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("size"))
.get(MemorySegment.ofAddress((MemoryAddress) handle(), getMemoryLayout().byteSize(), MemorySession.openImplicit()));
}
@Override
public GObject getItem(int position) {
if (position < 0 || position >= getNItems()) return null;
return new ListIndexItem(position);
}
}

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.inceptum.gtk.window;
import io.gitlab.jfronny.inceptum.gtk.util.ListIndex;
import io.gitlab.jfronny.inceptum.gtk.util.ListIndexModel;
import org.gnome.adw.Clamp;
import org.gnome.adw.StatusPage;
import org.gtk.gio.Menu;
@ -31,7 +31,7 @@ public class MainWindow extends ApplicationWindow {
private final Clamp listView;
private final GridView gridView;
private final List<Instance> instanceList;
private final ListIndex instanceListIndex;
private final ListIndexModel instanceListIndex;
public MainWindow(Application app) {
super(app);
@ -39,7 +39,7 @@ public class MainWindow extends ApplicationWindow {
HeaderBar header = new HeaderBar();
Button newButton = new Button();
newButton.setIconName("list-add-symbolic");
newButton.onClicked($ -> NewInstanceWindow.createAndShow());
newButton.onClicked(NewInstanceWindow::createAndShow);
MenuButton accountsButton = new MenuButton();
accountsButton.setIconName("avatar-default-symbolic");
@ -47,7 +47,7 @@ public class MainWindow extends ApplicationWindow {
listButton = new Button();
listButton.setIconName("view-list-symbolic");
listButton.onClicked($ -> {
listButton.onClicked(() -> {
InceptumConfig.listView = true;
InceptumConfig.saveConfig();
generateWindowBody();
@ -55,7 +55,7 @@ public class MainWindow extends ApplicationWindow {
gridButton = new Button();
gridButton.setIconName("view-grid-symbolic");
gridButton.onClicked($ -> {
gridButton.onClicked(() -> {
InceptumConfig.listView = false;
InceptumConfig.saveConfig();
generateWindowBody();
@ -79,12 +79,13 @@ public class MainWindow extends ApplicationWindow {
header.packEnd(accountsButton);
instanceList = new ArrayList<>();
instanceListIndex = new ListIndex();
instanceListIndex = new ListIndexModel(instanceList.size());
var singleSelection = new SingleSelection(instanceListIndex);
listView = new Clamp();
listView.maximumSize = 900;
listView.child = new ListView(instanceListIndex.inSelectionModel(), new InstanceListEntryFactory(instanceList));
gridView = new GridView(instanceListIndex.inSelectionModel(), new InstanceGridEntryFactory(instanceList));
listView.child = new ListView(singleSelection, new InstanceListEntryFactory(instanceList));
gridView = new GridView(singleSelection, new InstanceGridEntryFactory(instanceList));
empty = new StatusPage();
empty.title = I18n.get("main.empty.title");
empty.description = I18n.get("main.empty.description");
@ -117,7 +118,7 @@ public class MainWindow extends ApplicationWindow {
private void setupDirWatcher() throws IOException { //TODO test (including after lock state change)
WatchService ws = FileSystems.getDefault().newWatchService();
MetaHolder.INSTANCE_DIR.register(ws, ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE);
int source = GLib.idleAdd(data -> {
int source = GLib.idleAdd(() -> {
//TODO watch instance dirs for locks
WatchKey key = ws.poll();
boolean instancesChanged = false;
@ -125,14 +126,14 @@ public class MainWindow extends ApplicationWindow {
for (WatchEvent<?> event : key.pollEvents()) {
if (event.context() instanceof Path p) {
p = MetaHolder.INSTANCE_DIR.resolve(p);
instancesChanged |= Files.exists(p.resolve("instance.json"));
instancesChanged |= Files.exists(p.resolve(InstanceList.INSTANCE_CONFIG_NAME));
}
}
}
if (instancesChanged) generateWindowBody();
return true;
}, null);
onCloseRequest($ -> {
});
onCloseRequest(() -> {
try {
ws.close();
} catch (IOException ignored) {

View File

@ -29,8 +29,8 @@ public class InstanceView {
ImGui.text("This instance is currently being set up");
continue;
}
if (!Files.exists(instance.path.resolve("instance.json"))) {
Utils.LOGGER.error("Invalid instance (doesn't contain instance.json): " + instance);
if (!Files.exists(instance.path.resolve(InstanceList.INSTANCE_CONFIG_NAME))) {
Utils.LOGGER.error("Invalid instance (doesn't contain " + InstanceList.INSTANCE_CONFIG_NAME + "): " + instance);
continue;
}
ImGui.tableNextColumn();

View File

@ -6,6 +6,7 @@ import io.gitlab.jfronny.inceptum.launcher.api.McApi;
import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAccount;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Objects;
@ -35,6 +36,7 @@ public class LauncherEnv {
if (!Files.exists(MetaHolder.LIBRARIES_DIR)) Files.createDirectories(MetaHolder.LIBRARIES_DIR);
if (Files.exists(MetaHolder.FORCE_LOAD_PATH)) {
Utils.LOGGER.info("Force-Loading libraries:");
System.setProperty("java.library.path", System.getProperty("java.library.path", "") + File.pathSeparator + MetaHolder.FORCE_LOAD_PATH);
JFiles.listTo(MetaHolder.FORCE_LOAD_PATH, path -> {
Utils.LOGGER.info("Loading " + path);
try {

View File

@ -60,7 +60,7 @@ public abstract class Importer<T> {
Instance.setSetupLock(iDir, true);
InstanceMeta meta = new InstanceMeta();
meta.version = createVersionString(man.gameVersion, man.fabricVersion);
GC_InstanceMeta.write(meta, iDir.resolve("instance.json"));
GC_InstanceMeta.write(meta, iDir.resolve(InstanceList.INSTANCE_CONFIG_NAME));
state.incrementStep("Downloading mods");
downloadMods(manifest, iDir, state);

View File

@ -132,7 +132,7 @@ public record Instance(String id, Path path, InstanceMeta meta, ModsDirScanner m
public void writeMeta() {
try {
GC_InstanceMeta.write(meta, path.resolve("instance.json"));
GC_InstanceMeta.write(meta, path.resolve(InstanceList.INSTANCE_CONFIG_NAME));
} catch (IOException e) {
Utils.LOGGER.error("Could not write instance config", e);
}

View File

@ -16,6 +16,7 @@ import java.util.*;
public class InstanceList {
private static final Map<Path, IEntry> metas = new LinkedHashMap<>();
public static final String INSTANCE_CONFIG_NAME = "instance.json";
public static void reset() {
synchronized (metas) {
@ -61,7 +62,7 @@ public class InstanceList {
if (!metas.containsKey(instancePath)) {
metas[instancePath] = new IEntry(
instancePath,
new FileBackedRef<>(instancePath.resolve("instance.json"), GC_InstanceMeta::read)
new FileBackedRef<>(instancePath.resolve(INSTANCE_CONFIG_NAME), GC_InstanceMeta::read)
);
}
return metas[instancePath].toPub();
@ -69,7 +70,7 @@ public class InstanceList {
}
private static boolean isInstance(Path path) {
return Files.isDirectory(path) && Files.exists(path.resolve("instance.json"));
return Files.isDirectory(path) && Files.exists(path.resolve(INSTANCE_CONFIG_NAME));
}
private record IEntry(Path path, FileBackedRef<InstanceMeta> meta) implements Closeable {

View File

@ -2,6 +2,7 @@ package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta.GC_InstanceMeta;
import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
@ -15,7 +16,7 @@ public class RunMdsStep implements Step {
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
info.setState("Running MDS");
Path instance = MetaHolder.INSTANCE_DIR.resolve(info.name);
ModsDirScanner.get(instance.resolve("mods"), GC_InstanceMeta.read(instance.resolve("instance.json")))
ModsDirScanner.get(instance.resolve("mods"), GC_InstanceMeta.read(instance.resolve(InstanceList.INSTANCE_CONFIG_NAME)))
.runOnce((path, iwModDescription) -> info.setState("Scanned " + path));
}
}

View File

@ -4,6 +4,7 @@ import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.inceptum
import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
@ -17,7 +18,7 @@ public class WriteMetadataStep implements Step {
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
info.setState("Writing metadata");
Path instance = MetaHolder.INSTANCE_DIR.resolve(info.name);
Path metaPath = instance.resolve("instance.json");
Path metaPath = instance.resolve(InstanceList.INSTANCE_CONFIG_NAME);
if (!Files.exists(metaPath)) {
InstanceMeta meta = new InstanceMeta();
meta.version = info.version.id;
@ -40,7 +41,7 @@ public class WriteMetadataStep implements Step {
realms_persistence.json""");
}
if (!Files.exists(instance.resolve(".iceignore"))) {
Files.writeString(instance.resolve(".iceignore"), "instance.json");
Files.writeString(instance.resolve(".iceignore"), InstanceList.INSTANCE_CONFIG_NAME);
}
}
}

View File

@ -1,5 +1,6 @@
package io.gitlab.jfronny.inceptum.launchwrapper;
import java.io.File;
import java.lang.invoke.*;
import java.lang.reflect.Method;
import java.nio.file.*;
@ -12,6 +13,7 @@ public class Main {
String forceloadNatives = System.getProperty("inceptum.forceloadNatives");
if (forceloadNatives != null) {
System.setProperty("java.library.path", System.getProperty("java.library.path", "") + File.pathSeparator + forceloadNatives);
Path p = Paths.get(forceloadNatives);
if (Files.exists(p)) {
try (Stream<Path> paths = Files.list(p)) {