diff --git a/inc/event.h b/inc/event.h index 8a06449..b4f9f37 100644 --- a/inc/event.h +++ b/inc/event.h @@ -10,12 +10,12 @@ private: jobject input; //original Event object (type CppEvent) std::map 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); + virtual jobject getMap(JNIEnv* env); + virtual const std::string& getName() const; + virtual void* getData(JNIEnv* env, const std::string& name); + virtual void setData(const std::string& name, void* data); - void reapply(JNIEnv* env, jobject jevent); + virtual void reapply(JNIEnv* env, jobject jevent); Event(JNIEnv* env, jobject jevent); //virtual ~Event(); diff --git a/inc/libplugin.h b/inc/libplugin.h index 7e0d3ea..eca3ab0 100644 --- a/inc/libplugin.h +++ b/inc/libplugin.h @@ -18,6 +18,7 @@ extern jfieldID EVENTDATAF; extern jfieldID EVENTNAMEF; extern jmethodID MAPGET; extern jmethodID MAPPUT; +extern jmethodID MAPCLEAR; extern jmethodID LISTENERCONTR; extern jmethodID LISTENERSMALLCONTR; @@ -32,8 +33,9 @@ enum JNIDATA : long { 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, + JNI_MAPCLEARMETH = 256 | JNI_MAPCLASS, + JNI_LISTENERCONSTR = 512 | JNI_LISTENERCLASS, + JNI_LISTENERSMALLCONSTR = 1024 | JNI_LISTENERCLASS, JNI_EVENT = JNI_EVENTCLASS | JNI_EVENTDATAFIELD | JNI_EVENTNAMEFIELD, JNI_MAP = JNI_MAPCLASS | JNI_MAPGETMETH | JNI_MAPPUTMETH, diff --git a/inc/plugin.h b/inc/plugin.h index 8ba9594..4c5f2ca 100644 --- a/inc/plugin.h +++ b/inc/plugin.h @@ -10,7 +10,7 @@ class CppPlugin; //function pointer -typedef void (*eventfptr)(CppPlugin*, Event*); +typedef void (*eventfptr)(JNIEnv*, CppPlugin*, Event*); typedef CppPlugin* (*initfptr)(); class CppPlugin { diff --git a/src/main/cpp/src/event.cpp b/src/main/cpp/src/event.cpp index d641ee9..691b67b 100644 --- a/src/main/cpp/src/event.cpp +++ b/src/main/cpp/src/event.cpp @@ -12,23 +12,31 @@ const std::string& Event::getName() const { } void* Event::getData(JNIEnv* env, const std::string& name) { - std::cout << "Try to access " << name << std::endl; + DEB("Try to access " << name); + load(env, JNI_MAP); //search in map auto it = data.find(name); if(it == data.end()) { + DEB("Not in map"); + //search in original object //construct string jstring term = env->NewStringUTF(name.c_str()); //call data.get() + DEB("Access Java-Map"); jobject map = getMap(env); jobject content = env->CallObjectMethod(map, MAPGET, term); + DEB("Got " << content); //data.insert for next time data.insert({name, content}); //delete string + DEB("Delete REF"); env->DeleteLocalRef(term); + + return content; } else { return it->second; } @@ -38,13 +46,18 @@ void* Event::getData(JNIEnv* env, const std::string& name) { void Event::setData(const std::string& name, void* d) { //just put it in the map - data.insert({name, d}); + data.erase(name); //delete old + data.insert({name, d});//insert new } void Event::reapply(JNIEnv* env, jobject jevent) { jobject map = getMap(env); + + //clear old map + env->CallObjectMethod(map, MAPCLEAR); + for(auto it : data) { - std::cout << "write back to java: " << it.first << std::endl; + std::cout << "write back to java: " << it.first << " Value: " << it.second << std::endl; jstring key = env->NewStringUTF(it.first.c_str()); env->CallObjectMethod(map, MAPPUT, key, it.second); diff --git a/src/main/cpp/src/libplugin.cpp b/src/main/cpp/src/libplugin.cpp index 59a2904..106b60d 100644 --- a/src/main/cpp/src/libplugin.cpp +++ b/src/main/cpp/src/libplugin.cpp @@ -17,6 +17,7 @@ jfieldID EVENTDATAF; jfieldID EVENTNAMEF; jmethodID MAPGET; jmethodID MAPPUT; +jmethodID MAPCLEAR; jmethodID LISTENERCONTR; jmethodID LISTENERSMALLCONTR; @@ -84,12 +85,14 @@ void load(JNIEnv* env, long data) { 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_MAPCLEARMETH) + MAPCLEAR = env->GetMethodID(MAPCLASS, "clear", "()V"); if(data & JNI_LISTENERCONSTR) LISTENERCONTR = env->GetMethodID(LISTENERCLASS, "", "(Ljava/lang/String;J)V"); if(data & JNI_LISTENERSMALLCONSTR) LISTENERSMALLCONTR = env->GetMethodID(LISTENERCLASS, "", "()V"); - DEB("find methods: " << (!!MAPGET) << (!!MAPPUT) << (!!LISTENERCONTR) << (!!LISTENERSMALLCONTR)); + DEB("find methods: " << (!!MAPGET) << (!!MAPPUT) << (!!MAPCLEAR) << (!!LISTENERCONTR) << (!!LISTENERSMALLCONTR)); } JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_init_1(JNIEnv* env, jobject thisobj) { @@ -187,7 +190,7 @@ JNIEXPORT jobject JNICALL Java_de_mrbesen_cppplugins_CppPlugin_fireEvent(JNIEnv* Event event(env, jevent); //call it - f(plugin, &event); + f(env, plugin, &event); //put changed fields back in the jevent event.reapply(env, jevent); diff --git a/src/main/java/de/mrbesen/cppplugins/CppEvent.java b/src/main/java/de/mrbesen/cppplugins/CppEvent.java index f435cae..e95f56f 100644 --- a/src/main/java/de/mrbesen/cppplugins/CppEvent.java +++ b/src/main/java/de/mrbesen/cppplugins/CppEvent.java @@ -19,7 +19,7 @@ public class CppEvent { System.out.println("cppifying event: " + e.getClass().getSimpleName()); CppEvent cppe = new CppEvent(e.getClass().getSimpleName()); - for(Field field : e.getClass().getFields()) { + for(Field field : e.getClass().getDeclaredFields()) { System.out.println("try to read Field: " + field.getName()); if(!field.isAccessible()) field.setAccessible(true); @@ -34,19 +34,21 @@ public class CppEvent { } public static void uncppify(CppEvent cppe, Event original) { - System.out.println("uncppifying event: " + original.getClass().getSimpleName()); + System.out.println("uncppifying event: " + original.getClass().getSimpleName() + " values: " + cppe.data.size()); if(!original.getClass().getSimpleName().equals(cppe.name)) throw new IllegalArgumentException("CppEvent does not match original event type!"); - for(Field field : original.getClass().getFields()) { + for(Field field : original.getClass().getDeclaredFields()) { System.out.println("try to set Field: " + field.getName()); - if(!field.isAccessible()) field.setAccessible(true); Object value = cppe.data.get(field.getName()); if(value == null) { System.out.println("Data not available - skip"); continue; } + System.out.println("value: " + value); + + if(!field.isAccessible()) field.setAccessible(true); try { field.set(original, value); diff --git a/src/main/java/de/mrbesen/cppplugins/CppPlugin.java b/src/main/java/de/mrbesen/cppplugins/CppPlugin.java index be4804f..6df2f15 100644 --- a/src/main/java/de/mrbesen/cppplugins/CppPlugin.java +++ b/src/main/java/de/mrbesen/cppplugins/CppPlugin.java @@ -9,6 +9,7 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; diff --git a/testplugins/simpleEvents/src/plugin.cpp b/testplugins/simpleEvents/src/plugin.cpp index 6efb873..656b692 100644 --- a/testplugins/simpleEvents/src/plugin.cpp +++ b/testplugins/simpleEvents/src/plugin.cpp @@ -6,14 +6,6 @@ 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(); @@ -39,6 +31,18 @@ CppPlugin* init() { return new MyPlugin(); } +void eventJoin(JNIEnv* env, CppPlugin* pl, Event* e) { + jstring msg = (jstring) e->getData(env, "joinMessage"); + std::string jmsg(env->GetStringUTFChars(msg, 0)); + std::cout << "join " << e->getName() << " old join message: " << jmsg << std::endl; + jstring newmsg = env->NewStringUTF("Ein Spieler ist dem Spiel beigetreten!"); + e->setData("joinMessage", newmsg); +} + +void eventQuit(JNIEnv* env, CppPlugin* pl, Event* e) { + std::cout << "quit " << e->getName() << std::endl; +} + std::map MyPlugin::getEvents() { std::cout << "MyPlugin::getEvents" << std::endl; std::map out; @@ -46,10 +50,5 @@ std::map MyPlugin::getEvents() { out.insert({"PlayerQuitEvent", eventQuit}); return out; } -/* -std::map MyPlugin::getEvents() { - return std::map(); -} -*/ }//extern "C" \ No newline at end of file