pawn-lang / YSI-Includes

Just the YSI include files, none of the extra stuff.
209 stars 106 forks source link

Call a callback to y_hook from the script? #126

Closed rt-2 closed 7 years ago

rt-2 commented 7 years ago

Hi, Sorry if it has already been answered, I did some research but did not find anything. The tutorial is incredibly short and states that you simply have to replace one line. I did that for a lot of scripts and it helped me A LOT so far and worked perfectly. But lately I have come across an old code and it didn't worked so well.

Before: public OnPlayerLeaveDynamicCP(playerid, checkpointid) return OnPlayerEnterDynamicCP(playerid, checkpointid); public OnPlayerEnterDynamicCP(playerid, checkpointid) { //some codes return 1; } Worked fine, but now this code: hook OnPlayerLeaveDynamicCP(playerid, checkpointid) return OnPlayerEnterDynamicCP(playerid, checkpointid); hook OnPlayerEnterDynamicCP(playerid, checkpointid) { //some codes return 1; } Returns: error 004: function "OnPlayerEnterDynamicCP" is not implemented On the first line.

Since I din't find any information from googling the samp forum, I thought it was better to ask what was the real stable correct solution instead of just trying to find something that seems to work. Since I didn't find any real thread for y_hook I am posting here.

Thank you very much for all this, rt-2

Crayder commented 7 years ago

The functions have different names.

Like... Dynamic is Dyn and more. Try changing Dynamic to Dyn.

Other hook name replacements:

DEFINE_HOOK_REPLACEMENT(Checkpoint, CP ); DEFINE_HOOK_REPLACEMENT(Container , Cnt); DEFINE_HOOK_REPLACEMENT(Inventory , Inv); DEFINE_HOOK_REPLACEMENT(Dynamic , Dyn); DEFINE_HOOK_REPLACEMENT(TextDraw , TD ); DEFINE_HOOK_REPLACEMENT(Update , Upd); DEFINE_HOOK_REPLACEMENT(Object , Obj); DEFINE_HOOK_REPLACEMENT(Command , Cmd); DEFINE_HOOK_REPLACEMENT(DynamicCP , DynamicCP);

rt-2 commented 7 years ago

Thank you for your help.

But doesn't those 2 contradict?:

DEFINE_HOOK_REPLACEMENT(Dynamic , Dyn); DEFINE_HOOK_REPLACEMENT(DynamicCP , DynamicCP);

Crayder commented 7 years ago

Actually I think DEFINE_HOOK_REPLACEMENT(DynamicCP , DynamicCP); was an attempt to fix your issue. Do you have the latest YSI files? If you do, then this attempt failed. If you don't download them now and see if it works.

rt-2 commented 7 years ago

I just downloaded all this repository and copied the includes into pawno/includes, try recompiling, same error.

Crayder commented 7 years ago

Did you try this already? Try changing Dynamic to Dyn.

rt-2 commented 7 years ago

Yes, and itnerestingly, I got this different error instead: error 017: undefined symbol "OnPlayerEnterDynCP"

Y-Less commented 7 years ago

y_hooks renames all the callbacks with special patterns that it can detect - this is how it generates the code to chain them all together. You are trying to call OnPlayerEnterDynamicCP directly, but it has been silently renamed. There are three solutions.

The old method (which was always really the correct way of calling publics):

CallLocalFunction("OnPlayerEnterDynamicCP", "ii", playerid, checkpointid);

The slight variation if you have filterscripts as well:

CallRemoteFunction("OnPlayerEnterDynamicCP", "ii", playerid, checkpointid);

And because YSI did the renaming in the first place, there is a native work-around (but it only works for some callbacks, maybe not this one), which has compile-time parameter checking as well:

call OnPlayerEnterDynamicCP(playerid, checkpointid);
Crayder commented 7 years ago

Ah, I was actually under the impression that defining the hook was causing this error. I didn't notice the return OnPlayerEnterDynamicCP.

rt-2 commented 7 years ago

I would love to use call OnPlayerEnterDynamicCP(playerid, checkpointid); What is the reason it doesn't work on some callbacks? Is it a bug, or is it intentional? Is there a way to know which?

Also, you are telling me that return OnPlayerEnterDynamicCP(playerid, checkpointid); never really was correct in the first place?

I will use CallRemoteFunction or CallLocalFunction if I am sure that it is in the same script I guess.

Thank you, rt-2

Y-Less commented 7 years ago

It wouldn't work because that uses special macros to determine the function parameters:

https://github.com/Misiur/YSI-Includes/blob/4aa0975eef265038220435c367b520a6319a3eae/YSI_Core/y_als/impl.inc#L189-L272

However, it turns out I already did them for the streamer plugin.

rt-2 commented 7 years ago

Sorry I don't understand your answer. Do you mean that call will work safely with any functions? Or only the function included in your link?

Thank you again for your help! rt-2

Y-Less commented 7 years ago

It means that it only works for certain callbacks that it has been pre-defined for. However, the streamer plugin callbacks are in that list, so yes you can use it here.

rt-2 commented 7 years ago

Thank you very much Y-Less for this and for all your work on SAMP. One last question, does call execute the function instantly like return would do, or is it more of a CallLocalFunction type of result? (to me it seems CallLocalFunction almost works like a 10-100ms timer. Thank you, rt-2

Y-Less commented 7 years ago

It uses CallLocalFunction, but that isn't a timer - it calls it instantly:

public f()
{
    print("a")
}

main()
{
    print("1")
    SetTimer("f", 0, 0);
    print("2")
}

Output:

1
2
a
public f()
{
    print("a")
}

main()
{
    print("1")
    CallLocalFunction("f", "");
    print("2")
}

Output:

1
a
2
Y-Less commented 7 years ago
public f()
{
    print("a")
}

main()
{
    print("1")
    SetTimer("f", 1000, 0);
    print("2")
}

Output:

1
2
<possibly a lot of other irrelevant stuff>
a
rt-2 commented 7 years ago

One last question. When using CallRemoteFunction, does it also "pause the execution", looks into every scripts for instances of function asked, THEN continue in the current first function? Thank you very much for your help.

Y-Less commented 7 years ago

No - calling other code is by definition doing something. Nothing gets paused.

rt-2 commented 7 years ago

Yes I know, it was under quotes. I just meant that it still got to "wait" some ms because with CallRemoteFunction, it must check into every scripts to see if the function is available. that's what I meant by "pause", because sometimes those other function may take some time to execute. Thank you for your help sir!