Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Monsieur OUXX on Tue 24/07/2007 19:08:16

Title: optional float parameter
Post by: Monsieur OUXX on Tue 24/07/2007 19:08:16
Hi, i don't understand how "float" optional parameters work...

here is my code :


#define FLOAT_PARAM     -1000.0

struct MyStruct {
    import static void MyFunction(float aNormalParam, float anOptionalParam = FLOAT_PARAM);
};


With this code, i get the error "Parameter default value must be a literal" at compile time.

If i replace "-1000.0" by "-1000", then i get the error "cannot convert from int to float" when i call the function.


#define FLOAT_PARAM     -1000

...
MyStruct.MyFunction(0.0, FLOAT_PARAM); //this raises an error
...

Title: Re: optional float parameter
Post by: Khris on Tue 24/07/2007 20:17:14
Try "-1000.0"
Title: Re: optional float parameter
Post by: Monsieur OUXX on Tue 24/07/2007 22:30:26
Quote from: KhrisMUC on Tue 24/07/2007 20:17:14
Try "-1000.0"

Caught not reading what was written! :)
Please read again!
Title: Re: optional float parameter
Post by: Khris on Tue 24/07/2007 22:38:13
Oh, sorry. I'm tired.
Caught you, too, though ;)

Quote from: manualYou can make int parameters optional if there is a default value that the user doesn't need to supply.
Title: Re: optional float parameter
Post by: monkey0506 on Wed 25/07/2007 03:38:09
Also works for pointers by supplying a default value of 0. :P

Not sure if it would work, but it may be possible to substitute 0 for a float as well. It couldn't hurt to try, right?
Title: Re: optional float parameter
Post by: Gilbert on Wed 25/07/2007 04:02:13
Probably not, Since you have to use 0.0 for float values, if you use 0 you'll get an error. (float is not a pointer, so the scenario is different.)

I think there's a limitation on the optional parameter default values at the moment (possibly limited to 2-byte "short" integers as discovered earlier (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=31829.0)), this may render it impossible to have optional float parameters.
Title: Re: optional float parameter
Post by: Monsieur OUXX on Wed 25/07/2007 09:37:43
Quote from: manualYou can make int parameters optional

Sorry, but it took me more than 2 minutes to find this sentence in the doc, even knowing it's hidden in it.
Couldn't the keyword "optional" be added to the "script keywords" article? (presently it's in the "function" article).


Title: Re: optional float parameter
Post by: Ashen on Wed 25/07/2007 11:40:09
The function entry is part of the 'Script Keywords' article, isn't it? Also, I think giving it it's own entry would be confusing - it's not someting you have to actually USE to make optional parameters work, it's a matter of how you import the function. So, having optional parameters explaned in the function, or possibly import, entry makes more sense to me. Otherwise, it seems like you'd get people trying:


import function MyFunction(int first, optional int second = 2);


And complaining when it doesn't work. (And trust me, that would happen...)
Title: Re: optional float parameter
Post by: Monsieur OUXX on Wed 25/07/2007 13:51:21
Quote from: Ashen on Wed 25/07/2007 11:40:09
I think giving it it's own entry would be confusing

I'm not following you. Since it's a keyword, it should have its own entry, just like :

Also, all these keywords are not listed and should be added  (you don't find them easily when you're looking for them - they don't even appear in the index!)

Quote from: Ashen on Wed 25/07/2007 11:40:09
So, having optional parameters explaned in the function, or possibly import, entry makes more sense to me.

We are talking about 2 different things : adding these keywords to the keywords list is essential, so that the reader at least knows that they exist.
Then, the place where their meaning/use get explained can be somewhere else, in the appropriate article (just put a "see also" link?)
Title: Re: optional float parameter
Post by: Ashen on Wed 25/07/2007 14:31:36
No, I see where you're coming from, I just disagree with you :) and was trying to explain why I think the manual is as it is.

I don't see optional as a keyword in the same way as function, while, struct etc (it's not actually used anywhere, it just helps clarify things in the autocomplete), so I don't think it needs it's own entry. Even if it was used in script, I'd still think it made more sense grouped with how/where it's actually done (as it currently is). There aren't seperate entries on that list for int, String, etc - they're grouped under 'Data types'. Similarly the Operators - which the coder would actually use, unlike the optional keyword - are grouped together.

As for static, attribute, etc I think they're 'hidden' for much the same reason - they'd cause more confusion that they'd solve. Making them 'official' might cause some people to use them when they shouldn't, leading to easily avoided problems like the one in my last post.
I have to admit though, I don't entirely know what they do and the manual isn't much help. While a decent rule of thumb is 'If you don't know what it's for, don't use it', it'd be nice if they were explained in more detail but clearly marked 'For Advanced Users Only', like the bitwise operators.

