logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
nwnx_jvm - native JVM integration
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9
 
Post new topic   Reply to topic    nwnx.org Forum Index -> Linux development
View previous topic :: View next topic  
Author Message
elven



Joined: 28 Jul 2006
Posts: 259
Location: Germany

PostPosted: Wed Apr 06, 2016 15:48    Post subject: Re: ideas Reply with quote

Baaleos wrote:
Hi Elven,
Sorry, only just replying.

Performance wise - I could live with slower than native NWScript, its really the background thread operation I am looking forward to.


Had a brief look over your code, and there's a rather sizeable issue with it that I think you will run into.

You want to do many small nwscript invocations from a different thread than the mainloop one. To make this work without either memory or stack corruption, you need to slot each call somewhere into the mainloop, either through yielding nwscript invocations (via Scheduler.queue...etc), or through the new native Mainloop::Now() templates in nwnx2.

Either way will mean your thread synchronises with the mainloop for every single call you make, meaning your runtime performance will be absolute shite.

The NWN mainloop runs, by default, at 100 times per second; which means you will get AT MOST 100 nwscript calls in. The actual number is probably closer to 20. If you run nwnx_optimisations, this number will be even lower.

The obvious solution to this is to bunch up calls into atomic units and schedule whole blocks of functionality. At this point, you're back where you are now, with adding chunks of logic through DelayCommand().

There is no real fix for this. All game state touching code NEEDS to run on the gameloop thread.

tldr: you will not gain performance increases from running it in a separate thread; in fact, it will be even slower. It's best to keep code that heavily relies on nwscript in the main thread.
_________________
silm.pw, a player-driven Forgotten Realms NWN1 persistent world for tinkerers.
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Wed Apr 06, 2016 16:02    Post subject: Reply with quote

Just answered my own question about calling nwnx methods from inside jvm.

Doesn't seem to work.
But I am trying this approach.

Code:


//jvm_seteffcre
void main()
{
   object oModule = GetModule();
   object o = GetLocalObject(oModule,"ARGUMENT1");
   SetLocalString(oModule, "NWNX!STRUCTS!SETCREATOR", ObjectToString(o));
}



And then doing the following in jvm

Code:

public static void SetEffectCreator (NWEffect eEffect, NWObject oCreator) {
      NWScript.setLocalObject(NWObject.MODULE, "ARGUMENT1", oCreator);
       NWScript.executeScript("jvm_seteffcre", oCreator);
       NWScript.deleteLocalObject(NWObject.MODULE, "ARGUMENT1");
      
   }



Will know soon if it works.
Back to top
View user's profile Send private message
elven



Joined: 28 Jul 2006
Posts: 259
Location: Germany

PostPosted: Wed Apr 06, 2016 16:22    Post subject: Reply with quote

Baaleos wrote:
Just answered my own question about calling nwnx methods from inside jvm.

Doesn't seem to work.
But I am trying this approach.

Code:


//jvm_seteffcre
void main()
{
   object oModule = GetModule();
   object o = GetLocalObject(oModule,"ARGUMENT1");
   SetLocalString(oModule, "NWNX!STRUCTS!SETCREATOR", ObjectToString(o));
}



And then doing the following in jvm

Code:

public static void SetEffectCreator (NWEffect eEffect, NWObject oCreator) {
      NWScript.setLocalObject(NWObject.MODULE, "ARGUMENT1", oCreator);
       NWScript.executeScript("jvm_seteffcre", oCreator);
       NWScript.deleteLocalObject(NWObject.MODULE, "ARGUMENT1");
      
   }



Will know soon if it works.


You should be able to call that kind of thing from jvm directly, with setLocalString(.., "NWNX!.."); basically reproducing the nwscript code verbatim.
_________________
silm.pw, a player-driven Forgotten Realms NWN1 persistent world for tinkerers.
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Wed Apr 06, 2016 16:48    Post subject: Reply with quote

Code:

ublic static void SetEffectCreator (NWEffect eEffect, NWObject oCreator) {
      if(oCreator.equals(null)){
         NWScript.printString("Object equals null");
         return;
      }
      NWScript.printString("Attempting to set Effect Creator as "+oCreator.getObjectId());
      NWScript.setLocalString(NWObject.MODULE, "NWNX!STRUCTS!SETCREATOR", oCreator.getObjectId());
      //NWScript.setLocalObject(NWObject.MODULE, "ARGUMENT1", oCreator);
       //NWScript.executeScript("jvm_seteffcre", oCreator);
       //NWScript.deleteLocalObject(NWObject.MODULE, "ARGUMENT1");
   }



