Call Memberfunction in rep_execute?

Started by Rocco, Fri 08/08/2008 12:21:14

Previous topic - Next topic

Rocco

I have a struct, for a certain game task.
One functionality should be, that you can start a timer to initate an action periodicly.

But to see if the timer is expired, i need to check in the rep_execute, and when the timer is off i need to call the memberfunction.
Unfortunatly i can't call a memberfunction like this
this.SomeAction();
in the rep_execute

How can i solve this problem?





Mazoliin

This might, or might not work.

When you sheck if the timer is expired, aslo check if a bool is false, if it is, call the function and then set the bool to true.

Khris

#2
Either
a) export/import the struct in the module's header

or (way better)
b) put a repeatedly_execute inside the module script.
If AGS finds one, it gets called.

This way you won't have to add stuff to the global script, nor must the user of the module.

The list of all functions is here.

Rocco

thx, i have the rep_execute allready in the module script,
but it seems in the rep_execute (no matter if in the global or modul) AGS don't accepts the this-pointer.

but i cant see another way around, except  i generate an object in advance, and work with this object,
no matter if its needed in the game or not.

SSH

But how should AGS know what "this" refers to?

Try this:

Code: ags

struct my_struct {
  import function do_stuff();
}

my_struct inst_name;

function repeatedly_execute() {
  inst_name.do_stuff();
}

12

Rocco

#5
Quote from: Mazoliin on Fri 08/08/2008 12:36:52
This might, or might not work.

When you sheck if the timer is expired, aslo check if a bool is false, if it is, call the function and then set the bool to true.

this is not the problem, the problem is i cant call the function within the rep_execute.
the only way memberfunctions can called is within other memberfunctions.
Or with an specified object, but i dont know this object at this time, cause it can be generated by the developer somewhere in the game.
So the developer can write somewhere in the game.

GameTimeCalender myCalender;
myCalender.Increase();

but i want to implement the functionality,
that you can set an intervall at the beginning,
and then the Increase function must be called, when the timer_is_expired.

SSH: I know this alternative, but want to avoid it, if its possible,
because then i have to generate an object and set a date on suspicion in advance.

SSH

So, you want to be able to generate objects outside of your module but for your module to know about them? That's not possible. You'll need to make the repeatedly_execute function in the same place that you declare the object.

However, if your module implements a game time calendar I can't see why anyone would want more than 1, so what's the harm in putting the declaration in your module? If they don't want it at all, they can just remove the module.
12

Khris

Wouldn't this work:

Code: ags
GameTimeCalendar temp;  // temporary pointer

function GameTimeCalendar::Increase() {
  ...
  SetTimer(x, y);
  temp = this;
}

function repeatedly_execute() {
  if (IsTimerExpired(x)) {
    temp.Whatever();
  }
}

SSH

No, it wouldn't. You'd need to declare temp as a pointer which you can't do to user-defined structs.
12

Rocco

you are right, i will declare the object within the module, thx for all the help.  :)


Rocco

Another problem:

I have an defined object now:

Code: ags
GameTimeCalender myCalender;


but when im calling this function:
Code: ags
myCalender.Increase();


with declaration
Code: ags

GameTimeCalender::Increase()
{
  this.day++;
  ...
}

the myCalender.day hasnt changed   :(

Khris

The problem seems to be something else, because this should definitely be working.

I tried:
Code: ags
// new module script

GameTimeCalendar myCalendar;

function GameTimeCalendar::Increase() {
  this.day++;
}

function on_key_press(int k) {
  if (k == 'C') {
    Display("%d", myCalendar.day);
    myCalendar.Increase();
    Display("%d", myCalendar.day);
  }
}

Worked fine.

Rocco

Well its an unbelivable engima.
The function works when i call it per Hand, or with your method - works perfect.

But if it is called automaticlly in the rep_execute, it doesnt increase the var.
And the function is called for sure, i verified this.
I dont understand it.

Code: ags

function repeatedly_execute() {
  // put anything you want to happen every game cycle here
    if( calender.timer_activ )
    {    	 
      if(IsTimerExpired(calender.used_timer))
	    {
 	       calender.Increase();
 	       Display("TIMER IS EXPIRED");
 	       SetTimer(calender.used_timer, calender.timer_intervall);
      }  

    }
} 





SSH

Are you checking that timer anywhere else, as IsTimerExpired only ever returns true once.

Much better to code your own timer by setting a variable and decrementing it every cycle,
12

Rocco

But the Timer works without problems, and also the Increase function is called when it should be.
The only problem is, that it not really increase the value when its called this way, that is the mysterium.

monkey0506

#15
Just for future reference, if you did need to call a function on user-defined instances of your struct you could create an Update method and tell the user they must call Update within rep_ex[_always] or your module won't work:

Code: ags
struct GameTimeCalendar {
  // ...
  int timer;
  import void Update();
};

void GameTimeCalendar::Update() {
  if (this.timer_activ) {
    if (!this.timer) {
      this.Increase();
      this.timer = this.timer_intervall;
    }
  }
}


Quote from: Your manual/readme/documentationNOTE: You *MUST* call the Update method for your instances of this struct or they will *NOT* be updated.

It's not as user-friendly as managed instances, but if you ever wanted to do something like this...

Edit: Fixed "timer" instead of "this.timer"

Rocco

i dont get the clou about this.

what is the difference between the function, when its called from room-script ->       this.Increase();
and works as it should be, or the same function is called from the rep_execute every here and there and dont works.  ???

also the update function won't work - or better to say, the commands they are in there ->  this.Increase();
is also called in the update function but doesnt change the value.  :(

Its the first time, that i try to make a module in object oriented manner, all went really good, major functions worked perfect,
and in the end - the only thing is to implement the timer function,
at this point things run out of control, and now i'm contemplating suizide.  :P



Pumaman

Are you sure it's actually the same instance that you're using in both places?

If your module declares this:
GameTimeCalender myCalender;

and increments it in repeatedly_execute; but then your main script code declares its own GameTimeCalendar then that one would not get incremented.

The easiest solution is, as monkey_05_06, to simply tell the user of the module that they need to call the Update method in their repeatedly_execute.

Rocco

I have only one instance in the whole game (script).
in the complete room_script this function works (also in the Room_rep_Execute) - calender.Increase();
in the modul rep_exe... it want.
it is also called and running (there is no errormessage, i can see a display message within, but the var wont increase);

the update function dont work neither, (is the update function a special function within structs? if yes, is there a detailed description about it?)

i have the rep_exec in the module, so there is no need when the thing is working, that the user must call it byhimself, or?

SSH

Try putting a breakpoint inside the rep_ex function and then step into the Increase method to see whats happening.
12

SMF spam blocked by CleanTalk