I´m trying to put a together a small level system for my game. I want a update method that takes care of my game main logic. So I declared a method in my parent class .h file:
Level.h:
-(void)gameLogicTick:(ccTime)dt;
Then I do the implementation in Level.m, don´t think the exact code is relevant.
I created a subclass of Level called Forest. In the Forest init-method I would like to specify the interval of gameLogicTick, I did this:
[self schedule:#selector(gameLogicTick:)interval:5.0f];
This makes my game crash(after 5 seconds) with no debug message what so ever.
So how can I create a schedule update-method where I can specify the interval in the current class?
What you do is ok. Perhaps the Forest object got deallocated (ie because it was never added as child to a parent node for example) and the next time CCScheduler updates the scheduled methods, it will try to run your method on an already released instance.
You should enable the global exception breakpoint in Xcode to get more crash info and the exact line where the crash occurs.
Don't try messing with the parent class gameLogicTick: method. Leave that one to do its thing at full speed. In your Forest.m, simply call
[self schedule:#selector(update:) interval: 5.0f];
then make sure you have the appropriate update:(ccTime) delta in your Forest implementation. Just don't name it the same as your parent class's method and you won't have any problems.
Related
I have a custom table and I have implemented a search/filtering function which goes through all the elements in the table and then hides/shows the item in the table depending upon whether that item/element matches the one we are searching for.
For example, let's say I have a text control and I type "wxwidgets" in it then my custom function will go through all the elements in the table and hide the elements that do not match this "wxwidgets" entry. This works fine and I am correctly able to hide/show the elements. But the problem is that this search blocks the main thread(gui) since I am doing this in the main thread. The table has around 1000 entries or can be more in the future. My question is how can I avoid this blocking of the main thread. I am thinking of using another worker thread that will do this searching of elements. But then I read that "no secondary threads should call gui functions". But then how can i show/hide the elements of the table from the worker thread. For example, currently in the main thread I use Show(true) or Show(false) to show/hide a particular entry from the table and all this is done while I am in a for/while loop. But if i implement this(the for loop) in a worker thread then according to the quoted advice i should not use the Show() functions from inside that worker thread. What can be done in this situation? Also, is there any other way/advice of doing this searching for elements of the table. I am thinking of starting a new detachable thread every time the user enters some text in the text field. And then delete that old thread if the user appends some more text to the text field and start a new thread which starts searching from the beginning. Is this the right solution for this?
The problem is that inside my for loop i am using the wxWidgets functions. For example, this is what my for loop looks like:
void AnotherClass::onTextChanged(wxCommandEvent &event)
{
for(int i = 5; i<154;++i)
{
SomeClass *element = dynamic_cast<SomeClass*>(FindWindowById(i));
if(element.GetLabel() == textEnteredInTextCtrl)
{
element.Show(true);//element found
//update the necessary layout here using layout call
}
else
{
element.Show(false);//element not found
//update the necessary layout here using Layout() call
}
}
}
This is the main part of the search. Now inside the workerthread should/can i use the functions like FindWindowById() and GetLabel()? Are they considered GUI functions or not so that I can use them from the worker thread? Can i or can i not use FindWindowByID() and GetLabel() and other similar functions(like Layout() and Show()) from inside the worker thread. How should I make this work? I mean I know how to use wxThread and send events using QueueEvent and already have another worker thread in my program that does some other calculation but I am asking about how I should make it work in this particular case.
Another solution suggested by QuentinC would be to use a timer. His suggestion is as follows:
In my case, I don't start refreshing the list immediately after the
user has typed a letter in the search box. Instead, when the user has
typed a letter (wxEVT_TEXT), I start or restart a timer of 500ms. Only
when the timer goes out (the user stops typing for 500ms) then the list
is refreshed. Again, this is a measure to avoid a rapid succession of
useless refreshes.
But in this case of using a timer i have several queries. I am sending the wxEVT_TEXT from CustomTextCtrl's onTextChanged method to this class' onTextChanged method. I guess i could start the timer of 500ms inside the onTextChanged method of the CustomTextCtrl class when the user types a letter. But then where should i check that the timer is still running? In the CustomTextCtrl's onTextChanged method or inside the AnotherClass's onTextChanged method?
So for clarification i have two classes:
the CustomTextCtrl class which have a onTextChanged method which uses event.Skip() to forward this event to its parent.
The parent class AnotherClass which also have a onTextChanged method and this method receives this forwarded event and do the searching and updates the table.
Where and how should i start/restart/stop the timer to update the UI?
NOTE: The process of filtering the elements is working perfectly but the only problem is that the main(GUI) thread is blocked when the user type some text inside the textctrl. After lets say 6 or 7 seconds, the text appears inside the textctrl and the UI is updated. I don't want this unresponsiveness of the main UI for 6-7 seconds.
Also, note that i am not using any wxList/wxGrid. I am just using wxPanels and wxStaticText and using show/hide on them.
Edit: One improvement in the code above is that to only use Layout() call from outside the for loop. If i use the Layout() calls from outside the for loop then the search functionality works almost instantly. But this(method) still has the potential of blocking the main thread in the future if the table has many more elements. So i want to use a thread or a timer method. But i don't know how the secondary thread could use the gui functions or how can/should i use a wxTimer method(if any) to solve this problem.
I have several thoughts on this subjet
A) If you have a speed issue, then you better profile your code, to see where the bottle neck is.
B) Calling GDI functions from a not-main thread is risky. Maybe just asking for window-id and its label is not that dangerous, but I think calling Show() definitely is.
C) This piece of code is mainly GUI related. I don't think a worker thread is useful here. But stacking similar callings may improve its speed. For this, I have three advises:
Use CallAfter() passing the elemnt.Show() method
Use Freeze() before the loop and Thaw after it.
Call Layout()only once, right after the loop. About this I wonder if Show()/Hide() controls is better than Enable()/Disabñe()
D) Because you call FindWindowById() so many times, and also many user changes, it will be better to cache all affected windows in a container (a std::map with id as the key). Then, inside the loop use the container instead of 'FindWindowById()`.
E) As a last resource, if the GUI is still blocked, use wxYield() every xxx (say 100) loop-iterations. Depending of pending messages this solution may get things worse (reentrances, crossed effects, etc).
I recently switched from unity and I wanted to know if there was a “getComponent” equivalent in UE4? I have an enemy script and I created a blueprint from that script and have added a widget with a progress bar to show the enemies health during combat. I have seen a lot of examples of how to do this in blueprint but if possible, I would like to just do it in code and let the percentage be calculated when it is needed to be, like after damage or something, rather than binding via blueprints.
I have tried using the getcomponentbyclass method but that throws an error because the component I want is not a child of the actor class.
Any help appreciated
You need to call GetComponentByClass() on an Actor.
If your Enemy is a Component, you can call getOwner() to retrieve the actor owning this component.
You can then call GetComponentByClass() on this actor instance.
I've been going in circles for a day now trying to get this going and I'm just getting nowhere. I'm trying to have multiple objects in the scene with individual animations and when I fire a raycast from my player and it hits one, have the UFunction(blueprintimplementableevent) go off on the object that it hits. Please help me this is absolutely stumping me.
What I would do is use a BlueprintNativeEvent. This will allow you to create an Implementation function of the stuff you want to happen in C++, as well as a blueprint implementation, which can be different for each blueprint of that object type.
It is quite simple to use as well, for example, in your character's header file:
/** Called when the player presses the fire key */
UFUNCTION(BlueprintNativeEvent, Category = "Shooting")
void OnHit();
virtual void OnHit_Implementation();
And now your Cpp:
void AMyGameCharacter::OnHit_Implementation()
{
UE_LOG(LogTemp, Warning, TEXT("OnHit_Implementation!"));
// Do whatever stuff you want to do in C++ here
}
Now over in your character / actor blueprint, just go to the event graph, right click, and add the event of type OnHit. Make sure that you make a callback to the parent OnHit event though (right click on the event and hit "Add Call to Parent Function")
If you want an example of this you can look at the C++ Battery Collector series or the docs.
I can't seem to get a good grasp on how these OpenGLAppComponents come and go. Can someone please correct my thinking if it is wrong?
Object is created that inheirts from OpenGLAppComponents and Timer. Object exists in the AudioProcessorEditor.
Call initialise() (This is where we attach to an openGLContext? A timer is started.)
addAndMakeVisible(&my_gl_appcomponent); is called from the editor, telling it that this will be drawn.
my_gl_appcomponent.setBounds(...) is called specifying the size and location of the GL component.
The timer callback calls repaint() repeatedly, updating your display.
When the editor is closed, we call shutdown(), where we detach from the openGLContext.
Delete my_gl_component, calling shutdownOpenGL() in the destructor
We are free to open the editor again, goto 2.
Am I missing anything? Do I have extra things? I've been trying to find the cause of this GL_INVALID_FRAMEBUFFER_OPERATION error for the second day in a row and I'm getting pretty frustrated.
I have a Window object which contains only a grid. I want to use Gtk::Builder to get a pointer to the grid, and then use some Gtk::Box's Gtk::Box->pack_end() to add the grid to it many times (with manipulated contents each time).
Though each time that pack_end() is called I get:
gtk_box_pack: assertion 'gtk_widget_get_parent (child) == NULL' failed in my terminal and nothing gets added to the box.
What should I do?
Thanks
* EDIT:
Goal:
I want entries of a DB table to be put into a fancy widget for each record, though all the records being shown vertically one after the other. I thought I can create the fancy widget as a window in Glade and use Gtk::Builder to get a pointer to it. So in the fancy's Glade file I have a window containing a grid that has my custom appearance. I get the above error when I try to add the pointer to the fancy *grid*, to the visible window's Box. I hope I'm clear.
Here's the solution to gtk_box_pack: assertion 'gtk_widget_get_parent (child) == NULL' failed:
All that needs to be done at the first place is that you should draw the widgets WITHOUT a window, so when loaded with builder, it won't have a parent and thus the assersion succeeds.
Though here's another point: When I add the first instance of the grid to the Box, the second one results in the same error again. After a couple of trials and errors I realized that in each interation you should use Gtk::Builder::create_from_file() to create a new parent-less instance of the grid to be able to use, and this way it works.
There has to be a great difference in performance, in case number of records is gonna be big, but Gtk::Widget's copy constructor is private and direct copying is not possible, and since it wasn't my main obsession I didn't insist on resolving this "performance" issue.