However, this is the wrong forum to discuss changes to the manual ... I'm not actually sure what's the RIGHT forum, but this isn't it. I'll kick it over to Tech Questions - you're more likely to get a workaround for the initial problem if there is one, and CJ can look over the rest.
Title: Re: optional float parameter
Post by: Monsieur OUXX on Wed 25/07/2007 14:41:13
Quote from: Ashen on Wed 25/07/2007 14:31:36
I don't see optional as a keyword, since it just helps clarify things in the autocomplete

???

Anyway. Thanks!
Title: Re: optional float parameter
Post by: Khris on Wed 25/07/2007 14:56:49
"optional" is no keyword at all, it isn't used in scripts, and it's not a part of the language.
It is the adjective used by CJ to describe a part of the functionality of the function keyword.
Why would it be listed in the keywords section? That doesn't make any sense. At all.

And finding the sentence about how only ints can be used as optional parameters isn't that hard.
Where do you learn about the possibility of including optional parameters in the first place? In the manual's section about custom functions, right below "Optional parameters".
What's the first sentence of that paragraph? Oh.
Title: Re: optional float parameter
Post by: GarageGothic on Wed 25/07/2007 14:57:05
Considering the discussion of changes to the manual, maybe this would be a good place to repeat something I wrote in another thread (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=31201.0) but never got a reply to:

Quote from: GarageGothic on Thu 10/05/2007 11:09:05is there any chance that one of you scripting wizards might write a brief introduction to these undocumented commands [referring to static, void, protected etc.] and their uses? (or if one exists, please direct me to it). I've previously studied some books on other programming languages (Java and C#, I think) in an attempt to grasp it, but their example scripts were so different from AGS script that it wasn't very helpful.

(and wow, this thread gave me two new undocumented commands I'd never heard about - private and attribute)
Title: Re: optional float parameter
Post by: Monsieur OUXX on Wed 25/07/2007 15:10:31
Quote from: KhrisMUC on Wed 25/07/2007 14:56:49
"optional" is no keyword at all, it isn't used in scripts, and it's not a part of the language

Oh!
Oh my god.

I apologize to you and to Ashen : I don't know why, i was seeing myself writing the word "optional" i my code - I was absolutely convinced that I was using it as a keyword, so i didn't understand why Ashen kept saying that it wasn't one.

Sorry.

But don't think you've finished with my stupid questions, there's a new one coming in less than one minute - and it's a very tricky one ;) (to be continued)
Title: Re: optional float parameter
Post by: monkey0506 on Wed 25/07/2007 20:59:15
Quote from: GarageGothic on Wed 25/07/2007 14:57:05
Considering the discussion of changes to the manual, maybe this would be a good place to repeat something I wrote in another thread (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=31201.0) but never got a reply to:

Quote from: GarageGothic on Thu 10/05/2007 11:09:05is there any chance that one of you scripting wizards might write a brief introduction to these undocumented commands [referring to static, void, protected etc.] and their uses? (or if one exists, please direct me to it). I've previously studied some books on other programming languages (Java and C#, I think) in an attempt to grasp it, but their example scripts were so different from AGS script that it wasn't very helpful.

