Skip to content

Function as argument #2942

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 31 commits into
base: master
Choose a base branch
from

Conversation

MobinYengejehi
Copy link

@MobinYengejehi MobinYengejehi commented Apr 3, 2023

hi guys
i could made a method that help lua to pass a function as argument and send it to other resources
and you can use it in both server and client sides
you can pass function as argument in triggerEvent or exports.resource:func_name or setElementData(if you set 4th argument to false) and send it to another resource and call it
and also you can send functions in table (but you can't share metamethods)
for example:

-- resource : A
local player = nil;

local library = {};

function library.SetPlayer(element)
    if isElement(element) then
        player = element;
    end
end

function library.GetPlayer()
    return player;
end

addEvent("getlibrary", false);
addEventHandler("getlibrary", localPlayer, function(send)
    iprint("function is:", send, type(send)); -- type(send) = table
    send(library);
    print("library sent to ", getResourceName(send.resource));
    send:free(); -- cleanup function reference at resource B (this cleans up the memory. if you don't call this method it stays in memory untill program destroy lua stack like stopping resource)
end);
-- resource : B
local library;

triggerEvent("getlibrary", getLocalPlayer(), function(resourceALibrary)
    library = resourceALibrary;
    print("resource B got the library!");
end);

if library then
    print("player is : ", library.GetPlayer()); -- nil
    library.SetPlayer(getLocalPlayer());
    print("player is : ", library.GetPlayer()); -- local player
end

when you pass a function as an argument it will look like a table
and has these values:
-- function reference:
.resource : the resource that owns function
.reference : the reference id
.free : this method deletes the reference. if you call it, means that you won't be able to use that function anymore

note 1 : you can store a function reference in other resource if you want to let it be active otherwise if you call that function in render event or sth like that and you don't use :free method, after seconds your game or server console crashs because it occupies your memory
note 2 : remember when you want to cleanup your function call it as method, like function:free (not like function.free) because free needs a callable value as first argument

add function type to read and write method
define static `CallFunction` method and `CleanupFunction` method
define methods
define methods
define methods
@lopezloo lopezloo added the enhancement New feature or request label Apr 4, 2023
@CrosRoad95
Copy link

couldn't you just implicit convert functions to refs using ref and deref

@MobinYengejehi
Copy link
Author

couldn't you just implicit convert functions to refs using ref and deref

i think i couldn't understand well what you mean
but if you mean why those are table
its because it doesn't cause confusion when passing a function as an argument in triggerEvent and other functions and you can check in other resources that where does this function come from

@salwador
Copy link

No news about this PR? I can't imagine a cases for what need store functions in elementData, but for exports it very useful. 🤔

@Fernando-A-Rocha
Copy link
Contributor

This reminds me of #3551

{
lua_newtable(luaVM); // create callable

lua_pushresource(luaVM, m_pResource); // push function inside callable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a referenced resource become stopped this pointer will turn into the dangling one. From what I was able to see there is no an invalidation mechanism for functions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have some cleaner and better version in my mind for this
i will work on it and update its PR to use that instead

@tederis
Copy link
Member

tederis commented May 31, 2025

I consider this feature as excessive and the implementation as dangerous.

@MobinYengejehi
Copy link
Author

i need time to refactor this PR

@MegadreamsBE
Copy link
Member

I'm opposed to this. There's no good reason for this to exist, it can be dangerous AND it can cause easy memory leaks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants