View previous topic :: View next topic |
Author |
Message |
motu99
Joined: 24 Sep 2007 Posts: 16
|
Posted: Fri Jan 01, 2010 23:39 Post subject: |
|
|
OK, I finally got nwnx_jvm up and running. Works like a charm, although so far I only tried out the preconfigured stuff.
I had some problems setting up things, in particular with the following Quickstart instruction:
- you need to prefix LD_LIBRARY_PATH=/path/to/libjvm.so to your nwserver start script, where the LD_PRELOAD to nwnx2.so is too.
Being relatively noobish to Java, it took me some time to realize, that libjvm.so is the name of the "normal" Java virtual machine library file, which should be present in any installation of the JDK (or JRE). So I searched down /usr for the file libjvm.so and found 5 instances. I took the path to the "server" version. Is that correct? [There was also a "client" version and some three relatively small files < 10kB which obviously couldbe ruled out]
For better ease of use it might be a good idea to supply an example shell script (like the example for nwnx.ini) to start up the server with nwnx and nwnx_jvm. Here is mine:
#!/bin/sh
export LD_PRELOAD=./nwnx2.so
export LD_LIBRARY_PATH=/usr/local/jdk1.4.2/jre/lib/i386/server
./nwserver \
-publicserver 1 \
-servername YourServerHere \
-dmpassword yourpw \
-oneparty 0 \
-pvp 0 \
-difficulty 2 \
-elc 0 \
-ilr 0 \
-reloadwhenempty 0 \
-module "YourModuleHere" \
-maxclients 32 \
-servervault 1 \
-maxlevel 40 \
-gametype 0 \
-autosaveinterval 0 \
"$@"
After that everything went pretty smoothly.
I compiled jvm_token.nss and put jvm_token.ncs into a hak associated with the module [I guess that should work as well as putting it directly into the module; alternatively the jvm_token.ncs could go into the override folder!?]
Added the line
JVM_EVENT("test_event");
to the module's heartbeat script and looked at the messages piling up in the terminal window.
Seems everything is working great.
Two minor things:
The two example .java source files are outdated, although its quite obvious how to "fix" them.
InitExample.java:
The line
NWObject.registerDefaultHandler();
must be removed, as NWObject.registerDefaultHandlers() is gone since Dec 19th.
EventExample.java:
The import statement must be changed from
import org.nwnx.nwnx2.java.*;
to
import org.nwnx.nwnx2.jvm.*;
Also the line
NWScript.sendMessageToAllDMs("Event from Java: " + event + " on OBJECT_SELF = " + self.oid);
must be changed to
NWScript.sendMessageToAllDMs("Event from Java: " + event + " on OBJECT_SELF = " + self.oid());
[oid has been made private; read-access now is via oid()]
Thanks for posting your work here. The possibilities are ... awesome.
Ever since acaos released his nwexalt to the nwnx-community (in the form of nwns_funcs) I have been thinking to port the PRC to Linux. Grating feats and spells directly to a PC (via NWScript - without BootPC+Leto) would make the PRC much more user-friendly, than placing class-feats and spells as itemPropertyBonusFeats on the hide. The code would be much leaner, too. And many so far (nearly) impossible things could be done quite easily. However, I wasn't too keen on writing/rewriting tons of code in NWScript. But now I can do it in Java and learn to do some decent Java-programming at the same time. |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Mon Jan 04, 2010 10:35 Post subject: |
|
|
Changes:
- updated example code to use new classHandlers, eventListeners
- Scheduler.every() shiny new (but not yet efficient)
- NWVector.ORIGIN now NWVector, not Object (duh)
- Anon now generic, scheduleWait returns value after blocknig |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Mon Jan 04, 2010 10:46 Post subject: |
|
|
motu99: Thank you for your detailed post - I'm sure it'll help other people getting things up and running. Thanks also for the bug-report.
For kicks, here's a overview of my currently work-in-progress code:
* nwnxjvm_osgi: Apache Felix (OSGi R4) launcher inside NWServer
* NWNXVJM ObjectHierarchy (OSGi bundle): A tree hierarchy mapping NWN game objects to java classes, implementing all functionality in a clean, object-orientied way.
Upcoming, when I get around to it:
* NWNXJVM ResMan (OSGi bundle)
* NWNXJVM ScoRco (OSGi bundle)
* NWNXJVM Areas (OSGi bundle) - all three above together useable to bundle game resources in OSGi bundles, fully dynamic loading/unloading
* NWNXJVM Chat (OSGi bundle exporting chat service)
* lots more
Also, I really need to write up some decent documentation ..
Last edited by elven on Tue May 01, 2012 23:19; edited 1 time in total |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Sat Jan 09, 2010 15:51 Post subject: |
|
|
A bunch of changes:
- Scheduler can be configured to map OBJECT_INVALID to null instead of NWObject.INVALID. (This is useful for implementations that map objects to hierarchical classes and do primitive casting.) The default (was and) is to return NWObject.INVALID.
- Experimental SCO/RCO support. May memleak or not work in some cases. Does not run with -Xcheck:jni enabled (will be fixed later, but I suspect some people want to try it out.)
Updated files are at the usual place. (Sorry for rebasing the git repo. Get used to it. :p)
Edit: to test SCORCO, simply look at TestRunner. It's quite simple, you just need to implement SCORCOListener and return non-null values for keys you want to handle. |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Sun Jan 10, 2010 22:27 Post subject: |
|
|
(obsolete information removed)
Last edited by elven on Tue May 01, 2012 23:20; edited 1 time in total |
|
Back to top |
|
|
Fireboar
Joined: 17 Feb 2008 Posts: 323
|
Posted: Sat Jan 16, 2010 0:26 Post subject: |
|
|
Interesting. I've had a go, but unfortunately can't get any of my code to work: I get a java.lang.NoClassDefFoundError on my initListener class. Do I need to make a jar file? Where should my folder tree be in relation to the org.nwnx.nwnx2.jvm.jar package? Are there any build options I'm likely to have missed? |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Sat Jan 16, 2010 13:51 Post subject: |
|
|
Fireboar wrote: | Interesting. I've had a go, but unfortunately can't get any of my code to work: I get a java.lang.NoClassDefFoundError on my initListener class. Do I need to make a jar file? Where should my folder tree be in relation to the org.nwnx.nwnx2.jvm.jar package? Are there any build options I'm likely to have missed? |
As long as you have compiled .class files, the JVM can find them regardless of build options.
For jar files, you need to put the .jar itself onto the classpath; for custom-compiled class files, you need to put the directory on the classpath, where the package is.
For example, your custom classes are in package org.fireboar.rocks,
you would create a directory "classes" (or any other name), and create the directory structure org/fireboar/rocks under that, and put your custom class file in there.
then add the full path to classes/ to your classpath= setting in nwnx2.ini, and configure the listener: org/fireboar/rocks/Listener.
If you don't specify a "package xyzzy;" directive at the top, it's in the so-called default package, and it should work by simply putting it in a directory that is on the class path. |
|
Back to top |
|
|
Fireboar
Joined: 17 Feb 2008 Posts: 323
|
Posted: Sat Jan 16, 2010 22:24 Post subject: |
|
|
Well, working fine now. I kept at it yesterday after making that post and found that I could get either my own classes to be recognised (those not packaged in a jar file) or the ones provided in your package. I tried several things... in the end I found out how to put both the base directory of my classes and the jar file in classpath: by separating them with a colon (. It worked fine after I did that... maybe in the documentation it would be good to be a little more specific about that: I did notice in the nwnx.ini page on the wiki is a brief mention of "pathsep", but nothing on what this is.
Still, that raises the question. Is it possible to have just one entry in classpath, and linking a jar file and non-packaged code? Because if not, that's got to be something for the quickstart documentation, surely.
Anyway, looking good! |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Sat Jan 16, 2010 22:33 Post subject: |
|
|
Fireboar wrote: | Well, working fine now. I kept at it yesterday after making that post and found that I could get either my own classes to be recognised (those not packaged in a jar file) or the ones provided in your package. I tried several things... in the end I found out how to put both the base directory of my classes and the jar file in classpath: by separating them with a colon (:). It worked fine after I did that... maybe in the documentation it would be good to be a little more specific about that: I did notice in the nwnx.ini page on the wiki is a brief mention of "pathsep", but nothing on what this is.
Still, that raises the question. Is it possible to have just one entry in classpath, and linking a jar file and non-packaged code? Because if not, that's got to be something for the quickstart documentation, surely.
Anyway, looking good! |
Oh yeah. pathsep is : on linux, and ; on windows. classpath is meant to have multiple entries unless your application is very simple; order determines which class overrides what (if multiple of the same name exist). You cannot "link", classpath IS the search path much like PATH for binaries. |
|
Back to top |
|
|
Fireboar
Joined: 17 Feb 2008 Posts: 323
|
Posted: Sun Jan 17, 2010 0:03 Post subject: |
|
|
Got it, that makes perfect sense. Next thing to play with: this whole OSGi doohicky. Hooray for programming by trial and error!
EDIT: Oh, wait, hang on. Work in progress. Nevermind. |
|
Back to top |
|
|
motu99
Joined: 24 Sep 2007 Posts: 16
|
Posted: Sun Jan 17, 2010 23:33 Post subject: |
|
|
I love this tool!
So far it works beyond expectations
[I couldn't try out everything I had in mind, because Windows deleted my whole extended partition with all data on it, although it should have only deleted one outdated logical partition within the extended partition - took me quite some time to get everything back... arrgh]
I have written a Java class NWNXFunc (plus some helper classes) that implements all of the functionality in nwnx_func (by using the NWScript.setLocalString / getLocalString calls from within the JVM). Everthing works fine, although I didn't test every single func.
@elven: If you are interested in integrating those into the .jar let me know. I'll send the java source via Email.
Some things are a bit over my head still: OSGi, Ruby, closure, ... [I'll manage, eventually]
Another thing that has been on my mind: Why is ActionDoCommand() not needed? I always thought, that ActionDoCommand() puts a nwscript function (bytecode) in the action queue, which - AFAIK - is different from queue that handles the AssignCommand() stuff. What am I missing? |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Sun Jan 17, 2010 23:39 Post subject: |
|
|
motu99 wrote: | Another thing that has been on my mind: Why is ActionDoCommand() not needed? I always thought, that ActionDoCommand() puts a nwscript function (bytecode) in the action queue, which - AFAIK - is different from queue that handles the AssignCommand() stuff. What am I missing? |
Exactly.
AssignCommand() is just for context-switching (think: changing OBJECT_SELF). It does not manipulate the action queue.
ActionDoCommand() is to to encapsulate nwscript bytecode into a action-queue-executable action. This is the functionality that assign() in the jvm.jar implements.
Strictly speaking, jvm.jar doesn't support AssignCommand() as it is, it always does a round-trip into a token after the current event. (There is Scheduler.assignNow(), but I do not recommend using it because there is no advantage to have it scheduled immediately; instead, Scheduler.assign() queues all closures to the end of the event and then flushes them per-object, which is significantly faster). |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Mon Jan 18, 2010 2:29 Post subject: |
|
|
motu99 wrote: |
I have written a Java class NWNXFunc (plus some helper classes) that implements all of the functionality in nwnx_func (by using the NWScript.setLocalString / getLocalString calls from within the JVM). Everthing works fine, although I didn't test every single func.
@elven: If you are interested in integrating those into the .jar let me know. I'll send the java source via Email. |
Thanks for the offer - you may mail it to me and I may make yet use of it, but not in the core jvm.jar distribution. I will bundle nwnx plugins in OSGi bundles and provide services that way. |
|
Back to top |
|
|
Fireboar
Joined: 17 Feb 2008 Posts: 323
|
Posted: Tue Jan 19, 2010 3:03 Post subject: |
|
|
Initial impressions are very impressive, though there is one thing. Suppose I have a function in a DelayCommand loop, pseudo-heartbeat. How would that translate to Java? Some means of inserting parameters into the e method of Anon classes would be great. OBJECT_SELF seems to get lost in this transition as well. |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Tue Jan 19, 2010 3:45 Post subject: |
|
|
Fireboar wrote: | Initial impressions are very impressive, though there is one thing. Suppose I have a function in a DelayCommand loop, pseudo-heartbeat. How would that translate to Java? Some means of inserting parameters into the e method of Anon classes would be great. OBJECT_SELF seems to get lost in this transition as well. |
Pseudo-Heartbeats are notoriously difficult to get right, because either you miss ticks and lose the HB or have multiple tick threads running. The most pragmatic way to do it is simply to start X DelayCommands on Module HB (which runs every 6 seconds) and spread it out from there.
Runnable doesn't have OBJECT_SELF, yes - but that is not the issue, since you can bind all local final variables into the closure, like so (pseudo-code):
Code: |
// objSelf from method header, flag final if needed
final NWObject whatever = ...;
Scheduler.schedule(new Runnable() {
void run() {
objSelf.moveTo(whatever);
}
});
|
If that doesn't answer your question, please clarify. |
|
Back to top |
|
|
|
|
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
|