Skip to content

Commit

Permalink
feat: Create Choreographer
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Feb 23, 2024
1 parent 83c4c08 commit a69b7fe
Show file tree
Hide file tree
Showing 15 changed files with 211 additions and 10 deletions.
2 changes: 2 additions & 0 deletions package/android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ add_library(
../cpp/FilamentProxy.cpp
../cpp/Surface.cpp
../cpp/SurfaceProvider.cpp
../cpp/Choreographer.cpp
../cpp/Listener.cpp
../cpp/jsi/HybridObject.cpp
../cpp/jsi/Promise.cpp
Expand All @@ -34,6 +35,7 @@ add_library(
src/main/cpp/JNISharedPtr.cpp
src/main/cpp/FilamentInstaller.cpp
src/main/cpp/java-bindings/JFilamentProxy.cpp
src/main/cpp/java-bindings/JChoreographer.cpp
src/main/cpp/java-bindings/JFilamentView.cpp
src/main/cpp/java-bindings/JSurfaceProvider.cpp
)
Expand Down
4 changes: 4 additions & 0 deletions package/android/src/main/cpp/AndroidFilamentProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ std::shared_ptr<FilamentView> AndroidFilamentProxy::findFilamentView(int id) {
return _proxy->cthis()->findFilamentView(id);
}

std::shared_ptr<Choreographer> AndroidFilamentProxy::createChoreographer() {
return _proxy->cthis()->createChoreographer();
}

} // namespace margelo
1 change: 1 addition & 0 deletions package/android/src/main/cpp/AndroidFilamentProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class AndroidFilamentProxy : public FilamentProxy {
// TODO(hanno): implement
int loadModel(std::string path) override;
std::shared_ptr<FilamentView> findFilamentView(int id) override;
std::shared_ptr<Choreographer> createChoreographer() override;

private:
jni::global_ref<JFilamentProxy::javaobject> _proxy;
Expand Down
39 changes: 39 additions & 0 deletions package/android/src/main/cpp/java-bindings/JChoreographer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Created by Marc Rousavy on 23.02.24.
//

#include "JChoreographer.h"
#include <android/choreographer.h>

namespace margelo {

void JChoreographer::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", JChoreographer::initHybrid),
makeNativeMethod("start", JChoreographer::start),
makeNativeMethod("stop", JChoreographer::stop),
makeNativeMethod("onFrame", JChoreographer::onFrameLong),
});
}

JChoreographer::JChoreographer(const jni::alias_ref<jhybridobject>& javaThis) : _javaPart(jni::make_global(javaThis)) {}

jni::local_ref<JChoreographer::jhybriddata> JChoreographer::initHybrid(jni::alias_ref<jhybridobject> javaThis) {
return makeCxxInstance(javaThis);
}

void JChoreographer::onFrameLong(jlong timestamp) {
onFrame(static_cast<double>(timestamp));
}

void JChoreographer::start() {
static const auto method = javaClassLocal()->getMethod<void()>("start");
method(_javaPart);
}

void JChoreographer::stop() {
static const auto method = javaClassLocal()->getMethod<void()>("stop");
method(_javaPart);
}

} // namespace margelo
33 changes: 33 additions & 0 deletions package/android/src/main/cpp/java-bindings/JChoreographer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Created by Marc Rousavy on 23.02.24.
//

#pragma once

#include "Choreographer.h"
#include <fbjni/fbjni.h>

namespace margelo {

using namespace facebook;

class JChoreographer : public jni::HybridClass<JChoreographer>, public Choreographer {
public:
static void registerNatives();

void start() override;
void stop() override;
void onFrameLong(jlong timestamp);

private:
friend HybridBase;
jni::global_ref<JChoreographer::javaobject> _javaPart;
static auto constexpr TAG = "JChoreographer";
static auto constexpr kJavaDescriptor = "Lcom/margelo/filament/FilamentChoreographer;";

private:
explicit JChoreographer(const jni::alias_ref<jhybridobject>& javaThis);
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaThis);
};

} // namespace margelo
9 changes: 9 additions & 0 deletions package/android/src/main/cpp/java-bindings/JFilamentProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//

#include "JFilamentProxy.h"
#include "JChoreographer.h"
#include "JFilamentView.h"
#include "JNISharedPtr.h"
#include <fbjni/fbjni.h>
Expand Down Expand Up @@ -32,6 +33,14 @@ std::shared_ptr<FilamentView> JFilamentProxy::findFilamentView(int id) {
return std::static_pointer_cast<FilamentView>(sharedRef);
}

std::shared_ptr<Choreographer> JFilamentProxy::createChoreographer() {
static const auto method = javaClassLocal()->getMethod<jni::alias_ref<JChoreographer::javaobject>()>("createChoreographer");
jni::local_ref<JChoreographer::javaobject> choreographer = method(_javaPart);
jni::global_ref<JChoreographer::javaobject> globalRef = jni::make_global(choreographer);
std::shared_ptr<JChoreographer> sharedRef = JNISharedPtr::make_shared_from_jni<JChoreographer>(globalRef);
return std::static_pointer_cast<Choreographer>(sharedRef);
}

