kitgit

tirbofish/dropbear · diff

e50a2c0 · tk

significant progress, such as more work gradle and have generated a java native interface. still trying to get an idea of what might be best. for now, im merging back onto main and removing swift entirely.

Unverified

diff --git a/.run/build.run.xml b/.run/build.run.xml
new file mode 100644
index 0000000..87e14e1
--- /dev/null
+++ b/.run/build.run.xml
@@ -0,0 +1,24 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="build" type="GradleRunConfiguration" factoryName="Gradle">
+    <ExternalSystemSettings>
+      <option name="executionName" />
+      <option name="externalProjectPath" value="$PROJECT_DIR$" />
+      <option name="externalSystemIdString" value="GRADLE" />
+      <option name="scriptParameters" value="" />
+      <option name="taskDescriptions">
+        <list />
+      </option>
+      <option name="taskNames">
+        <list>
+          <option value="build" />
+        </list>
+      </option>
+      <option name="vmOptions" />
+    </ExternalSystemSettings>
+    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
+    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
+    <DebugAllEnabled>false</DebugAllEnabled>
+    <RunAsTest>false</RunAsTest>
+    <method v="2" />
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/.run/generateJniHeaders.run.xml b/.run/generateJniHeaders.run.xml
new file mode 100644
index 0000000..acc9512
--- /dev/null
+++ b/.run/generateJniHeaders.run.xml
@@ -0,0 +1,24 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="generateJniHeaders" type="GradleRunConfiguration" factoryName="Gradle">
+    <ExternalSystemSettings>
+      <option name="executionName" />
+      <option name="externalProjectPath" value="$PROJECT_DIR$" />
+      <option name="externalSystemIdString" value="GRADLE" />
+      <option name="scriptParameters" value="" />
+      <option name="taskDescriptions">
+        <list />
+      </option>
+      <option name="taskNames">
+        <list>
+          <option value="generateJniHeaders" />
+        </list>
+      </option>
+      <option name="vmOptions" />
+    </ExternalSystemSettings>
+    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
+    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
+    <DebugAllEnabled>false</DebugAllEnabled>
+    <RunAsTest>false</RunAsTest>
+    <method v="2" />
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 089e30f..3a523da 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -60,7 +60,7 @@ backtrace = "0.3"
 gltf = "1"
 os_info = "3.12"
 rustc_version_runtime = "0.3"
-libloading = "0.8"
+jni = { version = "0.21", features = ["invocation"] }
 
 [workspace.dependencies.image]
 version = "0.25"
