JeViCo Posted November 6, 2018 Share Posted November 6, 2018 (edited) Hello everyone :3 I tried to make my own dx-gui system. I separate functions into several .lua files (i have a window and a button) So i used this to destroy elements in 3-rd file addEventHandler("onClientElementDestroy",root,function() if getElementData(source,"dxcore") == true then triggerEvent("destroy-"..getElementType(source),localPlayer,getElementData(source,"variable-data")) end end) -- getElementData(source,"variable-data") returns table (all info about this dx element in metatable) 1-st file: function JVbutton:destroy() -- remove stuff (button) end addEvent("destroy-dx-button",true) addEventHandler("destroy-dx-button",root,function(data) data:destroy() end) 2-nd file function JVwindow:destroy() -- remove stuff (window) end addEvent("destroy-dx-window",true) addEventHandler("destroy-dx-window",root,function(data) data:destroy() end) but i keep getting same errors: ( attempt to call method 'destroy' a nil value) What am i doing wrong? Edited November 6, 2018 by JeViCo Link to comment
Moderators IIYAMA Posted November 7, 2018 Moderators Share Posted November 7, 2018 (edited) Ever seen a meta table as they are created? A meta table is used to change the behaviour of a regular table. The main issue is with the fact that it uses functions to achieve this behaviour. And functions... Optional Arguments NOTE: When using optional arguments, you might need to supply all arguments before the one you wish to use. For more information on optional arguments, see optional arguments. sendTo: The event will be sent to all players that are children of the specified element. By default this is the root element, and hence the event is sent to all players. If you specify a single player it will just be sent to that player. This argument can also be a table of player elements. arguments...: A list of arguments to trigger with the event. You can pass any lua data type (except functions). You can also pass elements. https://wiki.multitheftauto.com/wiki/TriggerClientEvent ...can't be send over according to wiki. But even if this is a meta table, you will have the same problem with a regular table. This has probably happend: all the functions that are inside of the table are deleted. Edited November 7, 2018 by IIYAMA 1 Link to comment
JeViCo Posted November 9, 2018 Author Share Posted November 9, 2018 On 07/11/2018 at 19:17, IIYAMA said: This has probably happend: all the functions that are inside of the table are deleted. I checked my code and that's true - all data saved except for functions i'll try to rewrite functions using elements only and connect them with metatables with elementData 1 Link to comment
JeViCo Posted November 11, 2018 Author Share Posted November 11, 2018 @IIYAMA same problem idk why 1-st lua file function destroyDX(element) local dx_type = getElementType(element) if dx_type == "dx-window" then JVwindow.destroy(source) elseif dx_type == "dx-button" then end end addEventHandler("onClientElementDestroy",root,function() if getElementData(source,"dxcore") == true then cancelEvent() destroyDX(source) end end) 2-nd lua file function JVwindow.destroy(element) local dat = getElementData(element, "variable-data") if #dat.main.related_elements > 0 then for _, el in ipairs(dat.main.related_elements) do destroyElement(el) end end removeEventHandler("onClientRender", root, dat.handlers.render) setmetatable(dat, nil) destroyElement(element) end errors: I thought cancelEvent() didn't work but nope print(element) returns userdata so element exists Link to comment
Moderators IIYAMA Posted November 11, 2018 Moderators Share Posted November 11, 2018 Image not working. @JeViCo Link to comment
JeViCo Posted November 11, 2018 Author Share Posted November 11, 2018 4 minutes ago, IIYAMA said: Image not working. What do you mean? It removed function once and spams now or what? Link to comment
Moderators IIYAMA Posted November 11, 2018 Moderators Share Posted November 11, 2018 (edited) 1 minute ago, JeViCo said: What do you mean? It removed function once and spams now or what? No, I do not see the errors you have. (in console) https://wiki.multitheftauto.com/wiki/OnClientElementDestroy is not cancel able. Edited November 11, 2018 by IIYAMA Link to comment
JeViCo Posted December 15, 2018 Author Share Posted December 15, 2018 @IIYAMA i returned :3 i figured everything out except for one: i use onClientRender event to draw DX window like that wnd.handlers.render = function() wnd:renderWindow() end addEventHandler("onClientRender", element, wnd.handlers.render) setElementData(element,"variable-data",wnd) but i can't do this because all functions disappear local dat = getElementData(source, "variable-data") removeEventHandler("onClientRender", root, dat.handlers.render) i don't know how to save them. Maybe i should not use elementData Link to comment
JeViCo Posted December 15, 2018 Author Share Posted December 15, 2018 sorry for bothering you :с i solved this problem by using an additional table Link to comment
JeViCo Posted December 15, 2018 Author Share Posted December 15, 2018 now i have another problem :c elements don't want to destroy. I use destroyElement(window) then onClientElementDestroy triggers where i do some magic stuff and that's all. window variable is still userdata so element still exists or something wrong with my code Link to comment
Moderators IIYAMA Posted December 15, 2018 Moderators Share Posted December 15, 2018 (edited) 33 minutes ago, JeViCo said: now i have another problem :c elements don't want to destroy. I use destroyElement(window) then onClientElementDestroy triggers where i do some magic stuff and that's all. window variable is still userdata so element still exists or something wrong with my code After you destroyed an element. A saved userdata reference will remain inside of the Lua memory. A userdata reference is not an element itself. It is a value that can be used to refer to an element in MTA. ------ It is like having a cat which you named `miauw`. After it died of old age, you can still refer to your precious cat by calling it's name. `miauw` I have dinner for you! (calling function: giveCatFoot(cat)) And then your grandma reminds you of the fact that it has already died... (warning: element does not exist) ------- That is sort of how userdata references work. See function isElement for userdata validation. isElement Edited December 15, 2018 by IIYAMA 1 1 Link to comment
JeViCo Posted December 15, 2018 Author Share Posted December 15, 2018 thank you for your support i had some problems with my code. Now everything works amazing 1 Link to comment
Discord Moderators Pirulax Posted December 17, 2018 Discord Moderators Share Posted December 17, 2018 For the sake of god, dont use element data If possible avoid it, it's slow af.(indexing is 30x times faster if I recall correctly) Link to comment
Moderators IIYAMA Posted December 18, 2018 Moderators Share Posted December 18, 2018 7 hours ago, Pirulax said: For the sake of god, dont use element data If possible avoid it, it's slow af.(indexing is 30x times faster if I recall correctly) That really depends how you compare and use it. 1 on 1, sure it can be 30x faster. But aren't you comparing two different things? A function vs just an empty variable. If you take a look at dxDraw functions, it is obvious that they are being called every frame. Incompare to call getElementData there isn't much of a difference. The data is bound to the element, it is not like you have to search in all elementdata for it. Example: You use 60 dx functions each frame and 1 time a getElementData function. How much will we gain from optimize this function? The real danger of elementdata is in using it, without knowing what mechanisms are activated behind it, after it is SET. Link to comment
Discord Moderators Pirulax Posted December 19, 2018 Discord Moderators Share Posted December 19, 2018 Well, setting takes way more time than getting it, just because the :~ty way its implemented in. for some reason everything is in CStaticFunctionDefinitions.cpp, even those things which are CLASS specific, for example, when you set an element data a new value, you'd expect that the CCustomData class should send a packet to the client to request them to refresh their data, but... NO, it doesn't. And that's not a big of a deal, at all.. But, take a look at the way setElementData is implemented... Link to comment
Captain Cody Posted December 19, 2018 Share Posted December 19, 2018 (edited) Element data is not that bad when used properly; for a beginner when used with caution element data is just fine. That being said; in the future it's better to make your own element data system to improve performance when systems needing element data start growing. Edited December 19, 2018 by CodyJ(L) Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now