jsi::Runtime& JFilamentProxy::getRuntime() {
if (_runtime == nullptr) {
[[unlikely]];
Expand Down
2 changes: 2 additions & 0 deletions package/android/src/main/cpp/java-bindings/JFilamentProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include "Choreographer.h"
#include "FilamentView.h"
#include <ReactCommon/CallInvokerHolder.h>
#include <fbjni/fbjni.h>
Expand All @@ -25,6 +26,7 @@ class JFilamentProxy : public jni::HybridClass<JFilamentProxy> {
// TODO(hanno): implement
int loadModel(const std::string& path);
std::shared_ptr<FilamentView> findFilamentView(int id);
std::shared_ptr<Choreographer> createChoreographer();

jsi::Runtime& getRuntime();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.margelo.filament;

import android.view.Choreographer;

import androidx.annotation.Keep;

import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;

/** @noinspection JavaJniMissingFunction*/
public class FilamentChoreographer {
/** @noinspection unused, FieldCanBeLocal */
@DoNotStrip
@Keep
private final HybridData mHybridData;
private final Choreographer choreographer;
private final Choreographer.FrameCallback frameCallback;
private boolean isRunning;

public FilamentChoreographer() {
mHybridData = initHybrid();
choreographer = Choreographer.getInstance();
frameCallback = timestamp -> {
if (!isRunning) return;
onFrame(timestamp);
};
}

private synchronized void start() {
if (!isRunning) {
isRunning = true;
choreographer.postFrameCallback(frameCallback);
}
}

private synchronized void stop() {
if (isRunning) {
isRunning = false;
choreographer.removeFrameCallback(frameCallback);
}
}

private native HybridData initHybrid();
private native void onFrame(long timestamp);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ class FilamentProxy {
reactContext = context;
}

/** @noinspection unused*/
@DoNotStrip
@Keep
FilamentChoreographer createChoreographer() {
return new FilamentChoreographer();
}

/** @noinspection unused*/
@DoNotStrip
@Keep
Expand Down
26 changes: 26 additions & 0 deletions package/cpp/Choreographer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Created by Marc Rousavy on 23.02.24.
//

#include "Choreographer.h"

namespace margelo {

void Choreographer::loadHybridMethods() {
registerHybridMethod("setOnFrameCallback", &Choreographer::addOnFrameListener, this);
}

std::shared_ptr<Listener> Choreographer::addOnFrameListener(Choreographer::OnFrameCallback onFrameCallback) {
_callbacks.push_back(std::move(onFrameCallback));
return std::make_shared<Listener>([]() {
// TODO: Find a safe way to remove this listener from the vector.
});
}

void Choreographer::onFrame(double timestamp) {
for (const auto& callback : _callbacks) {
callback(timestamp);
}
}

} // namespace margelo
31 changes: 31 additions & 0 deletions package/cpp/Choreographer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Created by Marc Rousavy on 23.02.24.
//

#pragma once

#include "Listener.h"
#include "jsi/HybridObject.h"
#include <functional>

namespace margelo {

class Choreographer : public HybridObject {
public:
using OnFrameCallback = std::function<void(double timestamp)>;

std::shared_ptr<Listener> addOnFrameListener(OnFrameCallback onFrameCallback);

virtual void start() = 0;
virtual void stop() = 0;

protected:
void onFrame(double timestamp);

void loadHybridMethods() override;

private:
std::vector<OnFrameCallback> _callbacks;
};

} // namespace margelo
4 changes: 2 additions & 2 deletions package/cpp/FilamentProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

#pragma once

#include <jsi/jsi.h>

#include <string>
#include <vector>

#include "Choreographer.h"
#include "FilamentView.h"
#include "jsi/HybridObject.h"
#include "test/TestHybridObject.h"
Expand All @@ -21,6 +20,7 @@ class FilamentProxy : public HybridObject {
private:
virtual int loadModel(std::string path) = 0;
virtual std::shared_ptr<FilamentView> findFilamentView(int id) = 0;
virtual std::shared_ptr<Choreographer> createChoreographer() = 0;

std::shared_ptr<TestHybridObject> createTestObject();

Expand Down
4 changes: 4 additions & 0 deletions package/cpp/Listener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ void Listener::remove() {
_isRemoved = true;
}

void Listener::loadHybridMethods() {
registerHybridMethod("remove", &Listener::remove, this);
}

} // namespace margelo
5 changes: 4 additions & 1 deletion package/cpp/Listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@

#pragma once

#include "jsi/HybridObject.h"
#include <functional>

namespace margelo {

class Listener {
class Listener : public HybridObject {
public:
explicit Listener(std::function<void()> remove);
~Listener();
void remove();

void loadHybridMethods() override;

private:
std::function<void()> _remove;
bool _isRemoved;
Expand Down
9 changes: 2 additions & 7 deletions package/cpp/SurfaceProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,8 @@ Listener SurfaceProvider::addOnSurfaceChangedListener(margelo::SurfaceProvider::
std::unique_lock lock(_mutex);

_callbacks.push_back(std::move(callback));
size_t index = _callbacks.size();

return Listener([weakThis = this, index]() {
if (weakThis != nullptr) {
std::unique_lock lock(weakThis->_mutex);
weakThis->_callbacks.erase(weakThis->_callbacks.begin() + index);
}
return Listener([]() {
// TODO: Find a safe way to remove this listener from the vector.
});
}

Expand Down

0 comments on commit a69b7fe

Please sign in to comment.