Author Topic: Re: An Array 'within' a Variant  (Read 2482 times)

0 Members and 1 Guest are viewing this topic.

Offline JFK

  • Camper
  • ***
  • Posts: 255
    • My TraxInSpace Account
An Array 'within' a Variant
« on: April 22, 2008, 04:04:45 pm »
Hellow all,

I have a question for those who are somewhat 'advanced' in Delphi/Pascal. I hope i can borrow some of your time:
I'm currently working on a Debug-script. It should help you scripters keep an eye on variables in order to debug large scripts. For this script i'm working with variants. Now i'd like to make the following procedure:

Code: [Select]
Debug(VarPar : Variant; Name, Script : String);

The procedure should be called through crossfunc, so it can be used in other scripts.
What the procedure does is making a copy of the value(s) of VarPar in to an Array of Variant (within an Array of Record). By using GetVarType() on VarPar i can determine whether VarPar is an Array or not. So far so good, Debug() can 'swallow' any kind of variable, INCLUDING complete arrays, like this:

Code: [Select]
SomeIntegers : Array of Integer;
SetArraySize.... blahblah give them some values...
Debug(SomeIntegers, 'SomeIntegers', ScriptName);

As said before, within Debug() there will be checked if VarPar is an array or not and that goes well, until i try to copy VarPar to an Array of Variant. In fact, GetVarType() might TELL me that VarPar is an array, but it seems its not. The following things i tried to find out the (array-)size of VarPar just won't work:

Code: [Select]
GetArrayLenght(VarPar);                      //Runtime: Could not call proc
//---------------
ArrayHigh(VarPar);                              //Runtime: Type Mismatch
//---------------
while (VarPar[i] <> NULL) do inc(i, 1);   //Runtime: Invalid variant type conversion
//---------------
VarParArray : Array of Variant;
VarParArray := VarPar                         //Runtime: Type Mismatch
//---------------
for i:= 0 to $FFFF do begin
   try Dummy := VarPar[i];
   except break;
   end;
 end;                                                //no errors (try-method), but i is always 0 (probably also type conversion error);

In fact VarPar[0] gives me an error on itself, wich makes me believe that a Variant can never be 'truly' an Array. Thus meaning there will never be ANY WAY to print out the values of an array 'within' Variant (since i should AT LEAST be able to determine how big that array is).
Now there seem to be some ways to typecast variables like this:

Code: [Select]
(VarPar as Array of Variant)   //Compile: syntax error
(VarPar as TvariantArray)      //Runtime: type Mismatch
TvariantArray(VarPar)           //Runtime: type Mismatch

But it seems to be impossible to typecast to an Array.
The only solution for the script i can think of is make a different Debug-procedure for an array. However i came this far and i like to finish the job as elegant as possible, so is there any way to:
-get the Array out of a Variant type?
-type-cast an 'Array within an Variant' to an array?
-find any other type like variant that can handle arrays as well as single variables?

If you read this: thank you for your time,

JFK

edit: tried some more typecasts: they compile, but won't work on runtime
« Last Edit: April 24, 2008, 05:20:14 am by JFK »
Come join: EliteCTF
Listen to: My Music

Offline JFK

  • Camper
  • ***
  • Posts: 255
    • My TraxInSpace Account