(and wow, this thread gave me two new undocumented commands I'd never heard about - private and attribute)

static: This keyword refers to a data member or function of a struct that is not called on an instance of a struct, but rather, directly from the struct itself. In the case of data members, only one instance of this member is created no matter how many instances of the struct are implemented.

struct MyStruct {
  writeprotected int Var; // writeprotected: The user can only read this variable; attempting to modify its value will result in an error. Its value is set by member functions of this struct. See also 'protected'.
  import function SetVar(int value);
  writeprotected static int StaticVar; // won't actually compile (yet), consider using an attribute
  import static function SetStaticVar(int value);
  }

function MyStruct::SetVar(int value) {
  if (value < 0) return;
  this.Var = value;
  }

static function MyStruct::SetStaticVar(int value) {
  if (value < 0) return;
  MyStruct.StaticVar = value; // since there is no instance of the struct, there is no "this" keyword within static functions
  }

MyStruct MyStructInstance;

// game_start
MyStructInstance.SetVar(18);
Display("Var: %d", MyStructInstance.Var);
MyStruct.SetStaticVar(409);                            // note the static function and member
Display("StaticVar: %d", MyStruct.StaticVar); // are called on the struct, not an instance


void: This is a special keyword used only as the return type of a function that returns nothing. These functions are intended simply to carry out a task; no result is returned from the function whatsoever.

void myfunc(int var) {
  if (var < -1093) return; // the return keyword is used by itself to return manually from a function with a void return type as nothing is being returned
  // do stuff
  }


protected: This keyword refers to a data member or member function of a struct that can only be accessed within another member function of the same struct.

struct MyStruct {
  protected int __data__;
  protected import void set_data(int value);
  import void do_something(int value);
  };

protected void MyStruct::set_data(int value) {
  // this function is non-essential, the data could be set directly from the do_something function, this is just an example
  this.__data__ = value;
  }

void MyStruct::do_something(int value) {
  if (value < 0) return;
  this.set_data(value);
  }

// game_start
MyStruct msInstance;
msInstance.do_something(83); // sets the data
msInstance.__data__ = 97; // crashes; data is protected; no read/write access outside of member functions
msInstance.set_data(111); // crashes; function is protected; no access outside of member functions


Regarding the use of static and protected together:

struct MyStruct {
  protected import static int ReturnFive();
  import int GetValue();
  import static int GetItStatically();
  };

protected static int MyStruct::ReturnFive() {
  return 5;
  }

int MyStruct::GetValue() {
  return this.ReturnFive(); // protected members/functions can only be accessed using the 'this' keyword. Although the function is static, it is still possible to access it through an instance
  }

static int MyStruct::GetItStatically() {
  // return MyStruct.ReturnFive(); // crashes; cannot access protected function unless using 'this' keyword which doesn't exist within static function
  // in other words, protected static functions/members are ONLY accessible through a non-static function of the same struct using the 'this' keyword
  }


Regarding writeprotected: This keyword works essentially the same as the protected keyword, except the user is given read access (no write access) to the data member. This keyword applies only to data members. To set a writeprotected member, you must use the same rules as when using protected: You can only modify its value within a non-static function of the same struct, using the this keyword.

private: This is NOT an AGS keyword. It is used in other scripting languages such as C++. See protected instead.

attribute: This is not an officially supported keyword. It is used internally for use with the managed types. It is possible for them to be used for a few purposes, however as its use is not supported, there is no guarantee that your scripts will continue to work with future versions of AGS. Due to ...well...more my lack of interest with this post at this point than anything else really... the advance nature of attributes, I'll withhold an example for now.

Edit: (20 Jan. 2010) Well it only took me 2 1/2 years, but I finally got around to writing up an article on the attribute (http://www.americangirlscouts.org/agswiki/Keyword:_attribute) keyword. Again, it's still not officially supported, but in case anybody's reading this...well...there you go. :)
Title: Re: optional float parameter
Post by: GarageGothic on Wed 25/07/2007 21:49:16
Thank you, thank you, thank you, monkey!!! I'll immediately save this thread to my "AGS help" folder.
All those keywords make perfect sense now. What I discovered from your examples though, is that I don't really get how the declaration and importing of functions into structs work (mainly because I never used it before).

When I remove the lines you said won't compile and try:

struct MyStruct {
  import function SetVar(int value);
  import static function SetStaticVar(int value);
  };


function MyStruct::SetVar(int value) {
  if (value < 0) return;
  this.Var = value;
  }

static function MyStruct::SetStaticVar(int value) {
  if (value < 0) return;
  MyStruct.StaticVar = value;
  }


I get the error message:

QuoteError (line 166): Variable 'MyStruct::SetVar' is already imported

(line 166 is "function MyStruct::SetVar(int value) {")

What am I doing wrong?
Title: Re: optional float parameter
Post by: monkey0506 on Wed 25/07/2007 21:58:19
You need to leave the instance-specific variable there and remove the static function (or rewrite it because it internally sets the static variable which doesn't exist).

struct MyStruct {
  writeprotected int Var;
  import function SetVar(int value);
  };

function MyStruct::SetVar(int value) {
  if (value < 0) return;
  this.Var = value;
  }


I don't see why it would be throwing that error message though. Try putting the struct into the script header, and the function definition in the main script. It shouldn't make a difference, but if you still get the error you can try that instead. BTW, where are you putting this script at? Just as with regular functions, you shouldn't put the function definition into a header, just the import (inside of the struct in this case).

Oh, and you're welcome. ;)
Title: Re: optional float parameter
Post by: GarageGothic on Wed 25/07/2007 22:13:14
Ah, it seems the problem was that I tried to do both the struct and function declaration in a room script. Apparently the struct either has to be declared in the header or as part of the global script or a module.
Title: Re: optional float parameter
Post by: TheMagician on Wed 25/07/2007 23:07:48
Thank you monkey for your tutorial on these keywords.
I never knew what they were for and now I think I can use them if I ever need to in some advanced script.