Simple Events working
This commit is contained in:
parent
e0407d9f5f
commit
02473d1fb1
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class Event {
|
||||||
|
private:
|
||||||
|
std::string name; //name of the event
|
||||||
|
jobject input; //original Event object (type CppEvent)
|
||||||
|
std::map<std::string, void*> data;
|
||||||
|
public:
|
||||||
|
jobject getMap(JNIEnv* env);
|
||||||
|
const std::string& getName() const;
|
||||||
|
void* getData(JNIEnv* env, const std::string& name);
|
||||||
|
void setData(const std::string& name, void* data);
|
||||||
|
|
||||||
|
void reapply(JNIEnv* env, jobject jevent);
|
||||||
|
|
||||||
|
Event(JNIEnv* env, jobject jevent);
|
||||||
|
//virtual ~Event();
|
||||||
|
};
|
|
@ -1,23 +1,50 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
#include <map>
|
#define DEBUG 1
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "plugin.h"
|
#ifdef DEBUG
|
||||||
|
#define DEB(A) std::cout << A << std::endl
|
||||||
|
#else
|
||||||
|
#define DEB(A) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
//extern "C" {
|
extern jclass CPPPLUGINCLASS;
|
||||||
|
extern jclass EVENTCLASS;
|
||||||
|
extern jclass MAPCLASS;
|
||||||
|
extern jclass LISTENERCLASS;
|
||||||
|
extern jfieldID EVENTDATAF;
|
||||||
|
extern jfieldID EVENTNAMEF;
|
||||||
|
extern jmethodID MAPGET;
|
||||||
|
extern jmethodID MAPPUT;
|
||||||
|
extern jmethodID LISTENERCONTR;
|
||||||
|
extern jmethodID LISTENERSMALLCONTR;
|
||||||
|
|
||||||
jclass CPPPLUGINCLASS;
|
void load(JNIEnv* env, long data);
|
||||||
jclass EVENTCLASS;
|
|
||||||
jclass MAPCLASS;
|
|
||||||
jclass LISTENERCLASS;
|
|
||||||
jfieldID EVENTDATAF;
|
|
||||||
jfieldID EVENTNAMEF;
|
|
||||||
jmethodID MAPGET;
|
|
||||||
jmethodID MAPPUT;
|
|
||||||
jmethodID LISTENERCONTR;
|
|
||||||
|
|
||||||
CppPlugin* plugin; //what happens, with more than one plugin?
|
enum JNIDATA : long {
|
||||||
|
JNI_PLUGINCLASS = 1,
|
||||||
|
JNI_EVENTCLASS = 2,
|
||||||
|
JNI_MAPCLASS = 4,
|
||||||
|
JNI_LISTENERCLASS = 8,
|
||||||
|
JNI_EVENTDATAFIELD = 16 | JNI_EVENTCLASS,
|
||||||
|
JNI_EVENTNAMEFIELD = 32 | JNI_EVENTCLASS,
|
||||||
|
JNI_MAPGETMETH = 64 | JNI_MAPCLASS,
|
||||||
|
JNI_MAPPUTMETH = 128 | JNI_MAPCLASS,
|
||||||
|
JNI_LISTENERCONSTR = 256 | JNI_LISTENERCLASS,
|
||||||
|
JNI_LISTENERSMALLCONSTR = 512 | JNI_LISTENERCLASS,
|
||||||
|
|
||||||
//} //extern "C"
|
JNI_EVENT = JNI_EVENTCLASS | JNI_EVENTDATAFIELD | JNI_EVENTNAMEFIELD,
|
||||||
|
JNI_MAP = JNI_MAPCLASS | JNI_MAPGETMETH | JNI_MAPPUTMETH,
|
||||||
|
JNI_LISTENER = JNI_LISTENERCLASS | JNI_LISTENERCONSTR | JNI_LISTENERSMALLCONSTR,
|
||||||
|
|
||||||
|
JNI_ALL = 0xFFFF
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
long operator|(JNIDATA a, JNIDATA b);
|
||||||
|
long operator|(long a, JNIDATA b);
|
||||||
|
long operator&(long a, JNIDATA b);*/
|
||||||
|
|
||||||
|
class CppPlugin;
|
||||||
|
extern CppPlugin* plugin; //what happens, with more than one plugin?
|
||||||
|
|
39
inc/plugin.h
39
inc/plugin.h
|
@ -4,34 +4,23 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class CppPlugin {
|
#include "event.h"
|
||||||
public:
|
|
||||||
void* handle;
|
|
||||||
virtual void onLoad() = 0;
|
|
||||||
virtual void onEnable() = 0;
|
|
||||||
virtual void onDisable() = 0;
|
|
||||||
//virtual ~CppPlugin();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Event {
|
//fwd declr
|
||||||
private:
|
class CppPlugin;
|
||||||
std::string name; //name of the event
|
|
||||||
jobject input; //original Event object (type CppEvent)
|
|
||||||
std::map<std::string, void*> data;
|
|
||||||
public:
|
|
||||||
jobject getMap(JNIEnv* env);
|
|
||||||
const std::string& getName();
|
|
||||||
void* getData(JNIEnv* env, const std::string& name);
|
|
||||||
void setData(const std::string& name, void* data);
|
|
||||||
|
|
||||||
void reapply(JNIEnv* env, jobject jevent);
|
|
||||||
|
|
||||||
Event(JNIEnv* env, jobject jevent);
|
|
||||||
//virtual ~Event();
|
|
||||||
};
|
|
||||||
|
|
||||||
//function pointer
|
//function pointer
|
||||||
typedef void (*eventfptr)(CppPlugin*, Event*);
|
typedef void (*eventfptr)(CppPlugin*, Event*);
|
||||||
typedef std::map<std::string, eventfptr> (*getEventsfptr)();
|
|
||||||
typedef CppPlugin* (*initfptr)();
|
typedef CppPlugin* (*initfptr)();
|
||||||
|
|
||||||
|
class CppPlugin {
|
||||||
|
public:
|
||||||
|
void* handle;
|
||||||
|
virtual void onLoad();
|
||||||
|
virtual void onEnable();
|
||||||
|
virtual void onDisable();
|
||||||
|
virtual std::map<std::string, eventfptr> getEvents();
|
||||||
|
virtual ~CppPlugin();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
9
pom.xml
9
pom.xml
|
@ -68,15 +68,6 @@
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--This adds the Bukkit API artifact to the build -->
|
|
||||||
<!-- Do not include this in the pom.xml file if the Spigot API is already added -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bukkit</groupId>
|
|
||||||
<artifactId>bukkit</artifactId>
|
|
||||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
|
|
17
runall.sh
17
runall.sh
|
@ -1,9 +1,24 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
#build java
|
||||||
mvn package
|
mvn package
|
||||||
|
if [ "$?" -ne "0" ]; then
|
||||||
|
echo "Error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#build cpp
|
||||||
rm target/*.so
|
rm target/*.so
|
||||||
make -j1 all #that makefile is not paralllizable
|
make -j1 all #that makefile is not paralllizable
|
||||||
|
if [ "$?" -ne "0" ]; then
|
||||||
|
echo "Error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#prepare server
|
||||||
mkdir -p testserver/plugins/CppPlugins
|
mkdir -p testserver/plugins/CppPlugins
|
||||||
cp target/Cppplugin-0.1-SNAPSHOT-final.jar testserver/plugins/
|
cp target/Cppplugin-0.1-SNAPSHOT-final.jar testserver/plugins/
|
||||||
cp target/libplugin.so testserver/plugins/CppPlugins
|
cp target/libplugin.so testserver/plugins/CppPlugins
|
||||||
|
|
||||||
|
#start server
|
||||||
cd testserver
|
cd testserver
|
||||||
java -jar spigot-1.12.2.jar
|
java -verbose:jni -jar spigot-1.12.2.jar
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include "event.h"
|
||||||
|
#include "libplugin.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
jobject Event::getMap(JNIEnv* env) {
|
||||||
|
return env->GetObjectField(input, EVENTDATAF);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Event::getName() const {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Event::getData(JNIEnv* env, const std::string& name) {
|
||||||
|
std::cout << "Try to access " << name << std::endl;
|
||||||
|
//search in map
|
||||||
|
auto it = data.find(name);
|
||||||
|
if(it == data.end()) {
|
||||||
|
//search in original object
|
||||||
|
//construct string
|
||||||
|
jstring term = env->NewStringUTF(name.c_str());
|
||||||
|
|
||||||
|
//call data.get()
|
||||||
|
jobject map = getMap(env);
|
||||||
|
jobject content = env->CallObjectMethod(map, MAPGET, term);
|
||||||
|
|
||||||
|
//data.insert for next time
|
||||||
|
data.insert({name, content});
|
||||||
|
|
||||||
|
//delete string
|
||||||
|
env->DeleteLocalRef(term);
|
||||||
|
} else {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::setData(const std::string& name, void* d) {
|
||||||
|
//just put it in the map
|
||||||
|
data.insert({name, d});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::reapply(JNIEnv* env, jobject jevent) {
|
||||||
|
jobject map = getMap(env);
|
||||||
|
for(auto it : data) {
|
||||||
|
std::cout << "write back to java: " << it.first << std::endl;
|
||||||
|
jstring key = env->NewStringUTF(it.first.c_str());
|
||||||
|
|
||||||
|
env->CallObjectMethod(map, MAPPUT, key, it.second);
|
||||||
|
env->DeleteLocalRef(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Event::Event(JNIEnv* env, jobject jevent) {
|
||||||
|
//get name
|
||||||
|
jstring name = (jstring) env->GetObjectField(jevent, EVENTNAMEF);
|
||||||
|
this->name = std::string(env->GetStringUTFChars(name, 0));
|
||||||
|
input = jevent;
|
||||||
|
}
|
|
@ -4,28 +4,97 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <dlfcn.h> //dynamic linking
|
#include <dlfcn.h> //dynamic linking
|
||||||
|
|
||||||
#include <libplugin.h>
|
#include <thread> //thread id
|
||||||
|
|
||||||
|
#include "libplugin.h"
|
||||||
|
#include "plugin.h"
|
||||||
|
|
||||||
|
jclass CPPPLUGINCLASS;
|
||||||
|
jclass EVENTCLASS;
|
||||||
|
jclass MAPCLASS;
|
||||||
|
jclass LISTENERCLASS;
|
||||||
|
jfieldID EVENTDATAF;
|
||||||
|
jfieldID EVENTNAMEF;
|
||||||
|
jmethodID MAPGET;
|
||||||
|
jmethodID MAPPUT;
|
||||||
|
jmethodID LISTENERCONTR;
|
||||||
|
jmethodID LISTENERSMALLCONTR;
|
||||||
|
|
||||||
|
CppPlugin* plugin; //what happens, with more than one plugin?
|
||||||
|
|
||||||
|
/*
|
||||||
|
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||||
|
DEB("onload" );
|
||||||
|
JNIEnv* env;
|
||||||
|
vm->GetEnv((void**) &env, JNI_VERSION_1_8);
|
||||||
|
|
||||||
|
|
||||||
|
return JNI_VERSION_1_8;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void fixcap(JNIEnv* env) {
|
||||||
|
DEB("ensure 1024" );
|
||||||
|
env->EnsureLocalCapacity(1024);
|
||||||
|
|
||||||
|
DEB("push frame 1024" );
|
||||||
|
env->PushLocalFrame(1024);
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
operator long()(JNIDATA d) {
|
||||||
|
return (long) d;
|
||||||
|
}
|
||||||
|
|
||||||
|
long operator|(JNIDATA a, JNIDATA b) {
|
||||||
|
return (long) a | (long) b;
|
||||||
|
}
|
||||||
|
|
||||||
|
long operator|(long a, JNIDATA b) {
|
||||||
|
return a | (long) b;
|
||||||
|
}
|
||||||
|
|
||||||
|
long operator&(long a, JNIDATA b) {
|
||||||
|
return a & (long) b;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void load(JNIEnv* env, long data) {
|
||||||
|
|
||||||
|
DEB("loading with mask: " << data);
|
||||||
|
|
||||||
|
|
||||||
|
if(data & JNI_PLUGINCLASS)
|
||||||
|
CPPPLUGINCLASS = env->FindClass("de/mrbesen/cppplugins/CppPlugin");
|
||||||
|
if(data & JNI_EVENTCLASS)
|
||||||
|
EVENTCLASS = env->FindClass("de/mrbesen/cppplugins/CppEvent");
|
||||||
|
if(data & JNI_MAPCLASS)
|
||||||
|
MAPCLASS = env->FindClass("java/util/Map");
|
||||||
|
if(data & JNI_LISTENERCLASS)
|
||||||
|
LISTENERCLASS = env->FindClass("de/mrbesen/cppplugins/CppPlugin$CppListener");
|
||||||
|
|
||||||
|
DEB("find classes: " << (!!CPPPLUGINCLASS) << (!!EVENTCLASS) << (!!MAPCLASS) << (!!LISTENERCLASS));
|
||||||
|
|
||||||
|
if(data & JNI_EVENTDATAFIELD)
|
||||||
|
EVENTDATAF = env->GetFieldID(EVENTCLASS, "data", "Ljava/util/Map;");
|
||||||
|
if(data & JNI_EVENTNAMEFIELD)
|
||||||
|
EVENTNAMEF = env->GetFieldID(EVENTCLASS, "name", "Ljava/lang/String;");
|
||||||
|
|
||||||
|
DEB("findfields: " << (!!EVENTDATAF) << (!!EVENTNAMEF));
|
||||||
|
|
||||||
|
if(data & JNI_MAPGETMETH)
|
||||||
|
MAPGET = env->GetMethodID(MAPCLASS, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
|
if(data & JNI_MAPPUTMETH)
|
||||||
|
MAPPUT = env->GetMethodID(MAPCLASS, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
|
if(data & JNI_LISTENERCONSTR)
|
||||||
|
LISTENERCONTR = env->GetMethodID(LISTENERCLASS, "<init>", "(Ljava/lang/String;J)V");
|
||||||
|
if(data & JNI_LISTENERSMALLCONSTR)
|
||||||
|
LISTENERSMALLCONTR = env->GetMethodID(LISTENERCLASS, "<init>", "()V");
|
||||||
|
|
||||||
|
DEB("find methods: " << (!!MAPGET) << (!!MAPPUT) << (!!LISTENERCONTR) << (!!LISTENERSMALLCONTR));
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_init_1(JNIEnv* env, jobject thisobj) {
|
JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_init_1(JNIEnv* env, jobject thisobj) {
|
||||||
std::cout << "init libplugin loading java references, 1 = good, 0 = bad" << std::endl;
|
load(env, JNI_ALL);
|
||||||
|
return true;
|
||||||
CPPPLUGINCLASS = env->FindClass("de/mrbesen/cppplugins/CppPlugin");
|
|
||||||
EVENTCLASS = env->FindClass("de/mrbesen/cppplugins/CppEvent");
|
|
||||||
MAPCLASS = env->FindClass("java/util/Map");
|
|
||||||
LISTENERCLASS = env->FindClass("de/mrbesen/cppplugins/CppPlugin$CppListener");
|
|
||||||
std::cout << "find classes: " << (!!CPPPLUGINCLASS) << (!!EVENTCLASS) << (!!MAPCLASS) << (!!LISTENERCLASS) << std::endl;
|
|
||||||
|
|
||||||
EVENTDATAF = env->GetFieldID(EVENTCLASS, "data", "Ljava/util/Map;");
|
|
||||||
EVENTNAMEF = env->GetFieldID(EVENTCLASS, "name", "Ljava/lang/String;");
|
|
||||||
std::cout << "findfields: " << (!!EVENTDATAF) << (!!EVENTNAMEF) << std::endl;
|
|
||||||
|
|
||||||
MAPGET = env->GetMethodID(MAPCLASS, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
|
||||||
MAPPUT = env->GetMethodID(MAPCLASS, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
|
||||||
LISTENERCONTR = env->GetMethodID(LISTENERCLASS, "<init>", "(Ljava/lang/String;J)V");
|
|
||||||
std::cout << "find methods: " << (!!MAPGET) << (!!MAPPUT) << (!!LISTENERCONTR) << std::endl;
|
|
||||||
|
|
||||||
return ((!CPPPLUGINCLASS) + (!EVENTCLASS) + (!MAPCLASS) + (!EVENTDATAF) + (!EVENTNAMEF) + (!MAPGET) + (!MAPPUT) + (!LISTENERCONTR)) == 0; //one nullptr -> inverted to 1 -> ends up at end -> false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +107,7 @@ JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_loadPlugin(JNIEn
|
||||||
const char* cpath = env->GetStringUTFChars(path, 0);
|
const char* cpath = env->GetStringUTFChars(path, 0);
|
||||||
|
|
||||||
//open plugin
|
//open plugin
|
||||||
std::cout << "open plugin " << cpath << std::endl;
|
DEB("open plugin " << cpath );
|
||||||
void* handle = dlopen(cpath, RTLD_LAZY);
|
void* handle = dlopen(cpath, RTLD_LAZY);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
std::cout << "could not create handle of: " << cpath << " error: " << dlerror() << std::endl;
|
std::cout << "could not create handle of: " << cpath << " error: " << dlerror() << std::endl;
|
||||||
|
@ -59,7 +128,7 @@ JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_loadPlugin(JNIEn
|
||||||
|
|
||||||
//store data
|
//store data
|
||||||
//setData(data, env, thisobj);
|
//setData(data, env, thisobj);
|
||||||
std::cout << "plugin: " << (bool)plugin << std::endl;
|
DEB("plugin: " << (bool)plugin);
|
||||||
return (bool) plugin; // converted to boolean here
|
return (bool) plugin; // converted to boolean here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +139,7 @@ JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_loadPlugin(JNIEn
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onLoad(JNIEnv* env, jobject thisobj) {
|
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onLoad(JNIEnv* env, jobject thisobj) {
|
||||||
//TODO
|
//TODO
|
||||||
std::cout << "lib::onLoad()" << std::endl;
|
DEB("lib::onLoad()");
|
||||||
plugin->onLoad();
|
plugin->onLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +150,7 @@ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onLoad(JNIEnv* env,
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onEnable_1(JNIEnv* env, jobject thisobj) {
|
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onEnable_1(JNIEnv* env, jobject thisobj) {
|
||||||
//TODO
|
//TODO
|
||||||
std::cout << "lib::onEnable()" << std::endl;
|
DEB("lib::onEnable()");
|
||||||
plugin->onEnable();
|
plugin->onEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +161,7 @@ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onEnable_1(JNIEnv* e
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onDisable_1(JNIEnv* env, jobject thisobj) {
|
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onDisable_1(JNIEnv* env, jobject thisobj) {
|
||||||
//TODO
|
//TODO
|
||||||
std::cout << "lib::onDisable()" << std::endl;
|
DEB("lib::onDisable()" );
|
||||||
plugin->onDisable();
|
plugin->onDisable();
|
||||||
dlclose(plugin->handle);
|
dlclose(plugin->handle);
|
||||||
}
|
}
|
||||||
|
@ -103,14 +172,16 @@ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onDisable_1(JNIEnv*
|
||||||
* Signature: (Lde/mrbesen/cppplugins/CppEvent;I)Lde/mrbesen/cppplugins/CppEvent;
|
* Signature: (Lde/mrbesen/cppplugins/CppEvent;I)Lde/mrbesen/cppplugins/CppEvent;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jobject JNICALL Java_de_mrbesen_cppplugins_CppPlugin_fireEvent(JNIEnv* env, jobject thisobj, jobject jevent, jlong functionid) {
|
JNIEXPORT jobject JNICALL Java_de_mrbesen_cppplugins_CppPlugin_fireEvent(JNIEnv* env, jobject thisobj, jobject jevent, jlong functionid) {
|
||||||
std::cout << "lib::fireEvent()" << std::endl;
|
DEB("lib::fireEvent()" );
|
||||||
if(functionid == 0) {
|
if(functionid == 0) {
|
||||||
std::cout << "invalid function id" << std::endl;
|
DEB("invalid function id");
|
||||||
return jevent;
|
return jevent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
load(env, JNI_EVENT | JNI_MAP);
|
||||||
|
|
||||||
//cast function
|
//cast function
|
||||||
eventfptr f = reinterpret_cast<eventfptr>(functionid);
|
eventfptr f = reinterpret_cast<eventfptr>(functionid);
|
||||||
|
|
||||||
//cast event
|
//cast event
|
||||||
Event event(env, jevent);
|
Event event(env, jevent);
|
||||||
|
@ -140,18 +211,17 @@ JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onCmd(JNIEnv* en
|
||||||
* Signature: ()[Lde/mrbesen/cppplugins/CppPlugin/CppListener;
|
* Signature: ()[Lde/mrbesen/cppplugins/CppPlugin/CppListener;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jobjectArray JNICALL Java_de_mrbesen_cppplugins_CppPlugin_getListener(JNIEnv* env, jobject thisobj) {
|
JNIEXPORT jobjectArray JNICALL Java_de_mrbesen_cppplugins_CppPlugin_getListener(JNIEnv* env, jobject thisobj) {
|
||||||
|
load(env, JNI_LISTENER);
|
||||||
|
|
||||||
//call getEvents
|
//call getEvents
|
||||||
std::map<std::string, eventfptr> events;
|
std::map<std::string, eventfptr> events = plugin->getEvents();
|
||||||
getEventsfptr getEventsf = (getEventsfptr) dlsym(plugin->handle, "getEvents");
|
DEB("found " << events.size() << " Events");
|
||||||
if(getEventsf) {
|
|
||||||
//only non null
|
|
||||||
events = getEventsf();
|
|
||||||
}
|
|
||||||
|
|
||||||
//create array
|
//create array
|
||||||
jclass clas = env->FindClass("de/mrbesen/cppplugins/CppPlugin/CppListener");
|
jobject initial = env->NewObject(LISTENERCLASS, LISTENERSMALLCONTR);
|
||||||
jobjectArray arr = env->NewObjectArray(events.size(), clas, 0);
|
jobjectArray arr = env->NewObjectArray(events.size(), LISTENERCLASS, initial);
|
||||||
|
|
||||||
|
DEB("populate array");
|
||||||
//populate array
|
//populate array
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(auto it : events) {
|
for(auto it : events) {
|
||||||
|
@ -164,66 +234,8 @@ JNIEXPORT jobjectArray JNICALL Java_de_mrbesen_cppplugins_CppPlugin_getListener(
|
||||||
env->SetObjectArrayElement(arr, i++, listener);
|
env->SetObjectArrayElement(arr, i++, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEB("Array finished");
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////// EVENTS
|
|
||||||
|
|
||||||
jobject Event::getMap(JNIEnv* env) {
|
|
||||||
return env->GetObjectField(input, EVENTDATAF);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& Event::getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* Event::getData(JNIEnv* env, const std::string& name) {
|
|
||||||
std::cout << "Try to access " << name << std::endl;
|
|
||||||
//search in map
|
|
||||||
auto it = data.find(name);
|
|
||||||
if(it == data.end()) {
|
|
||||||
//search in original object
|
|
||||||
//construct string
|
|
||||||
jstring term = env->NewStringUTF(name.c_str());
|
|
||||||
|
|
||||||
//call data.get()
|
|
||||||
jobject map = getMap(env);
|
|
||||||
jobject content = env->CallObjectMethod(map, MAPGET, term);
|
|
||||||
|
|
||||||
//data.insert for next time
|
|
||||||
data.insert({name, content});
|
|
||||||
|
|
||||||
//delete string
|
|
||||||
env->DeleteLocalRef(term);
|
|
||||||
} else {
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::setData(const std::string& name, void* d) {
|
|
||||||
//just put it in the map
|
|
||||||
data.insert({name, d});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::reapply(JNIEnv* env, jobject jevent) {
|
|
||||||
jobject map = getMap(env);
|
|
||||||
for(auto it : data) {
|
|
||||||
std::cout << "write back to java: " << it.first << std::endl;
|
|
||||||
jstring key = env->NewStringUTF(it.first.c_str());
|
|
||||||
|
|
||||||
env->CallObjectMethod(map, MAPPUT, key, it.second);
|
|
||||||
env->DeleteLocalRef(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Event::Event(JNIEnv* env, jobject jevent) {
|
|
||||||
//get name
|
|
||||||
jstring name = (jstring) env->GetObjectField(jevent, EVENTNAMEF);
|
|
||||||
this->name = std::string(env->GetStringUTFChars(name, 0));
|
|
||||||
input = jevent;
|
|
||||||
}
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <plugin.h>
|
||||||
|
|
||||||
|
void CppPlugin::onLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppPlugin::onEnable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppPlugin::onDisable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, eventfptr> CppPlugin::getEvents() {
|
||||||
|
return std::map<std::string, eventfptr>();
|
||||||
|
}
|
||||||
|
|
||||||
|
CppPlugin::~CppPlugin() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package de.mrbesen.cppplugins;
|
package de.mrbesen.cppplugins;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ import java.util.Map;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CppEvent {
|
public class CppEvent {
|
||||||
|
@Getter
|
||||||
private final String name;
|
private final String name;
|
||||||
Map<String, Object> data = new HashMap<>();
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
package de.mrbesen.cppplugins;
|
package de.mrbesen.cppplugins;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.event.*;
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.EventException;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.plugin.*;
|
import org.bukkit.plugin.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class CppLoader implements PluginLoader {
|
public class CppLoader implements PluginLoader {
|
||||||
|
@ -54,17 +59,28 @@ public class CppLoader implements PluginLoader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Class<? extends Event>, Set<RegisteredListener>> createRegisteredListeners(Listener listenerabcdeg, Plugin plugin) {
|
public Map<Class<? extends Event>, Set<RegisteredListener>> createRegisteredListeners(Listener listenerabcdeg, Plugin plugin) {
|
||||||
|
System.out.println("register Listener for: " + plugin.getName());
|
||||||
CppPlugin.CppListener[] listener = ((CppPlugin) plugin).getListener();
|
CppPlugin.CppListener[] listener = ((CppPlugin) plugin).getListener();
|
||||||
Map<Class<? extends Event>, Set<RegisteredListener>> out = new HashMap<>();
|
Map<Class<? extends Event>, Set<RegisteredListener>> out = new HashMap<>();
|
||||||
Package bukkitevents = Package.getPackage("org.bukkit.event");
|
|
||||||
|
System.out.println("found " + listener.length + " Events");
|
||||||
|
|
||||||
for(CppPlugin.CppListener lis : listener) {
|
for(CppPlugin.CppListener lis : listener) {
|
||||||
|
if(lis.functionid == 0) continue;
|
||||||
|
|
||||||
//search for Class
|
//search for Class
|
||||||
Class clas = findClass(lis.eventfilter);
|
Class clas = findClass(lis.eventfilter);
|
||||||
|
if(clas == null) {
|
||||||
|
System.out.println("Class " + lis.eventfilter + " is unknown event");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
AdapterExecutor adapt = new AdapterExecutor();
|
System.out.println("register event " + clas.getName() + " for function: " + lis.functionid );
|
||||||
|
|
||||||
Set<RegisteredListener> lisset = out.getOrDefault(clas, new TreeSet<>());
|
AdapterExecutor adapt = new AdapterExecutor((CppPlugin) plugin, lis.functionid);
|
||||||
|
Bukkit.getPluginManager().registerEvent(clas, lis, EventPriority.NORMAL, adapt, plugin, true);
|
||||||
|
|
||||||
|
Set<RegisteredListener> lisset = out.getOrDefault(clas, new HashSet<>());
|
||||||
lisset.add(new RegisteredListener(lis, adapt, EventPriority.NORMAL, plugin, true));
|
lisset.add(new RegisteredListener(lis, adapt, EventPriority.NORMAL, plugin, true));
|
||||||
if(lisset.size() == 1) //nur wenn neu
|
if(lisset.size() == 1) //nur wenn neu
|
||||||
out.put(clas, lisset);
|
out.put(clas, lisset);
|
||||||
|
@ -91,6 +107,7 @@ public class CppLoader implements PluginLoader {
|
||||||
@Override
|
@Override
|
||||||
public void enablePlugin(Plugin plugin) {
|
public void enablePlugin(Plugin plugin) {
|
||||||
plugin.onEnable();
|
plugin.onEnable();
|
||||||
|
createRegisteredListeners(null, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,6 +115,7 @@ public class CppLoader implements PluginLoader {
|
||||||
plugin.onDisable();
|
plugin.onDisable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
private class AdapterExecutor implements EventExecutor {
|
private class AdapterExecutor implements EventExecutor {
|
||||||
CppPlugin plugin;
|
CppPlugin plugin;
|
||||||
long functionid;
|
long functionid;
|
||||||
|
@ -107,6 +125,7 @@ public class CppLoader implements PluginLoader {
|
||||||
//cppify event
|
//cppify event
|
||||||
CppEvent cppe = CppEvent.cppify(event);
|
CppEvent cppe = CppEvent.cppify(event);
|
||||||
|
|
||||||
|
System.out.println("fire event " + cppe.getName() + " in function " + functionid);
|
||||||
cppe = plugin.fireEvent(cppe, functionid);
|
cppe = plugin.fireEvent(cppe, functionid);
|
||||||
|
|
||||||
//uncppify
|
//uncppify
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class CppPlugin implements Plugin {
|
public class CppPlugin implements Plugin {
|
||||||
|
|
||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
@Getter
|
@Getter
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -166,9 +165,18 @@ public class CppPlugin implements Plugin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
static class CppListener implements Listener {
|
static class CppListener implements Listener {
|
||||||
String eventfilter;
|
String eventfilter;
|
||||||
long functionid;
|
long functionid;
|
||||||
|
|
||||||
|
public CppListener(String eventfilter, long functionid) {
|
||||||
|
this.eventfilter = eventfilter;
|
||||||
|
this.functionid = functionid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CppListener() {
|
||||||
|
this.eventfilter = "NOP";
|
||||||
|
functionid = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.util.logging.Level;
|
||||||
|
|
||||||
public class CppPlugins extends JavaPlugin {
|
public class CppPlugins extends JavaPlugin {
|
||||||
|
|
||||||
|
public static String testplugin = "simpleevents.so";
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static CppPlugins instance;
|
private static CppPlugins instance;
|
||||||
|
|
||||||
|
@ -23,12 +25,12 @@ public class CppPlugins extends JavaPlugin {
|
||||||
getLogger().info("registered");
|
getLogger().info("registered");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Bukkit.getPluginManager().loadPlugin(new File("plugins/verysimpleplugin.so")); //TODO: do loading in another way
|
Bukkit.getPluginManager().loadPlugin(new File("plugins/" + testplugin)); //TODO: do loading in another way
|
||||||
System.out.println("loaded verysimpleplugin.so");
|
System.out.println("loaded " + testplugin);
|
||||||
|
|
||||||
//TODO: trigger onLoad in those Plugins
|
//TODO: trigger onLoad in those Plugins
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
getLogger().log(Level.SEVERE, "Error ocoured during loading verysimpleplugin.so", e);
|
getLogger().log(Level.SEVERE, "Error ocoured during loading " + testplugin, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
CFLAGS = -Wall -pedantic-errors -std=c++17 -g
|
||||||
|
SRCDIR = src/
|
||||||
|
INCDIR = ../../inc
|
||||||
|
LDFLAGS = -I/usr/lib/jvm/java-8-openjdk-amd64/include/ -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -I$(INCDIR) -I../../src/main/cpp/inc
|
||||||
|
NAME = simpleevents.so
|
||||||
|
|
||||||
|
all:
|
||||||
|
g++ -fPIC -shared $(CFLAGS) $(SRCDIR)*.cpp ../../src/main/cpp/src/plugin.cpp $(LDFLAGS) -o $(NAME) /home/yannis/git/Cppplugin/testserver/plugins/CppPlugins/libplugin.so
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "plugin.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void eventJoin(CppPlugin* pl, Event* e) {
|
||||||
|
std::cout << "join " << e->getName() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void eventQuit(CppPlugin* pl, Event* e) {
|
||||||
|
std::cout << "quit " << e->getName() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyPlugin : public CppPlugin {
|
||||||
|
public:
|
||||||
|
virtual void onLoad();
|
||||||
|
virtual void onEnable();
|
||||||
|
virtual void onDisable();
|
||||||
|
virtual std::map<std::string, eventfptr> getEvents();
|
||||||
|
};
|
||||||
|
|
||||||
|
void MyPlugin::onLoad() {
|
||||||
|
std::cout << "onload();" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyPlugin::onEnable() {
|
||||||
|
std::cout << "onEnable();" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyPlugin::onDisable() {
|
||||||
|
std::cout << "onDisable();" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
CppPlugin* init() {
|
||||||
|
std::cout << "init im plugin!" << std::endl;
|
||||||
|
return new MyPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, eventfptr> MyPlugin::getEvents() {
|
||||||
|
std::cout << "MyPlugin::getEvents" << std::endl;
|
||||||
|
std::map<std::string, eventfptr> out;
|
||||||
|
out.insert({"PlayerJoinEvent", eventJoin});
|
||||||
|
out.insert({"PlayerQuitEvent", eventQuit});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
std::map<std::string, eventfptr> MyPlugin::getEvents() {
|
||||||
|
return std::map<std::string, eventfptr>();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}//extern "C"
|
|
@ -6,4 +6,4 @@ LDFLAGS = -I/usr/lib/jvm/java-8-openjdk-amd64/include/ -I/usr/lib/jvm/java-8-op
|
||||||
NAME = verysimpleplugin.so
|
NAME = verysimpleplugin.so
|
||||||
|
|
||||||
all:
|
all:
|
||||||
g++ -fPIC -shared $(CFLAGS) $(SRCDIR)*.cpp $(LDFLAGS) ../../src/main/cpp/src/libplugin.cpp -o $(NAME)
|
g++ -fPIC -shared $(CFLAGS) $(SRCDIR)*.cpp ../../src/main/cpp/src/plugin.cpp $(LDFLAGS) -o $(NAME)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
@ -9,6 +11,7 @@ public:
|
||||||
virtual void onLoad();
|
virtual void onLoad();
|
||||||
virtual void onEnable();
|
virtual void onEnable();
|
||||||
virtual void onDisable();
|
virtual void onDisable();
|
||||||
|
//virtual std::map<std::string, eventfptr> getEvents();
|
||||||
};
|
};
|
||||||
|
|
||||||
void MyPlugin::onLoad() {
|
void MyPlugin::onLoad() {
|
||||||
|
@ -28,8 +31,4 @@ CppPlugin* init() {
|
||||||
return new MyPlugin();
|
return new MyPlugin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventJoin(CppPlugin* pl, Event* e) {
|
|
||||||
std::cout << "join " << e->getName() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}//extern "C"
|
}//extern "C"
|
Loading…
Reference in New Issue