Re: An Array 'within' a Variant
« Reply #1 on: April 25, 2008, 09:14:47 am »
(sorry to double post, but i think it's better than opening a new topic on almost the same subject.. besides that: BUUUUMP)

Well, without any answers im just gonna talk to myself a bit more so at least all my findings will be documented online, for myself.. for you.. and for our children...
If you have anything to add, comment or even want to tell my what a fool i am trying this stuff, please reply...

I still have not found any way to get an Array out of a single variant type. Thats why i moved on and split the debug procedure into two separate ones:

Code: [Select]
Debug(VarPar : Variant; Name, Script: String);
DebugA(VarParArray : TvariantArray; Name, Script: String);

Very nice, DebugA() is my main function. All that Debug() does is putting the single Variant in a TvariantArray (also read: Array of Variant, practically the same) on index zero. With that Array I then call DebugA(). So far so good, now for my next problem:
It seems that a procedure with TvariantArray as argument will only swallow a TvariantArray and nothing else. This unlike a procedure with a single Variant, which will, as i stated before, swallow practically anything. To clarify:

Code: [Select]
SomeIntegers : Array of Integer;
SetArraySize(Some...blahblah give them some values...

Procedure SwallowVariant(Var : Variant);
begin
  WriteLn('Hello World!');
end;

Procedure SwallowVariantArray(VarArray: TvariantArray);
begin
  WriteLn('Hello Hell!')'
end;

SwallowVariant(SomeIntegers); //Will nicely output "Hello World", but i wont be able to use the array anymore (as stated before)
SwallowVariantArray(SomeIntegers); //Gives me a runtime-error: Type Mismatch

An obvious solution would be to create another procedure like this one:

Code: [Select]
DebugAI(IntArray : Array of Integer; Name, Script : string);
var
VarParArray : TvariantArray;
Index : integer;

begin
  Index := GetArrayLength(IntArray);
  SetArrayLength(VarParArray, Index);
  for i:=0 to (Index-1) do VarParArray[i] := IntArray[i];
  DebugA(VarParArray, Name, ScriptName);
end; 

This has however two disadvantages:
1. I will have to create a different debug-procedure for every (global) type of array (that's 5 types: variant, integer, float, string and boolean, help me here if i forget anything).
2. By using it this way TvariantArray will lose it's Type-information, usually retrievable by VarType() (note: i called this GetVarType before, that was a mistake). I have to add here that since i haven't been able to let a procedure with TvariantArray swallow a different type of array, i do not know if VarType() will work at all on a TvariantArray as it does on a single Variant. VarType(TvariantArray) will 'probably' always return Variant as type, since that seems to be the only type it can hold on to. VarType(TvariantArray[index]) will return the correct type, just like VarType(Variant), however VarType(TvaraintArray[index+1]) could then of course be something totally different.

Well.. to bring my problem in to context: I was hoping to provide you scripters with a single procedure Debug() which would give you the possibility to easily keep track of all kinds of variables you use in a script (by logging (rtf!!!), consolewriting and even drawing(!!)). But now that one simple procedure (that will have to be included in the script you want to debug) seem to have grown out to 6 different ones (one for single types, 5 for arrays). This kind of kills the 'easy' part which is quite important for this project i think.

And it even gets worse:

Back up a bit and forget about TvariantArray for now. I found another problem in the single Variant. It seems that it has some trouble with booleans.... yep those simple one or zero bitlike types.. fecking booleans... watch:

Code: [Select]
TestVar : Boolean;
TestVar := true;

Function VarToString(VarPar : Variant): String; //there actually exist a vartostr() procedure in delphi, but not in soldat...
var
ParType : integer;
ParValue : string;
begin
  ParType := VarType(VarPar) and VarTypeMask; //will return an integer that is the type of variabe. VarTypeMask removes the pointer and array info.
  //-----some more conversions for int flt and str which DO work btw.
  if (ParType = 17) then begin //17 is the value for boolean
    if (VarPar = true) then ParValue := 'True' else ParValue := 'False';
  end;
  Result := ParValue;
end;

WriteLn(VartoStr(TestVar)); //will give me a runtime: Invalid variant type conversion

Replacing (VarPar = true) for (VarPar = 1) or typecasting (VarPar as Boolean) will change nothing. Replacing it for (VarPar) will give me a compile error Type Mismatch. Basically this means that as soon as i put a Boolean into a Variant it becomes unusable. The information that little bit was carrying is in fact gone. This really surprises me since the function GetPlayerStat in fact returns a Variant, which in a few cases is a perfectly usable Boolean. But then the scriptcore also uses procedures with pointers and in soldatscripting pointers are not supported (pointers btw, would make this project a piece of cake).
So if i want to go on with the project (without any help) i can do two things: totally exclude booleans in the project. Or make a lot of extra procedures and some records just for the booleans, who are, lousy as they may be, still very important. This will also mean a seventh Debug() procedure.

So i'm kinda stuck with a dilemma. I actually don't think i will continue this project unless i find solutions to the problems stated above. I would still prefer a solution to my first question: how to get an Array out of a Variant. If that's not possible, then i'd like to know how to handle TvariantArray like it really is a Variant. But most important: how do i get a boolean out of a Variant. I really think that should be possible and i kinda hope it's a little mistake in the scriptcore which will be solved in the next version. I think i will keep looking for answers myself on our beautiful world wide web. But the problem with that is: I can find things about Variants and TvariantArrays for Delphi (btw: link) but they mostly don't confirm with the soldat scriptcore.
Now if this topic gets a lot of comments like 'PLZ JFK, MAKE US A NICE DEBUG SCRIPT, EVEN IF IT IS A BIT COMPLICATED', i will gladly go on with the project, else this will have to wait for a later time.. or like never.

Once again: if you took the time to read this, thank you very much. If you have something slightly valuable to reply, please do so.

JFK
Come join: EliteCTF
Listen to: My Music

Offline JFK

  • Camper
  • ***
  • Posts: 255
    • My TraxInSpace Account
Re: An Array 'within' a Variant
« Reply #2 on: April 25, 2008, 09:15:10 am »
plz delete this post, the server gave me an error so i posted the last one twice...

double posting is bad enough.. i won't triple post here :p
« Last Edit: April 25, 2008, 09:17:02 am by JFK »
Come join: EliteCTF
Listen to: My Music

Offline Boblekonvolutt

  • Soldier
  • **
  • Posts: 222
  • "YOU are a CAR."
Re: Re: An Array 'within' a Variant
« Reply #3 on: April 26, 2008, 02:21:00 am »
Well, I was gonna make some witty remark about the triple post but I figured I should read the whole thing first and also, I couldn't think of something witty to say.

So, what are you up to? You're trying to make an elephant dance like Baryshnikov*, and you think it will... From a young age, Soldats are trained in the art of soldat scripting - an ancient tradition passed on from geek to geek, nerd to nerd and sometimes geek to nerd. But never, and that's NEVER, is it passed on from a nerd to a geek. When the young Soldats have reached scripting adulthood, they are well trained scripting machines - they know the many secrets and horrors of the scripting core like the back (palm) of their hand - and they know not to cross paths with the brutal god of scripting.

For EnEsCe is a god of not-making-any-sense, capable of unspeakable erratic behaviour. And the dark lord of scripting will NOT provide Soldats with the necessary tools to create beautiful works of scripting art - he will limit them to brutal tools of, umm, well, not art! Bugs, workarounds and type mismatches... Soldat is indeed a Deadly Game - I'm Mr. Idiot Reality Host, thank you for watching. *dramatic music, camera zoom out, burning torches*

The opinions expressed in the text does not represent the opinion of Boblekonvolutt.

*I cant spell that, google is indeed my friend.

Offline JFK

  • Camper
  • ***
  • Posts: 255
    • My TraxInSpace Account
Re: Re: An Array 'within' a Variant
« Reply #4 on: April 26, 2008, 04:09:19 pm »
First of all, thanks for replying, Bob... without any remarks bout the triple post :p

Accept for the nerd-geek sentence in your post, i think i've been able to transform all your creative metaphors into understandable language for a non-native English reader.. i think
I think your post really brings some things into perspective for me. After all, with my six weeks, I'm only a newbie in the art of sodat scripting. And perhaps, like all young ones, I'm having a too idealistic view of the world around me. I am indeed trying to be a choreograph for an elephant, but i kinda already understand that the dancefloor may not be strong enough.
I get the feeling that you have the impression that I am trying to let Enesce strengthen that floor. Accept for a little remark about that 'variants not supporting' booleans *could* be a little mistake in the scriptcore, I really don't expect Ensesce to solve any of my problems. After all, I'm probably the only one with an elephant here (next to some of my sexy ballerinas of course).
As you might have read i actually gave up on the project. I was just slightly hoping that some scripters would tell me that i was working on a very interesting project OR that any of the 'adult' scripters would be like: 'My boy, what are you doing? you should do it like THIS!'...
Your post just decreased that hope to the size of a metaphorical flea; no bad feelings, you're just the messenger ;)
Come join: EliteCTF
Listen to: My Music

Offline Boblekonvolutt

  • Soldier
  • **
  • Posts: 222
  • "YOU are a CAR."
Re: Re: An Array 'within' a Variant
« Reply #5 on: April 27, 2008, 03:51:55 am »
It is an interesting project, but it's not really necessary. Most Soldat scripts just never grow that complicated.