modifing events

This commit is contained in:
mrbesen 2020-02-20 20:17:00 +01:00
parent 02473d1fb1
commit 636a007f62
Signed by: MrBesen
GPG Key ID: 596B2350DCD67504
8 changed files with 50 additions and 30 deletions

View File

@ -10,12 +10,12 @@ private:
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);
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();

View File

@ -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,

View File

@ -10,7 +10,7 @@
class CppPlugin;
//function pointer
typedef void (*eventfptr)(CppPlugin*, Event*);
typedef void (*eventfptr)(JNIEnv*, CppPlugin*, Event*);
typedef CppPlugin* (*initfptr)();
class CppPlugin {

View File

@ -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);

View File

@ -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, "<init>", "(Ljava/lang/String;J)V");
if(data & JNI_LISTENERSMALLCONSTR)
LISTENERSMALLCONTR = env->GetMethodID(LISTENERCLASS, "<init>", "()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);

View File

@ -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);

View File

@ -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;

View File

@ -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<std::string, eventfptr> MyPlugin::getEvents() {
std::cout << "MyPlugin::getEvents" << std::endl;
std::map<std::string, eventfptr> out;
@ -46,10 +50,5 @@ std::map<std::string, eventfptr> MyPlugin::getEvents() {
out.insert({"PlayerQuitEvent", eventQuit});
return out;
}
/*
std::map<std::string, eventfptr> MyPlugin::getEvents() {
return std::map<std::string, eventfptr>();
}
*/
}//extern "C"