Jump to content

(solved) Error when passing "context" from PostRender to another function


Mordred
 Share

Recommended Posts

Hello Leadwerkers,

 

i have an issue that i really do not understand. I have made a function that draws basically an image, depending of the mouse position ("hover over Button"). I need to have access to the "current context" within this function, but as soon as i try to get access to the "Context:GetCurrent()" i do get a crash (no errormessage in Leadwerks, just "MyGame.exe has stopped running").

 

I tried it the following ways.

1st: define "context" within the function --> context = Context:GetCurrent() --> results in crash

2nd: define "context" as globa within the whole script --> "context = Context:GetCurrent()" in the first row --> crash

3rd: Passing "context" from the PostRender into the function like: "function menu (context, label, x, y)--> crash.

4th: creating another context named "xcontext = Context:GetCurrent()" to prevent from using the same variable twice --> crash.

 

Now my problem is: Why does the game crash at launch as soon as i try to pass or access the context into or within the function? I do have to pass the context somehow into the function or the "context" within the function will be unknown.

 

For a better understanding here's the script (the error occurs within the "menu" function):

 

Script.player = nil --entity "Player"

function Script:Start()
window = Window:GetCurrent()
local context = Context:GetCurrent()

self.button = Texture:Load("Materials/HUD/Btn_not_pressed.tex")
self.button_pressed = Texture:Load("Materials/HUD/Btn_pressed.tex")

local font = Font:Load("Materials/Fonts/arial.ttf", 20)
context:SetFont(font)
font:Release()
context:Release()
end

function Script:HUD()

end

local menuopen = 0
function Script:PostRender(context)
local windowWidth = window:GetWidth()
local windowHeight = window:GetHeight()

if window:KeyHit(Key.T) then
if menuopen == 0 then
menuopen = 1
else
menuopen = 0
end
end
if menuopen == 1 then
context:Clear()
context:SetColor(1,1,1)
context:SetBlendMode(Blend.Alpha)
end
menu("Start", 9, 7)
context:SetBlendMode(Blend.Solid)
end

function menu(label, x, y)
local mousepos = window:GetMousePosition()
local mx = mousepos.x
local my = mousepos.y

window:ShowMouse()

if mx >= x and my >= y and mx <= x+200 and my <= y+35 then
context:DrawImage(button_pressed, x, y)
context:DrawText(label, x+5, y+3)
else
context:DrawImage(button, x, y)
context:DrawText(label, x+5, y+3)
end
end

 

[Edit]

Found my error, i defined the button variables as "self.button" and tried to access them via "button" since "self.button" didnt work in the funtion. I renamed the variables to plain "button" (instead of self.) and it did work. Yay, the context wasn't the error at all!

Link to comment
Share on other sites

In the script you have in your post, where are you passing context into menu? You aren't. Also note that your menu function is now global the way you set it up. To make a script level function (which is almost 100% what you want in this case) do the following:

 

 

function Script:PostRender(context)
self:Menu(context, lbl, 5, 6) -- note the colon and not period to call functions instead of access variables
end

function Script:Menu(context, label, x, y)
-- now you can use context in here
end

 

This would be what I call the right way to do this. You can also access the global App to get the context via App.context.

 

 

local context = Context:GetCurrent()

 

You must think this is how you can use context in menu without passing it? The keyword local makes it only viewable inside the function it's created in. In your case the variable context is only available in the Start() function.

 

Also note that your window variable is global the way you have it setup too. To make script level variables use self like:

 

self.window = Window:GetCurrentWindow()

 

Now you can use self.window in this entire script.

Link to comment
Share on other sites

And again it's Rick smile.png Thanks for your reply, as mentioned in my edit above the error itself is already found. But thanks for your further suggestions. The context wasn't passed in this special snipplet, since i already had my changes redone.

 

So, if i understand you correctly the "button = Texture:Load...." in the "Script:Start" is global too and should therefore be "self.button"?

Link to comment
Share on other sites

Your script already has self.button (even before your edit), but yes. Just remember this:

 

Inside an entity script 99% of the time you only want to use local if the variable only needs to be used in said function, and use self.variable if it needs to be accessed anywhere in the script. Also make your script function like:

 

function Script:MyFunction()

end

 

And call them like:

 

self:MyFunction()

 

Don't make anything global or you could get some really hard to find bugs that you just can't figure out what is happening because 5 different scripts could be altering the same global variable at different times without you realizing it because it's just too hard to keep track of global variables.

Link to comment
Share on other sites

Hey Rick, thanks again for explaining it,

 

i had feard in the first place that i somewhere did change "context" to get the error, but luckily it was easier than that smile.png.

 

Okay, now in case someone is interested in knowing the result / maybe someone might use this as a hint on how to start, i made a simple script that opens a small menu when hitting "T" within the game, if you hover your mouse over the "start" button it switches to a green colored texture file, if you press the mouse the text shown switches between "Start" and "Hit!". It's far from being finished yet, but maybe it's usefull for some newbies like me smile.png

 

I gonna attach it at this posting.

Basic_Menu.zip

Link to comment
Share on other sites

No problem. A couple notes which aren't major:

 

You have menuopen defined before PostRender outside of any function. The good news with that is you used local so it's local to this script, and you can do it this way, but it's a little inconsistent. If this is a variable needed in this script then it's probably best to define it in Start() with self.menuopen.

 

You already get the window in Start() and assign it to self.window but you do it again in your Menu() and assign it to a local window variable. No need to do it again. Inside Menu just use self.window. It refers to the same window.

Link to comment
Share on other sites

Okay, i did change that too, i gonna edit my previous posting and edit the file too :)

 

Btw. how can i make it so that hitting the "Exit" button actually does close the window from within the function? I cannot use "return false end" (--> just does nothing) and there's no "Window:Close()" function. Or do i have to use "Window:Release()"?

Link to comment
Share on other sites

This is where the App object (which is in App.lua) comes into play. App is a global object and anything defined in it you have access anywhere from your scripts. I wish there were a better way as I dislike globals, but right now that's what we have. So knowing that, and knowing that the only way you can close the application is by returning false in App:Loop(), a good method would be to create a function in App.lua that will set a variable to false and always return that variable from App:Loop(). ie.

 

App.lua

 

function App:Start()
   self.running = true
end

function App:ExitGame()
   self.running = false
end

function App:Loop()
  -- all the other stuff in here

   -- notice we are returning a variable here. it's set to true, but from our script we call the QuitGame function which sets this to false meaning when the world:Update() method that's in here returns back to this function it'll return false because self.running was changed to false by our script. Note all entity scripts are executed from world:Update()
   return self.running
end

 

Your script:

 

function Script:Menu()
   -- if click exit button
   App:ExitGame()
end

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...