Home   Help Search Login Register  

Author Topic: Properties for objects  (Read 5324 times)

0 Members and 1 Guest are viewing this topic.

UNN

  • Guest
Re:Properties for objects
« Reply #45 on: 20 Jul 2005, 09:10:19 »
I tried passing the array, and used _This in the function, got the same results as you. It appears to treat errors with _This differently to other variables.

I modified the original function, with a local variable instead of a global, and it works for both now:

Code: [Select]
_ARRAY_INITIALISED={private ["_array"] ; _Array=_This Select 0 ; _T=True ; If (Count _Array>=0) Then {_T=False} ; !_T};

If !([TESTARRAY] Call _ARRAY_INITIALISED) Then {TESTARRAY=[] ; Player SideChat Format ["Run Once %1",TESTARRAY]};

Although I'm probably going to drop counts on arrays, and add a boolean check. Sometimes I have 200+ elements, so I don't want to be counting them all the time. Assuming thats what OFP does when you call Count ???

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Properties for objects
« Reply #46 on: 26 Jul 2005, 00:44:53 »
I *guess* that OFP keeps track of the size of its arrays by treating them as objects, and then whenever they are operated on, eg. by the 'set' command, a variable within the array object that keeps track of it's size is also modified. This approach would mean negligible overhead associated with checking the array size. However, we've got no way of knowing.... However, the thing about the function approach is, once any operator that is designed to work on arrays has been run on an undefined variable (for example 'count'), the whole function aborts and spits out the scalar array nonsense. So you'll have noticed that in the function:

_checkVariable = {_bool = true; count _this >= 0; _bool};

the 'count _this' bit isn't actually doing anything except killing the function if the parameter is not an array. So perhaps you could have

_checkVariable = {_bool = true; _this + []; _bool};

which would do excalty the same thing, except without doing any checks on the array.

UNN

  • Guest
Re:Properties for objects
« Reply #47 on: 02 Aug 2005, 04:15:56 »
Quote
I *guess* that OFP keeps track of the size of its arrays by treating them as objects, and then whenever they are operated on, eg. by the 'set' command, a variable within the array object that keeps track of it's size is also modified.

This has to be one possibility, although it would have to cater for + and - as well as set. But easy enough if your BIS, I guess.

Quote
_checkVariable = {_bool = true; count _this >= 0; _bool};

I don't think it kills the function, it just skips this bit:

Code: [Select]
; count _this >= 0 ;



Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Properties for objects
« Reply #48 on: 02 Aug 2005, 05:14:25 »
I think it skips the rest of the function after it encounters the dodgy bit, ie the 'count' operation on a non-array type variable. '_bool' is not returned so _thingie call _checkvariable has some sort of Not-A-Value type variable assigned to it.

+/- ... BIS can do whatever they like, as you point out.

UNN

  • Guest
Re:Properties for objects
« Reply #49 on: 02 Aug 2005, 14:02:25 »
Quote
I think it skips the rest of the function after it encounters the dodgy bit, ie the 'count' operation on a non-array type variable. '_bool' is not returned so _thingie call _checkvariable has some sort of Not-A-Value type variable assigned to it.

Gah..Yeah it's that damn _this again. You are correct, sorry. It's just not standard behaviour, but it does offer a safe workaround for the count command.

Cheers

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Properties for objects
« Reply #50 on: 02 Aug 2005, 22:56:57 »
Interesting how many different 'nothings' there are: <Null>, <Null-Object>, scalar bool array string, scalar bool array string nothing, then of course there's scalar, bool, and so on. I think I understand where most of them come from, although I am a little hazy one where '<null>' originates, despite having seen it around (mostly when checking arrays, it seems to turn up occasionally). I guess we've just learned that the 'nothing' bit means a null value assigned when a function is called using _this.... strange are the ways of OFP.

Offline Killswitch

  • Members
  • *
  • Peace, cheese and ArmA
Re:Properties for objects
« Reply #51 on: 05 Aug 2005, 10:53:01 »
I've been using the Set/GetProperty functions for a while. Neat. However, they needed some fixin'  ;D

