I'm Stuck: Sending a list of objects to a Script

Want to discuss changes to the UOX3 source code? Got a code-snippet you'd like to post? Anything related to coding/programming goes here!
Post Reply
Grimson
Developer
Posts: 802
Joined: Sat Jun 04, 2005 1:52 am
Location: Germany
Has thanked: 0
Been thanked: 0

I'm Stuck: Sending a list of objects to a Script

Post by Grimson »

As you already might know I want to add a function to UOX3 that sends a list of items (and maybe one that sends a list of chars) to the JS engine, but I don't seem to be able to find a way.

That's what I found out so far:

There doesn't seem to be a way to send an array, you can only send strings, numeric values or objects. So while I could send the serial of the item for a single list entry instead of the item object I need to send the list itself as an object or as part of an object.

What I tried so far:

Sending a CDataList as an Object, that failed badly. It eigther didn't work at all or it crashed the server. It's also not very easy to check (inside the iterate functions) whether the object send by the script really is a CDataList or not.

Creating a very basic item and directly using it's CDataList, basically using the item as a wrapper for the CDataList. That worked and I could use the alread present functions to iterate over the list, but according to Giwo it can cause data corruption so it's not an option eighter.

I also thought about creating a new wrapper object class, that only contains a bunch of data lists. But this is more or less the same approach I used with the basic item above, and as I currently don't understand how that could cause data corruption I'm not shure that this idea would work.

Any ideas?
giwo
Developer
Posts: 1780
Joined: Fri Jun 18, 2004 4:17 pm
Location: California
Has thanked: 0
Been thanked: 0

Post by giwo »

There is no way I know of to pass an array directly, thus short of creating and sending an object linked to a class that wrapped an array (such as CDataList) which I am hesitant to do, the next best way is the current manner in which we run through lists.

If you notice, AreaCharFunction() populates a list, then on every match calls the function name we specify. Something similar using X,Y,Z would likely be your best bet to accomplish what you were going for.
Scott
Grimson
Developer
Posts: 802
Joined: Sat Jun 04, 2005 1:52 am
Location: Germany
Has thanked: 0
Been thanked: 0

Post by Grimson »

giwo wrote:There is no way I know of to pass an array directly, thus short of creating and sending an object linked to a class that wrapped an array (such as CDataList) which I am hesitant to do, the next best way is the current manner in which we run through lists.
And if I only store the item/char serials inside the array and send them to the JS function? I don't think this could cause any corrupt data.
giwo wrote:If you notice, AreaCharFunction() populates a list, then on every match calls the function name we specify. Something similar using X,Y,Z would likely be your best bet to accomplish what you were going for.
I'll have a look at it, but for the scripts I have in mind I need to somehow get the list of items/chars inside the main function (for ex. to do comparisions on them). Calling a function on each item won't help me there.
giwo
Developer
Posts: 1780
Joined: Fri Jun 18, 2004 4:17 pm
Location: California
Has thanked: 0
Been thanked: 0

Post by giwo »

Well, the CDataList is just a generic wrapper, it can contain anything, much like a vector.

Where corruption comes in is when you use an already existant DataList (like on a character or in a region) and then add items which should not be on that datalist. In the case of manually putting items on another items datalist, you will wind up having the same items saved twice, and thus created twice, with the same serial numbers, causing worldfile corruption.

So if you created your own instance of CDataList, you should be able to pass that to the JS engine in the same way we pass a CChar, it's just another class. The problem is the overhead you will get from creating a new JS class, with new methods.
Scott
Grimson
Developer
Posts: 802
Joined: Sat Jun 04, 2005 1:52 am
Location: Germany
Has thanked: 0
Been thanked: 0

Post by Grimson »

giwo wrote:Where corruption comes in is when you use an already existant DataList (like on a character or in a region) and then add items which should not be on that datalist. In the case of manually putting items on another items datalist, you will wind up having the same items saved twice, and thus created twice, with the same serial numbers, causing worldfile corruption.
Hmmm, but this should only happen when the wrapper item containing the list gets saved. So setting ShouldSave() to false on the wrapper item could prevent it, as the list entrys are only pointers to the actual items and not new instances of them (I think).
giwo
Developer
Posts: 1780
Joined: Fri Jun 18, 2004 4:17 pm
Location: California
Has thanked: 0
Been thanked: 0

Post by giwo »

Yes, the list entrys are just pointers to objects, not actual objects themselves. And setting ShouldSave() to false would stop it from saving and thus keep it from creatind duplicate worldfile entries.

Regardless, creating an item for any purpose other than to create an actual item is bad behavior. If there really is need to pass a list to JS (which I haven't really come across an absolute need yet) the proper way would be to create a new instance of CDataList and make a JS class for it.

As I noted, though, I'm not sure the effort and the resource usage is really worth it, as anything that needs to be done should be able to be accomplished using our current form of list handling.
Scott
Grimson
Developer
Posts: 802
Joined: Sat Jun 04, 2005 1:52 am
Location: Germany
Has thanked: 0
Been thanked: 0

Post by Grimson »

giwo wrote: Regardless, creating an item for any purpose other than to create an actual item is bad behavior.
Agreed.
giwo wrote:If there really is need to pass a list to JS (which I haven't really come across an absolute need yet) the proper way would be to create a new instance of CDataList and make a JS class for it.
I think that's the way I'm going to do it.
giwo wrote:As I noted, though, I'm not sure the effort and the resource usage is really worth it, as anything that needs to be done should be able to be accomplished using our current form of list handling.
Well, ultimately I would like the ability to create custom AIs through JS. But for an AI to be worth anything it needs a way get aware of items and chars in it's environment.

If you don't like or want such a function just say so and I'll keep it out of the CVS and only use it on my local builds.
giwo
Developer
Posts: 1780
Joined: Fri Jun 18, 2004 4:17 pm
Location: California
Has thanked: 0
Been thanked: 0

Post by giwo »

If you get it working, put it in. If we don't think it's something UOX3 needs, we can always remove it later. Alternatively, if it improves the JS interface, we may make use of it and remove other alternatives. :P
Scott
Grimson
Developer
Posts: 802
Joined: Sat Jun 04, 2005 1:52 am
Location: Germany
Has thanked: 0
Been thanked: 0

Post by Grimson »

giwo wrote:If you get it working, put it in. If we don't think it's something UOX3 needs, we can always remove it later. Alternatively, if it improves the JS interface, we may make use of it and remove other alternatives. :P
Ok, but it may take some time as I don't have much time under the week.
Maarc
Developer
Posts: 576
Joined: Sat Mar 27, 2004 6:22 am
Location: Fleet, UK
Has thanked: 0
Been thanked: 0
Contact:

Post by Maarc »

I'm already looking at ways to help improve AI. And really, AreaCharacterFunction/AreaItemFunction would work well for making decisions, if there was an easy way to early abort.

One of the things I'm working on is an upgrade to some combat related things (the tracking of damage and healing). This way, we can apportion karma/fame better, and exposing this information (who does how much damage/healing aggregate over time, but getting rid of entries over 5 minutes old) to the JS would allow you to write AI that is somewhat more intelligent (ie attack the person who's doing the most damage to you, or the person doing the most healing to your current target, etc).
Post Reply