# How to use

### Overview

The wrapper classes are placed in the `org.apertusvr` package. For each ApertusVR entity type there's a corresponding Java wrapper class. Also there are a wrapper classes for the manager classes (e.g.  `ape::EventManager`, `ape::SceneManager`)and `ape::Event` and there are several supporting classes (e.g. `apeColor`, `apeVector3`). To be able to cast the interfaces, we ha a builder Java interface (`apeBuilder`) too.

### Event connection

Just like using the C++ interface, the user can connect to various events (fired by ApertusVR) from Java code. To do that, we need to implement the `apeEventCallback` function:

```java
class MyEventCallback implements apeEventCallback {
    @Override
    public void onEvent(apeEvent event) {
        // do sth with event
    }
}
```

We also have to create an instance of the `MyEventCallback` class, e.g.

```java
MyEventCallback eventCallback = new MyEventCallback();
```

After instantiation, the connection works simply with the usage of `apeManager`'s `connectEvent(...)` function. E.g., to be able to listen `NODE` events, just type:

```java
apeEventManager.connectEvent(apeEvent.Group.NODE, eventCallback);
```

To get an insight of what actually happens here, let us discuss the details! When the user connects an event, the `apeEventManager` (which is a static class) puts this `eventCallback` into a map:

```java
private static Map<apeEvent.Group, LinkedList<apeEventCallback>> mEventMap
```

The app developer also creates a `FrameCallback`  class, which implements Android's built in `Choreographer.FrameCallback`. Like in the following code block:

```java
class FrameCallback implements Choreographer.FrameCallback {
        @Override
        public void doFrame(long frameTimeNanos) {
            choreographer.postFrameCallback(this);
            
            if (apeSystem.isRunning()) {
                ApertusJNI.processEventDoubleQueue();
            }
        }
    }
```

This will parse all the events fired in the C++ side, during the last frame. The ApertusJNI member function called `processEventDoubleQueue()` is a JNI-function, which calls back to Java with `apeEventManager`'s `fireEvent()` function, which will call the `onEvent(apeEvent)` function of our `apeEventCallback` implementation, if its instance is connected to the event's group (so the implementation object can be found under the `apeEvent.Group.NODE` key in the map).

![](https://4044724383-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LEyKyxZqxfQ560k-THK%2F-MEXB9kxBEvz4YbBfCZc%2F-MEXN73sQQwihBMzTxz9%2FJNI-events.svg?alt=media\&token=93e91603-b8ca-4b3c-8713-156a339f112f)

### Entity wrappers

As it was written before, for each entity class in ApertusVR we have a corresponding Java class. The member functions and the class hierarchies on the Java side are the same, as they are on the C++ side. Therefore the API does not differ much, but there are tiny differences between the two. We will go through everything you need, to use ApertusVR entities from Java.

#### Getting access to entities

In C++, knowing the entity's name, we ask the `ape::ISceneManager` to give us a weak pointer. Then we use the `lock()` function to access it. After calling `lock()`, we can also cast the resulted `shared_ptr` to the proper type (`ape::Entity::Type`), if we know what the entity's type should be.\
When using ApertusVR from Java, we just use the interface's constructor to get access to an entity, then we check with the `isValid()` function, that we can actually lock it in C++.

E.g. assume, that we want to access an `apeFileGeometry` entity we know about, with the name of `"FooBar"`, and our goal is to query its `OwnerID`. The procedure goes something like on the following code example:

```java
String fooBarName = "FooBar";
apeFileGeometry fooBarGeometry = new apeFileGeometry(fooBarName);

if (fooBarGeometry.isValid()) {
    String ownerID = fooBarGeometry.getOwnerID();
}
```

The following figure summarizes the procedure executed in the background:

![](https://4044724383-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LEyKyxZqxfQ560k-THK%2F-MEbPiHYbxzgdMLRzGd4%2F-MEbRleCQjR-y7O8W5lU%2FJNI-pipeline.svg?alt=media\&token=f966280f-5e98-427d-a34e-3930c52d2f94)

This is the way in 90% of the cases. However, what if we don't know already the type of the entity, and only its name is given. In this case, we can use the `apeSceneManager` interface:

```java
String fooBarName = "FooBar";
apeEntity fooBarEntity = apeSceneManager.getEntity(fooBarName);

if (fooBarEntity != null && fooBarEntity.isValid()) {
    apeEntity.Type fooBarType = fooBarEntity.getType();
    
    if (fooBarType == apeEntity.Type.GEOMETRY_FILE) {
        apeFileGeometry fooBarGeometry = new apeFileGeometry(fooBarName);
        // ...
    }
}
```

#### Creating an entity

The next question is, how can we create entities in Java? Easy. Just use the `apeSceneManager` interface!:

```java
String fooBarName = "FooBar";
apeEntity.Type fooBarType = apeEntity.Type.GEOMETRY_FILE;
boolean fooBarIsReplicate = false;
String fooBarOwner = "FooBarOwner";

apeEntity fooBarEntity = apeSceneManager.createEntity(
    fooBarName, fooBarType, fooBarIsReplicate, fooBarOwner);
```

&#x20;Okay, then how do we cast it to our needs? We wanted `apeFileGeometry` interface, not `apeEntity`.\
This is where the `apeBuilder` interface come in! The `apeEntity` abstract class has a member function called `cast`:

```java
public <apeType extends apeEntity> apeType cast(apeBuilder<apeType> builder)
```

Providing a proper builder class (which implements the `apeBuilder` interface), we can cast our `apeEntity` to any given type extended from it. In the example, we just type:

```java
apeFileGeometry fooBarGeometry =  Objects.requireNonNull(
        apeSceneManager.createEntity(
            fooBarName,
            fooBarType,
            fooBarIsReplicate,
            fooBarOwner))
            .cast(new apeFileGeometry.FileGeometryBuilder());
```

Or an alternative way is to instance an other `apeFileGeometry` entity  with the `apeEntity`'s name you got from `apeSceneManager` (like you saw it in the former sub-subsection).

#### Deleting entities

Deleting an entity in Java is the same as in C++, an example is presented below:

```java
String entityName = "FooBar";
apeSceneManager.deleteEntity(entityName);
```