The variable existence checks you've been having troubles with...well, this works:
Code: [Select]
...
_checkVariable={_r=true;if(count(_this select 0)>=0)then{_r=false};!_r};
...
...
if ( [FRG_Properties] call _checkVariable ) then {
...
...
Note how I call _checkVariable by passing the parameter into it as an array. OFP has it's ways...

UNN

  • Guest
Re:Properties for objects
« Reply #52 on: 06 Aug 2005, 00:19:32 »
Lol, I seem to be going round in circles with this, I'm constatly changing my mind. I just did a double check, using:

Code: [Select]
_checkVariable = {_bool = true; _this=_this+[]; _bool};

Player SideChat Format ["Run Once %1",TESTARRAY Call _checkVariable]

And you get a 'scalar bool array string nothing 0xfcffffef' error in sidechat. But that does not appear to equate to false? So if you change it to:

Code: [Select]
_checkVariable = {_bool = true; _this=_this+[]; _bool};

If !(TESTARRAY Call _checkVariable) Then {Player SideChat Format ["Run Once %1",TESTARRAY]}

The sidechat command never gets called.

But you could use it this way:

Code: [Select]
_checkVariable = {_bool = true; _this=_this+[]; _bool};

If (Format ["%1",TESTARRAY Call _checkVariable]=="scalar bool array string nothing 0xfcffffef") Then {TESTARRAY=[]}

Thats fine, because your never trying to format the entire array, just a boolean. So it always returns a true or false result.

@KillSwitch

We were trying to come up with a way that avoids using the count command, as we don't know for sure how ofp handles array counting.
« Last Edit: 06 Aug 2005, 07:50:15 by UNN »

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Properties for objects
« Reply #53 on: 09 Aug 2005, 13:10:02 »
Sorry about the delay for my reply, I've been busy with boring RL things... annoying distractions mostly ::)

Killswitch:
Thanks, glad to hear Set/Get are working for you.
I'd just like to point out that at the moment the funcs are tested and working in good order. We're fine tuning, just to make sure we have the quickest and most un-intensive initialisation check possible, to cut down on overhead (a good general purpose word that ;D). UNN has brought up that using count, once the array and all its subarrays start to get large, might create a longer and longer delay, something i'm obviously anxious to avoid.

UNN & Killswitch
The method is entirely unorthodox, as you can see, but relatively fast. It relies on several factors, none of which would qualify as particularly good programming practise :P. They involve:

- Deliberately causing an error in a returning method, by passing it the wrong type of data if uninitialised. An operation inside the method (either count or something else array specific) causes the error when it is passed the wrong type of data. However, the error message gets suppressed

- Passing a nothing/null type variable to an 'if' statement (that's if the array was uninitialised). This is not true, not false, in fact not a boolean at all. Oddly, this doesnt produce an error message, but ofp simply skips the if statement.

- If the array was initialised (ie already existed), the if statment is run. A boolean in this if statement is set to true, which tells the function not to initialise the array. It's all quite straight forward

Code: [Select]
   _init = false;
   if ( FRG_Properties call _checkVariable ) then {
      _userPropertyArray = FRG_Properties;
      _init = true;
   };
   if (!_init) then {
      _userPropertyArray = [];   
      FRG_Properties = _userPropertyArray;
   };
The reason i dont use an else here, instead of the two 'if's, is because if the 'if' is skipped over, then the else is too.

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Properties for objects
« Reply #54 on: 05 Sep 2005, 06:07:17 »
OK - UNN's rating check method for unit pointers has provoked me into action :). I've streamlined the Set and Get funcs here to run more quickly (with any luck).

What I've done:

Got rid of all the extra variables that I didn't really need in the functions, to save OFP  time reading and writing them.

Improved the coding for the initialisation bit at the beginning of the functions- it wasn't written very well, and now takes up about half the space. I'd effectively duplicated the code, which i didnt need to do.

Changed how the Get function works - it should be much faster now in returning values.

Changed the structure of the while loops in the Set method, and taking out one of the break variables (didn't actually need it).

My use of arrays was incorrect in some places. Basically I was writing the same information into the property array twice, because I didnt fully understand how OFP handled arrays when I first wrote it. Needless to say that has been changed, hopefully with a correspondig speed boost.

Removed all comment{} comments and replaced them with // and /**/ comments. This is because when the file is read into a string, the comment{} comments aren't removed, whereas the other type are. This surely had a detrimental effect on speed. Note that the functions will no longer work with loadfile after this.

For the few people who are interested, I will post the new functions as soon as I have tested them.

EDIT:

I have tested them, and there is quite a marked performance increase for the new versions. Lag becomes noticeable (for me) at 6 x (10 'get' calls + 10 'set' calls) x 0.1 second loops. The variables being stored and retreived were ~80 character strings. The old versions were unusable at these kind of frequencies.

Funcs uploaded at the usual place.

« Last Edit: 05 Sep 2005, 11:23:10 by Fragorl »

Offline hardrock

  • Members
  • *
  • Title? What's that?
    • Operation FlightSim
Re:Properties for objects
« Reply #55 on: 08 Dec 2005, 20:01:02 »
I'd like to dig this older thread up again with some improvement suggestions.

Right now, your array format is [ [object, ["prop",value], ["prop",value], ["prop",value]] , [object,...] ]
I think you could improve this by creating an a bit different array structure. You would have one array containing all the objects, and another one containing arrays of properties and values.

[Objects, [ [Properties,Values], [Properties,Values], [Properties,Values] ]

or, written more codewise

[ [object1, object2, object3],[ [ ["prop1","prop2","prop3",...], [value1, value2, value3,...] ] , [ ["prop1_1","prop1_2","prop1_3",...], [value1_1, value1_2, value1_3,...] ] ] ]

This way you could speed up the setting process, as you would simply have to check if the object is in the objects array (using 'in') instead of running through the whole big array. The same counts for the single properties: Instead of loading an array, checking if the first element is the searched property, loading the next one, checking again a.s.o. only to find in the worst case, that the property doesn't exist yet (after having checked 20 others), you simply type if (_prop in _properties). If not, you push the new property and value on the according arrays and get the hell out of there. Else you can still do some looping.

If you have problems with the size of the arrays, you could even split into three arrays, one for the objects, one for the properties and one for the values.

I hope this helped a bit.
« Last Edit: 08 Dec 2005, 20:05:58 by hardrock »

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Properties for objects
« Reply #56 on: 11 Dec 2005, 08:43:43 »
Well, that's definitely a possibility - it appeals partly because of the cutdown on code for checking if a property exists,  partly because it groups the searching terms, ie the strings, together. Had I started writing the functions today, I would have most likely created the array the way you've suggested here.

I don't know if we can make any comment on how the 'in' operator works, or whether or not the game engine does something with it's arrays to make searching go faster. But It'd be nice to think that the Bohemians did something of the sort.

This is probably worth a redesign, except that I don't think it will benefit very many people. If anyone really wants, though, then I'll do it, and also improve the search technique (ie with a binary search or something).

« Last Edit: 11 Dec 2005, 08:44:29 by Fragorl »

Offline General Barron

  • Former Staff
  • ****
  • Semper Fi!
Re:Properties for objects
« Reply #57 on: 11 Dec 2005, 11:04:50 »
This is probably worth a redesign, except that I don't think it will benefit very many people. If anyone really wants, though, then I'll do it, and also improve the search technique (ie with a binary search or something).

I'm always in favor of people updating their resources. There's always room for improvement :).

As far as searching goes: I really don't think it is worth it, if even possible, to do anything other than just iterating one at a time thru the list. Searching generally requires sorting (by what? side?), and I seriously doubt anyone will even fill the array with enough items to make searching worthwhile.
HANDSIGNALS COMMAND SYSTEM-- A realistic squad-control modification for OFP
kexp.org-- The best radio station in the world, right here at home! Listen to John Richards!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:Properties for objects
« Reply #58 on: 12 Dec 2005, 00:31:54 »
I'm always in favor of people updating their resources. There's always room for improvement :).
This is true.

wrt sorting, I was going to write a function do it by string (recall that a new propery can be assigned to an object or a string, and all property names are strings ... in the case of objects i could just format[] them) until i remembered that there is no way to examine strings character by character ... which rules out comparing them ... which rules out sorting them ... which rules out a fancy search. But if there were such facilities, then this would most certainly be possible.

> Filling the array with enough items...
You never know. If someone wanted to implement this for, say, every object on the map, or use this in an ecp-sized project (hundreds of small and mid-sized pieces of data stored...), then it might be conceivably possible. I'm sure that the slowness of retrieval is due to the priority that functions don't get, however.  :-\