diff --git a/build.gradle.kts b/build.gradle.kts
index 1e72603..cbfc7df 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,6 +11,7 @@ repositories {
 
 dependencies {
     testImplementation(kotlin("test"))
+    implementation(kotlin("test"))
 }
 
 tasks.test {
@@ -18,4 +19,26 @@ tasks.test {
 }
 kotlin {
     jvmToolchain(21)
-}
\ No newline at end of file
+}
+
+sourceSets {
+    main {
+        java.srcDirs("src/main/kotlin", "src/main/java")
+    }
+}
+
+tasks.register<JavaCompile>("generateJniHeaders") {
+    val outputDir = layout.buildDirectory.dir("generated/jni-headers")
+    options.headerOutputDirectory.set(outputDir.get().asFile)
+
+    classpath = files(
+        tasks.named("compileKotlin"),
+        tasks.named("compileJava")
+    )
+
+    source = fileTree("src/main/java") {
+        include("**/*.java")
+    }
+
+    dependsOn("compileJava", "compileKotlin")
+}
diff --git a/eucalyptus-core/Cargo.toml b/eucalyptus-core/Cargo.toml
index ee6dc6b..c2122bd 100644
--- a/eucalyptus-core/Cargo.toml
+++ b/eucalyptus-core/Cargo.toml
@@ -25,8 +25,8 @@ serde.workspace = true
 winit.workspace = true
 tokio.workspace = true
 rayon.workspace = true
-libloading.workspace = true
-crossbeam-channel.workspace = true
+jni.workspace = true
+lazy_static = "1.5.0"
 
 [features]
 editor = []
diff --git a/eucalyptus-core/src/input.rs b/eucalyptus-core/src/input.rs
index 8da40f1..fcda409 100644
--- a/eucalyptus-core/src/input.rs
+++ b/eucalyptus-core/src/input.rs
@@ -2,7 +2,6 @@ use std::{
     collections::{HashMap, HashSet},
     time::{Duration, Instant},
 };
-use serde::{Deserialize, Serialize};
 use winit::{event::MouseButton, keyboard::KeyCode};
 
 #[derive(Clone)]
diff --git a/eucalyptus-core/src/scripting.rs b/eucalyptus-core/src/scripting.rs
index 561f097..d3907e5 100644
--- a/eucalyptus-core/src/scripting.rs
+++ b/eucalyptus-core/src/scripting.rs
@@ -1,15 +1,12 @@
+mod java;
+
 use crate::input::InputState;
 use crate::states::{EntityNode, PROJECT, SOURCE, ScriptComponent, Value};
 use dropbear_engine::entity::{AdoptedEntity, Transform};
 use hecs::{Entity, World};
 use std::path::PathBuf;
 use std::{collections::HashMap, fs};
-use std::env::current_exe;
-use glam::{Quat, Vec3};
-use libloading::{library_filename, Library};
-use once_cell::sync::Lazy;
-use parking_lot::Mutex;
-use serde::{Deserialize, Serialize};
+use crate::scripting::java::JavaContext;
 
 pub const TEMPLATE_SCRIPT: &str = include_str!("../../resources/scripting/swift/sample.swift");
 
@@ -86,7 +83,7 @@ impl DropbearScriptingAPIContext {
 
 pub struct ScriptManager {
     script_context: DropbearScriptingAPIContext,
-    // library: Library,
+    java: JavaContext,
 }
 
 impl ScriptManager {
@@ -95,11 +92,10 @@ impl ScriptManager {
         // let library = unsafe { Library::new(lib_path.clone())? };
 
         let result = Self {
-            // library,
+            java: JavaContext::new()?,
             script_context: DropbearScriptingAPIContext::new(),
         };
 
-        // log::info!("Loaded {} from {}", library_filename("dropbear").display(), lib_path.display());
         log::debug!("Initialised ScriptManager");
         Ok(result)
     }
diff --git a/eucalyptus-core/src/scripting/java.rs b/eucalyptus-core/src/scripting/java.rs
new file mode 100644
index 0000000..0b18927
--- /dev/null
+++ b/eucalyptus-core/src/scripting/java.rs
@@ -0,0 +1,20 @@
+use jni::{InitArgsBuilder, JNIVersion, JavaVM};
+
+/// A dropbear wrapper for Java Virtual Machine (JVM) based functions
+pub(crate) struct JavaContext {
+    jvm: JavaVM,
+}
+
+impl JavaContext {
+    pub fn new() -> anyhow::Result<Self> {
+        let jvm_args = InitArgsBuilder::new()
+            .version(JNIVersion::V8)
+            .build()?;
+
+        let jvm = JavaVM::new(jvm_args)?;
+        log::info!("Initialised JVM");
+        Ok(Self {
+            jvm
+        })
+    }
+}
\ No newline at end of file
diff --git a/eucalyptus-editor/src/main.rs b/eucalyptus-editor/src/main.rs
index 88687c1..e2d5bf2 100644
--- a/eucalyptus-editor/src/main.rs
+++ b/eucalyptus-editor/src/main.rs
@@ -11,7 +11,6 @@ mod signal;
 use clap::{Arg, Command};
 use dropbear_engine::{scene, WindowConfiguration};
 use std::{fs, path::PathBuf, rc::Rc};
-use std::panic::catch_unwind;
 use std::sync::Arc;
 use parking_lot::RwLock;
 use dropbear_engine::future::FutureQueue;
diff --git a/src/main/kotlin/com/dropbear/DropbearEngine.kt b/src/main/kotlin/com/dropbear/DropbearEngine.kt
new file mode 100644
index 0000000..44722c3
--- /dev/null
+++ b/src/main/kotlin/com/dropbear/DropbearEngine.kt
@@ -0,0 +1,28 @@
+package com.dropbear
+
+import com.dropbear.ffi.NativeEngine
+
+class DropbearEngine {
+    var nativeEngine: NativeEngine? = null
+
+    // figure out how to create a new class
+    /**
+     * Fetches the currently active entity the script is attached to.
+     *
+     * If there is no entity this script is attached to, it will return
+     * a `null` in the form of a [Result]
+     */
+    fun getActiveEntity(): Result<EntityRef> {
+        return Result.failure(Exception("Function not implemented"))
+    }
+
+    /**
+     * Fetches an entity based on its label in the editor.
+     *
+     * If there is no entity under that label, it will return a
+     * `null` in the form of a [Result]
+     */
+    fun getEntity(label: String): EntityRef? {
+        return null
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/dropbear/EntityRef.kt b/src/main/kotlin/com/dropbear/EntityRef.kt
new file mode 100644
index 0000000..7bccd3c
--- /dev/null
+++ b/src/main/kotlin/com/dropbear/EntityRef.kt
@@ -0,0 +1,27 @@
+package com.dropbear
+
+import com.dropbear.math.Vector3D
+
+/**
+ * A class to hold a reference to an entity.
+ *
+ * The dropbear engine interface is made in Rust, which uses a
+ * borrow checker paradigm, which heavily utilises immutability
+ * unless explicitly provided with the `mut` keyword.
+ *
+ * Because of this, the primary source of the World (place to store
+ * entities) is stored in Rust, and passing an EntityRef (which contains
+ * an ID) follows Rust's ideologies of passing references instead of the entire entity,
+ * which provides immutability.
+ *
+ * To edit any values part of the entity, take a look at the functions provided
+ * by [EntityRef], which will require a reference to [DropbearEngine] to push the commands.
+ */
+class EntityRef {
+    var label: String = ""
+
+    /**
+     * Sets the position of the entity by a Vector
+     */
+    fun setPosition(position: Vector3D, engine: DropbearEngine) {}
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/dropbear/Example.kt b/src/main/kotlin/com/dropbear/Example.kt
new file mode 100644
index 0000000..e1ef013
--- /dev/null
+++ b/src/main/kotlin/com/dropbear/Example.kt
@@ -0,0 +1,12 @@
+package com.dropbear
+
+class Example(override var engine: DropbearEngine) : RunnableScript {
+    override fun load() {
+        val entity = engine.getActiveEntity()
+
+    }
+
+    override fun update() {
+        TODO("Not yet implemented")
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/dropbear/Main.kt b/src/main/kotlin/com/dropbear/Main.kt
deleted file mode 100644
index 8ba4d97..0000000
--- a/src/main/kotlin/com/dropbear/Main.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.dropbear
-
-fun main() {
-    println("Hello World!")
-}
\ No newline at end of file
diff --git a/src/main/kotlin/com/dropbear/RunnableScript.kt b/src/main/kotlin/com/dropbear/RunnableScript.kt
new file mode 100644
index 0000000..d7cb338
--- /dev/null
+++ b/src/main/kotlin/com/dropbear/RunnableScript.kt
@@ -0,0 +1,21 @@
+package com.dropbear
+
+/**
+ * The basic interface that all classes implement for the class to be run.
+ */
+interface RunnableScript {
+    var engine: DropbearEngine
+    /**
+     * A function that is run once during the lifetime of the entity.
+     *
+     * It can be used to set initial properties such as health and more.
+     *
+     * ALl classes that implement RunnableScript need to implement the load function.
+     */
+    fun load()
+
+    /**
+     * A function that is run every frame during the lifetime of the entity.
+     */
+    fun update()
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/dropbear/ffi/NativeEngine.java b/src/main/kotlin/com/dropbear/ffi/NativeEngine.java
new file mode 100644
index 0000000..fbb19da
--- /dev/null
+++ b/src/main/kotlin/com/dropbear/ffi/NativeEngine.java
@@ -0,0 +1,17 @@
+package com.dropbear.ffi;
+
+import com.dropbear.math.Transform;
+
+/**
+ * A class for dealing with native functions that is required by the Kotlin scripting
+ * and the Rust game engine.
+ */
+public class NativeEngine {
+    /**
+     * Fetches the transform of the entity by its label in the editor
+     * @param label The label of the entity
+     * @return The {@link Transform} component if the entity exists, null if not.
+     */
+    public native Transform getTransformOfEntity(String label);
+    public native String getLabelOfAttachedEntity();
+}
diff --git a/src/main/kotlin/com/dropbear/math/Quaternion.kt b/src/main/kotlin/com/dropbear/math/Quaternion.kt
new file mode 100644
index 0000000..97779eb
--- /dev/null
+++ b/src/main/kotlin/com/dropbear/math/Quaternion.kt
@@ -0,0 +1,11 @@
+package com.dropbear.math
+
+typealias QuaternionD = Quaternion<Double>
+
+class Quaternion<T: Number>(var x: T, var y: T, var z: T, var w: T) {
+    companion object {
+        fun identity(): Quaternion<Double> {
+            return Quaternion(0.0, 0.0, 0.0, 1.0)
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/dropbear/math/Transform.kt b/src/main/kotlin/com/dropbear/math/Transform.kt
new file mode 100644
index 0000000..bfa039f
--- /dev/null
+++ b/src/main/kotlin/com/dropbear/math/Transform.kt
@@ -0,0 +1,9 @@
+package com.dropbear.math
+
+/**
+ * A class that keeps all the values of a Transform, which consists of a
+ * position ([Vector3D]), rotation([QuaternionD]) and a scale([Vector3D]).
+ */
+class Transform(var position: Vector3D, var rotation: QuaternionD, var scale: Vector3D) {
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/dropbear/math/Vector3.kt b/src/main/kotlin/com/dropbear/math/Vector3.kt
new file mode 100644
index 0000000..822dd23
--- /dev/null
+++ b/src/main/kotlin/com/dropbear/math/Vector3.kt
@@ -0,0 +1,29 @@
+package com.dropbear.math
+
+/**
+ * A class for holding a vector of `3` values of the same type.
+ */
+class Vector3<T: Number>(var x: T, var y: T, var z: T) {
+    companion object {
+        /**
+         * Creates a new [com.dropbear.math.Vector3] of type `T` with one value.
+         */
+        fun <T: Number> uniform(value: T): Vector3<T> {
+            return Vector3(value, value, value)
+        }
+
+        /**
+         * Creates a [com.dropbear.math.Vector3] of type [Double] filled with only zeroes
+         */
+        fun zero(): Vector3<Double> {
+            return Vector3(0.0, 0.0, 0.0)
+        }
+    }
+
+    fun asDoubleVector(): Vector3<Double> {
+        return Vector3(this.x.toDouble(), this.y.toDouble(), this.z.toDouble())
+    }
+
+}
+
+typealias Vector3D = Vector3<Double>
\ No newline at end of file