Skip to content

Commit

Permalink
Add native method getComponents to Installation class
Browse files Browse the repository at this point in the history
Description
===========

This patch adds a new getter method `getComponents` to the
`Installation` class. This getter is bound to a native implementation
which  will return an Array with all installed components.

Changes
=======

![ADD] native getter `getComponents` to `Installation`
  • Loading branch information
Larusso committed Oct 31, 2018
1 parent ffec13e commit 65db543
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 10 deletions.
2 changes: 1 addition & 1 deletion jni/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ authors = ["Manfred Endres <manfred.endres@tslarusso.de>"]

[dependencies]
jni = "0.10.2"
uvm_core = { git = "https://github.com/Larusso/unity-version-manager.git", branch="feature/unity-hub-support"}
uvm_core = { git = "https://github.com/Larusso/unity-version-manager.git", rev="4959648f38b269e7e7064e65344b797d4833be3b"}
error-chain = "0.12.0"
log = "0.4.6"

Expand Down
60 changes: 55 additions & 5 deletions jni/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use std::str::FromStr;
use std::collections::HashSet;
use uvm_core::install::InstallVariant;
use std::error::Error;
use uvm_core::unity::Component;

mod error {
use jni;
Expand Down Expand Up @@ -69,6 +70,28 @@ mod jni_utils {
Ok(native_installation)
}

pub fn get_component<'a, 'b>(env: &'a JNIEnv<'b>, component: &'b Component) -> error::UvmJniResult<JObject<'a>> {
let component_class = env.find_class("net/wooga/uvm/Component")?;
let component_method = match component {
&Component::Android => "android",
&Component::Ios => "ios",
&Component::TvOs => "tvOs",
&Component::WebGl => "webGl",
&Component::Linux => "linux",
&Component::Windows => "windows",
&Component::WindowsMono => "windowsMono",
&Component::Editor => "editor",
&Component::Mono => "mono",
&Component::VisualStudio => "visualStudio",
&Component::MonoDevelop => "monoDevelop",
&Component::StandardAssets => "standardAssets",
&Component::Documentation => "documentation",
};
let native_component = env.get_static_field(component_class, component_method, "Lnet/wooga/uvm/Component;")?;
let native_component = native_component.l()?;
Ok(native_component)
}

pub fn print_error_and_return_null<E: Error>(err: E) -> jobject {
eprintln!("{}", err.description());
if let Some(source) = err.source() {
Expand Down Expand Up @@ -152,10 +175,10 @@ impl From<jint> for Variant {
match component {
0 => Variant(InstallVariant::Android),
1 => Variant(InstallVariant::Ios),
2 => Variant(InstallVariant::WebGl),
3 => Variant(InstallVariant::Linux),
4 => Variant(InstallVariant::Windows),
5 => Variant(InstallVariant::WindowsMono),
3 => Variant(InstallVariant::WebGl),
4 => Variant(InstallVariant::Linux),
5 => Variant(InstallVariant::Windows),
6 => Variant(InstallVariant::WindowsMono),
_ => Variant(InstallVariant::Android),
}
}
Expand Down Expand Up @@ -199,4 +222,31 @@ pub extern "system" fn Java_net_wooga_uvm_UnityVersionManager_installUnityEditor
pub extern "system" fn Java_net_wooga_uvm_UnityVersionManager_installUnityEditor__Ljava_lang_String_2Ljava_io_File_2_3Lnet_wooga_uvm_Component_2(env: JNIEnv, _class: JClass, version: JString, destination: JObject, components: jobjectArray) -> jobject {
install_unity_editor(&env, version, destination, Some(components))
.unwrap_or_else(jni_utils::print_error_and_return_null)
}
}

fn get_installation_components(env: &JNIEnv, object: JObject) -> error::UvmJniResult<jobjectArray> {
let location = env.call_method(object, "getLocation", "()Ljava/io/File;", &[])?;
let location = location.l()?;
let path = jni_utils::get_path(&env, location)?;

let installation = uvm_core::unity::Installation::new(path)?;
let components = uvm_core::unity::InstalledComponents::new(installation);
let components: Vec<Component> = components.collect();
let component_class = env.find_class("net/wooga/uvm/Component")?;

let output = env.new_object_array(components.len() as jsize, component_class, JObject::null())?;
for (i, component) in components.iter().enumerate() {
let native_component = jni_utils::get_component(&env, &component)?;
env.set_object_array_element(output, i as jsize, native_component)?;
}

Ok(output)
}


#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn Java_net_wooga_uvm_Installation_getComponents(env: JNIEnv, object: JObject) -> jobjectArray {
get_installation_components(&env, object)
.unwrap_or_else(jni_utils::print_error_and_return_null)
}
15 changes: 11 additions & 4 deletions jni/src/main/java/net/wooga/uvm/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@
public enum Component {
android(0),
ios(1),
webGl(2),
linux(3),
windows(4),
windowsMono(5);
tvOs(2),
webGl(3),
linux(4),
windows(5),
windowsMono(6),
Editor(7),
Mono(8),
visualStudio(9),
monoDevelop(10),
standardAssets(11),
documentation(12);

Component(int value) {
this.value = value;
Expand Down
76 changes: 76 additions & 0 deletions jni/src/test/groovy/net/wooga/uvm/InstallationSpec.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package net.wooga.uvm

import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll

import java.nio.file.Files

class InstallationSpec extends Specification {

@Shared
def buildDir

def setup() {
buildDir = new File('build/unityVersionManagerSpec')
buildDir.mkdirs()
}


@Unroll("can call :#method on Installation")
def "installation interface doesn't crash"() {
given: "An Installation object"
def installation = new Installation(null, null)

when:
installation.invokeMethod(method, *arguments)
then:
noExceptionThrown()

where:
method | arguments
"getComponents" | null
}

@Unroll("method :getComponents returns #valueMessage #reason")
def "get components returns list of installed components"() {
given: "install unity with specific components"
def basedir = Files.createTempDirectory(buildDir.toPath(), "installationSpec_getComponents").toFile()
basedir.deleteOnExit()
def destination = new File(basedir, version)
assert !destination.exists()
def installation = UnityVersionManager.installUnityEditor(version, destination, components.toArray() as Component[])
assert destination.exists()

expect:
installation.components == expectedComponents.toArray() as Component[]

cleanup:
destination.deleteDir()

where:
components | expectedComponents | reason
[Component.android, Component.ios] | [Component.android, Component.ios] | "when components are installed"
[] | [] | "when no components are installed"
version = "2017.1.0f1"
valueMessage = components.size() > 0 ? "list of installed components" : "empty list"
}

}

0 comments on commit 65db543

Please sign in to comment.