optional float parameter

Started by Monsieur OUXX, Tue 24/07/2007 19:08:16

Previous topic - Next topic

Monsieur OUXX

Hi, i don't understand how "float" optional parameters work...

here is my code :

Code: ags

#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.

Code: ags

#define FLOAT_PARAM     -1000

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

 

Khris


Monsieur OUXX

Quote from: KhrisMUC on Tue 24/07/2007 20:17:14
Try "-1000.0"

Caught not reading what was written! :)
Please read again!
 

Khris

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.

monkey0506

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?

Gilbert

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), this may render it impossible to have optional float parameters.

Monsieur OUXX

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).


 

Ashen

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:

Code: ags

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


And complaining when it doesn't work. (And trust me, that would happen...)
I know what you're thinking ... Don't think that.

Monsieur OUXX

#8
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 :

  • Arrays
    Data types
    Operators
    Constants
    Version checking
    if, else statements
    while
    function
    struct
    enum
    import
    export
    noloopcheck

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!)

  • static
    attribute
    private
    etc.

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?)
 

Ashen

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.
I know what you're thinking ... Don't think that.

Monsieur OUXX

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!
 

Khris

"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.

GarageGothic

Considering the discussion of changes to the manual, maybe this would be a good place to repeat something I wrote in another thread 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)

Monsieur OUXX

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)
 

monkey0506

#14
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 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.

Code: ags
 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.

Code: ags
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.

Code: ags
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:

Code: ags
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 keyword. Again, it's still not officially supported, but in case anybody's reading this...well...there you go. :)

GarageGothic

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:

Code: ags
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?

monkey0506

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).

Code: ags
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. ;)

GarageGothic

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.

TheMagician

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.

SMF spam blocked by CleanTalk