Gives me

Quote:

[Dynamic-linking native method java.lang.Double.longBitsToDouble ... JNI]
Exception in thread "Thread-1" java.lang.NullPointerException
[Dynamic-linking native method java.lang.Throwable.getStackTraceDepth ... JNI]
[Dynamic-linking native method java.lang.Throwable.getStackTraceElement ... JNI]
at org.baaleos.systems.genetics.Include.SetEffectCreator(Unknown Source)
at org.baaleos.systems.genetics.Include.HeartbeatProcessGene(Unknown Source)
at org.baaleos.systems.genetics.Include.ProcessGenome(Unknown Source)
at org.baaleos.systems.genetics.Include.ProcessPlayer(Unknown Source)
at org.baaleos.systems.genetics.Include.GeneticsLoop(Unknown Source)
at org.baaleos.systems.genetics.GeneticsHeartbeat.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)



Just wondering if it doesn't like the oid format?
Its complaining about a null reference, but I am trying to trap the null reference - still gets through it.

Note - I am running this on a background thread.
Initiated from TestRunner via

Code:

@Override
         public void event(NWObject objSelf, String event) {
            
            try{
               if(event.equals("OnModuleLoad")){
                  long startbench = System.currentTimeMillis();
                  String modName = "";
                  //Start genetics Loop
               }
               if(event.equals("OnModuleLoadGenetics")){
                  (new Thread(new GeneticsHeartbeat())).start();   // <---- HERE
               }
...
Back to top
View user's profile Send private message
elven



Joined: 28 Jul 2006
Posts: 259
Location: Germany

PostPosted: Wed Apr 06, 2016 18:06    Post subject: Reply with quote

Quote:

[Dynamic-linking native method java.lang.Double.longBitsToDouble ... JNI]
Exception in thread "Thread-1" java.lang.NullPointerException
[Dynamic-linking native method java.lang.Throwable.getStackTraceDepth ... JNI]
[Dynamic-linking native method java.lang.Throwable.getStackTraceElement ... JNI]
at org.baaleos.systems.genetics.Include.SetEffectCreator(Unknown Source)
at org.baaleos.systems.genetics.Include.HeartbeatProcessGene(Unknown Source)
at org.baaleos.systems.genetics.Include.ProcessGenome(Unknown Source)
at org.baaleos.systems.genetics.Include.ProcessPlayer(Unknown Source)
at org.baaleos.systems.genetics.Include.GeneticsLoop(Unknown Source)
at org.baaleos.systems.genetics.GeneticsHeartbeat.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)



I'd recommend packing in the actual source code too, then it'll give you more context, like line numbers and symbols, and maybe even var data.
_________________
silm.pw, a player-driven Forgotten Realms NWN1 persistent world for tinkerers.
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Wed Apr 06, 2016 18:28    Post subject: Reply with quote

Hmm
Am I able to do that in eclipse or in the build.xml?

This one is deployed via my jenkins instance, built via the ant build file.
How do I include symbols?

Made this edit to build.xml
Will test it when I get home

Code:

<target name="jar" depends="compile">
      <fileset dir="${src}" includes="**/*.java"/>
      <jar jarfile="${dist}/org.nwnx.nwnx2.jvm.jar"
         
         manifest="META-INF/MANIFEST.MF" basedir="${build}"/>
   </target>

Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Thu Apr 07, 2016 11:34    Post subject: Reply with quote

Managed to get it to run with symbols/debug info.


Code:

[Dynamic-linking native method java.lang.Double.longBitsToDouble ... JNI]
Exception in thread "Thread-1" java.lang.NullPointerException
[Dynamic-linking native method java.lang.Throwable.getStackTraceDepth ... JNI]
[Dynamic-linking native method java.lang.Throwable.getStackTraceElement ... JNI]
        at org.baaleos.systems.genetics.Include.HeartbeatProcessGene(Include.java:140)
        at org.baaleos.systems.genetics.Include.ProcessGenome(Include.java:224)
        at org.baaleos.systems.genetics.Include.ProcessPlayer(Include.java:211)
        at org.baaleos.systems.genetics.Include.GeneticsLoop(Include.java:244)
        at org.baaleos.systems.genetics.GeneticsHeartbeat.run(GeneticsHeartbeat.java:13)
        at java.lang.Thread.run(Thread.java:745)










Line 140 is here
Code:

if(Apply == 5){
         //Conditions met!
         int iDamageToApply = theGene.getApplyDamageAmount();
         NWEffect eEffect;
         NWObject oEffectCreator = GetGeneticEffectCreator();
HERE ->>>>         if(oEffectCreator.valid()){
            NWScript.printString("Object is valid!");
         
         }
         if(iDamageToApply > 0){
            //Damage effect
            int iDamageType = theGene.getDamageType();
            eEffect = NWScript.effectDamage(iDamageToApply,iDamageType,DAMAGE_POWER_ENERGY); //IRRESISTABLE
            //SetEffectCreator(eEffect, oEffectCreator);
            NWScript.applyEffectToObject(DurationType.INSTANT,eEffect,oPC,0.00f);
            
         }else{
            NWScript.printString("Attempting to apply effect!");
            if(!HasEffectAlready(oPC,theGene.getEffectType())){
               //WriteTimestampedLogEntry("Does not have effect already: Applying new");
               eEffect = GetEffectFromID(theGene.getEffectType(), theGene.getEffectNumber1(), theGene.getEffectNumber2());
               SetEffectCreator (eEffect, oEffectCreator);
               NWScript.applyEffectToObject(DurationType.PERMANENT,eEffect,oPC,0.00f);
            }
         }
Back to top
View user's profile Send private message
elven



Joined: 28 Jul 2006
Posts: 259
Location: Germany

PostPosted: Thu Apr 07, 2016 13:22    Post subject: Reply with quote

Is oEffectCreator null, maybe?
_________________
silm.pw, a player-driven Forgotten Realms NWN1 persistent world for tinkerers.
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Thu Apr 07, 2016 14:55    Post subject: Reply with quote

In this particular test, oEffectCreator is

Code:

   private static NWObject GetGeneticEffectCreator(){
      return NWScript.getObjectByTag("genetic_unit_test", 1);
   }


That creature does exist, when I have a ModLoad script execute something on him, he is able to do it.
The irony here, is that the effect I am trying to change the creator to, is being applied to him.

Eg: oPC and oEffectCreator are the same object, just acquired differently
(oPC was acquired via getLocalObject from the module)

(Note - while it says its oPC, its actually an NPC, I am using an NPC to simulate a PC)

The only thing I can think of at the moment, is that maybe kicking my Java code off in the Module OnLoad event, is triggering this code, before the creature has been spawned?
Something that might not ordinarily occur for NWScript.

I will try delaying the java call.
Back to top
View user's profile Send private message
elven



Joined: 28 Jul 2006
Posts: 259
Location: Germany

PostPosted: Thu Apr 07, 2016 15:36    Post subject: Reply with quote

If memory serves, the nwnx_jvm java libs support a flag where OBJECT_INVALID can be either null, or a valid object that represents null, for this exact reason (to cut down on nullptr checks). You should check which one you've set to use.
_________________
silm.pw, a player-driven Forgotten Realms NWN1 persistent world for tinkerers.
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Thu Apr 07, 2016 17:29    Post subject: Reply with quote

How do I set which one to use?

Quote:

Stack: [0xf0757000,0xf07a8000], sp=0xf07a6820, free space=318k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [nwnx_structs.so+0x16ca] Func_SetCreator+0x26
C [nwnx_structs.so+0x1b06] CNWNXStructs::OnRequest(char*, char*, char*)+0x5e
C [nwnx2.so+0x5376f] StringPayLoad(char const**, char const**)+0x388
C [nwnx2.so+0x54387] my_SetString(char const**, char const**, char const**)+0x1a
C [nwserver+0x1bc1ec]
C [nwserver+0x1e9a7e]
C [nwnx_jvm.so+0x4862a] VM_ExecuteCommand+0x1e
C [nwnx_jvm.so+0x84ddb] Java_org_nwnx_nwnx2_jvm_NWScript_setLocalString+0x3a2
j org.nwnx.nwnx2.jvm.NWScript.setLocalString(Lorg/nwnx/nwnx2/jvm/NWObject;Ljava/lang/String;Ljava/lang/String;)V+0
j org.baaleos.systems.genetics.Include.SetEffectCreator(Lorg/nwnx/nwnx2/jvm/NWEffect;Lorg/nwnx/nwnx2/jvm/NWObject;)V+54
j org.baaleos.systems.genetics.Include.HeartbeatProcessGene(Lorg/nwnx/nwnx2/jvm/NWObject;Lorg/baaleos/systems/genetics/Gene;ILorg/nwnx/nwnx2/jvm/NWObject;IIII)V+277
j org.baaleos.systems.genetics.Include.ProcessGenome(Lorg/nwnx/nwnx2/jvm/NWObject;Lorg/baaleos/systems/genetics/Genome;I)V+111
j org.baaleos.systems.genetics.Include.ProcessPlayer(Lorg/nwnx/nwnx2/jvm/NWObject;I)V+38



I get a java crash when the call eventually gets to nwnx_structs

I am feeding through the following:

Code:

NWObject oEffectCreator = oPC;
         if(oEffectCreator.valid()){
            NWScript.printString("Object is valid!");
         
         }
         if(iDamageToApply > 0){
            //Damage effect
            int iDamageType = theGene.getDamageType();
            eEffect = NWScript.effectDamage(iDamageToApply,iDamageType,DAMAGE_POWER_ENERGY); //IRRESISTABLE
            //SetEffectCreator(eEffect, oEffectCreator);
            NWScript.applyEffectToObject(DurationType.INSTANT,eEffect,oPC,0.00f);
            
         }else{
            NWScript.printString("Attempting to apply effect!");
            if(!HasEffectAlready(oPC,theGene.getEffectType())){
               //WriteTimestampedLogEntry("Does not have effect already: Applying new");
               eEffect = GetEffectFromID(theGene.getEffectType(), theGene.getEffectNumber1(), theGene.getEffectNumber2());
   HERE ->>            SetEffectCreator (eEffect, oEffectCreator);
               NWScript.applyEffectToObject(DurationType.PERMANENT,eEffect,oPC,0.00f);
            }
         }


Quote:

StrReq: "SETCREATOR"
Params: "f"





As far as I know, thats a valid call to nwnx_structs
It just doesn't seem to like it in jvm Sad
I changed oEffectCreator to be oPC.
oPC it seems to be a valid object.
Back to top
View user's profile Send private message
elven



Joined: 28 Jul 2006
Posts: 259
Location: Germany

PostPosted: Thu Apr 07, 2016 18:16    Post subject: Reply with quote

Baaleos wrote:
How do I set which one to use?


https://github.com/NWNX/nwnx2-linux/blob/master/plugins/jvm/java/src/org/nwnx/nwnx2/jvm/NWObject.java#L217
_________________
silm.pw, a player-driven Forgotten Realms NWN1 persistent world for tinkerers.
Back to top
View user's profile Send private message
xorbaxian



Joined: 18 Dec 2007
Posts: 45

PostPosted: Tue Jul 25, 2017 20:50    Post subject: jvm - status ? Reply with quote

hi all,

just wondering what the actual status of this plugin is.

i'm doing a global make from a completely fresh install. everything goes fine until i reach the jvm plugin. at this point, some required files are missing in the build tree.

Code:
/usr/bin/ruby: No such file or directory -- ./build/gen_java.rb (LoadError)
plugins/jvm/CMakeFiles/jvm.dir/build.make:62: recipe for target 'plugins/jvm/java/src/org/nwnx/nwnx2/jvm/NWScript.java' failed
make[2]: *** [plugins/jvm/java/src/org/nwnx/nwnx2/jvm/NWScript.java] Error 1
CMakeFiles/Makefile2:784: recipe for target 'plugins/jvm/CMakeFiles/jvm.dir/all' failed
make[1]: *** [plugins/jvm/CMakeFiles/jvm.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

i tracked this down to a possible inconsistency in the cmake file. while the build directory does exist in the source tree at nwnx2-linux/plugins/jvm, it and its contents aren't copied into the global build directory nwnx2-linux/build/plugins/jvm during the cmake, so an error is thrown. furthermore, simply copying the directory over into the build tree gens an additional page's worth of compile errors. most of these are of the form
Code:
{function} retval "{value}": cannot resolve, will not export

but there are also a few like
Code:
./build/gen_java.rb:692:in `initialize': No such file or directory @ rb_sysopen - java/src/org/nwnx/nwnx2/jvm/NWScript.java (Errno::ENOENT)

i.e., the build refers to source files that are actually missing from the distrib.

all of this leads me to believe this plugin hasn't actually been configured for distribution. is it still experimental ?
Back to top
View user's profile Send private message
Zunath



Joined: 06 Jul 2006
Posts: 183

PostPosted: Wed Nov 22, 2017 13:02    Post subject: Reply with quote

Hi,

Will this plugin be updated as part of the rewrite for the enhanced edition?

Thanks!

EDIT: Disregard. I received my answer on Discord. For others:

JVM won't be included at launch. It'll require a rewrite.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Linux development All times are GMT + 2 Hours
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9
Page 9 of 9

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group