October 25th, 2012, 09:18 PM
Questions About Delphi (solved)
Edit. These issues have been solved.
I have recently started programming again after a long hiatus, in particular making a game or 2 but I have some questions that need answering.
1. Should I always use variables for checkboxes/radio butons in the main game loop? Or is there no speed difference referencing the actual object state? For example:
if Speed_Checkbox.checked then
Is there any difference in a game. My object is also on a different form (a setup form). Normally I would not think this could matter but my game loop is 60cycles a second which means it has to access the state 60 times a second.
compared to if Speed=true then
Why am I asking this? Because I want to save time in not having to make a variable for the ton of option checkboxes.
2. I made a dll for Final Fantasy VIII PC recently (dll is injected via loader). I created a thread for the new form that the user could display with hotkey. The problem was I wanted to use form.show; and when I did that the form flashed on and off, it would not stay on screen. Only when I used showmodal would the form stay. Is there any reason why this is?
procedure funcStart( appHandle: HWND ); stdcall; begin Form1 := tForm1.Create(nil); Form1.show; end;
I will probably have some more questions soon. Any help appreciated.
October 25th, 2012, 10:29 PM
Its hard to imagine that there would be a noticeable difference.
Surely you can just write a little test loop of a million iterations or so and time them both.
An equally relevant question, if you have lots of them, would be:
why are you not creating some sort of TGameStatus class
that holds all these values and divorces your status from any GUI objects and can be referenced from any form (you seem to have more than one).
One thing that is invariably bad design is accessing a UI object on one form directly from another form.
Reference your flashing form. From what you posted, it looks as if your thread completes
after form1.show. If that is true, then the form will die immediately possibly leaving you with a little memory leak.
form1.showmodal will stay visible because the thread can not complete until you close the form.
Last edited by clivew; October 25th, 2012 at 10:31 PM.
Reason: Grammar improvements
October 25th, 2012, 11:14 PM
Thank you for the reply. On the flashing issue, what you are saying is, the thread I create is not able to stay with form1.show because it cannot keep the thread open.
In that case, how would I go about keeping the thread open with a show (or anything else) as opposed to showmodal?
October 26th, 2012, 12:11 AM
Why do you need separate thread for showing the form? And what Delphi version are you using?
Regarding the speed between accessing CheckBox.Checked and directly use boolean variable, the latter will definitely faster. Because Property TCheckBox.Checked actually check the state (enumeration type) of the TCheckBox. However the difference would be negligible in most occasion (including yours, I believe), just a few CPU cycles.
What did you mean by "dies" here? Aside from creating and showing the form, the thread has nothing else to do with the form. So, from where did you conclude that the form dies after thread completion?
Originally Posted by clivew
Last edited by Luthfi; October 26th, 2012 at 12:15 AM.
Reason: Answer the speed "difference"
October 26th, 2012, 12:28 AM
The separate thread has bass.dll loaded for music (I programmed ogg music into ff8 pc which was originally midi). If bass is initalised and used on the same thread as FF8, the game crashes.
I take it radio button is exactly the same as checkbox? Nevertheless if it is only a minor speed reduction it is fine.
I am using d7.
October 26th, 2012, 12:48 AM
Normally manipulating form (or any other GUI related) in separate thread (other than in the main thread) will immediately crash your application, or at least you would get access violation or similar like that. Because some aspects in Delphi VCL related with GUI are not thread-safe.
Originally Posted by DLPB
It is surprising for me if you got Form1 visible using .Show or .ShowModal. But there is one explanation for this (beside you were extremely lucky), i.e. there was no other form or GUI showing beside Form1. This is why the non-thread-safe aspects never gotten modified by several thread at once.
The point is, you should avoid manipulating form through thread other than the main one. If you really can not solve the .dll problem, you still can use separate thread, but call the Form1 creation and display in the main thread. There are many ways to do this.
The easiest I believe is by using TThread class instead of using Windows API CreateThread directly. Because in TThread you have Synchronize method which will execute parameterless method given to it in the main thread.
The best one, because this one will not block the separate thread, is using custom message, then PostMessage this custom message to main thread, and then message handler in the main thread create and show Form1.
October 26th, 2012, 01:05 AM
There are no other forms because the dll is attaching to a Computer game (Final Fantasy VIII). The game doesn't provide forms or boxes..
It is not a delphi made game or made with forms. And my app is itself a dll using another dll.
This person was the one I got the code from:
Do you have an example of how my dll can use TThread to create and show form1?
October 26th, 2012, 01:21 AM
Oh I see. That's different environment than ordinary Delphi application. In this case you don't need to synchronize with main thread, since the main thread is not governed by VCL framework.
What are you trying to display in Form1? Is it just simple message or containing many advance control? If your aim is just to show simple text message, you can get away using Win API MessageBox or MessageBoxEx.
If it turned out that you still have to use Delphi form, then you need to do some initialization and also cleaning up later. See if you can use this article.
October 26th, 2012, 01:27 AM
It displays menu option for sound and various in game hex values, it also has bass.dll attached to it which plays the various musics of the game (i send the music ID to it).
It is much more than an ordinary form. Problem is, it disappears with .show and not with .showmodal.
Also I have already tried what you suggested, the form still disappears. Perhaps it is to do with Final Fantasy VIII itself or how the dll is working with the game?
Also, the form disappears even when totally blank and unused.
October 26th, 2012, 10:57 AM
Because the form is being created inside the thread, so I don't see how a thread local variable can continue after the thread closes.
Am I wrong?
October 27th, 2012, 12:32 AM
On the speed of component vs variable, I did a for loop iteration of 100 million cycles and used timegettime to work out the difference in time between both.
Variable 45 ms
The difference is minor for what I want it for.
In a game running at 60fps there will be no performance hit. My cpu can perform 295,858,000 checks on a checkbox state a second.
and 2,222,222,200 checks a second on a variable.
October 29th, 2012, 12:05 AM
Darkbyte explains it... seems the thread DOES exit with a show.
October 29th, 2012, 12:19 AM
That is what I suggested from the start, and explained further later.
There really is no way for a variable created inside a thread to remain valid once the thread closes.
October 29th, 2012, 03:41 PM
Thing is I thought when you created a thread it stayed created (until you destroyed it...) obviously I had no clue how threads work. Any decent documentation somewhere? Especially with regards to dll.
Originally Posted by clivew
October 29th, 2012, 04:24 PM
Yes; but it hides pretty well.
Put some key words into Google and see what comes up.
Ditto Embarcadero site, although I don't think it works too well.
Regarding DLLs make sure you read up about the messaging loop.
Basically (if I remember correctly) they use the messaging loop of the calling program,
so if it isn't yours there can be some surprises you will need to navigate.
It is too important a subject and I am not certain enough of my facts to go further than the warning.