Godot engine: removing an instance of a scene without freeing the whole scene - instance

I’ve added multiple instances of a scene as enemies, and now I want to remove one of them when it dies. I tried using “queue_free()” on it, but this only works for one instance, and every instance afterwards doesn’t get removed and returns a “node not found” error. How do I just remove one instance at a time?

Your question can't be easily answered because we don't know your specific code and there are multiple good ways to do this. As far as I understand you, you have an enemy class with some kind of health level. You could create a function that checks if the health is above zero or some other variable like alive. A very easy way would be like
func is_alive():
if health > 0:
return True
else:
queue_free()
You could call this function in every process cycle and also add some dying animation or counter later.

Related

didEnterRegion gets triggered many times

For some strange reason sometimes when I enter a region, the didEnterRegion gets triggered as much as 10 times. Does anyone know what are the possible reasons this can happen? I know that may happen if I'm at a boundary but maybe Apple has smart logic not trigger at those points.
Whats up with this??
I've seen that when you have multiple instances of your CLLocationManager instantiated. Say you have multiple classes that need to use the location, you alloc/init the location manager 4-5 times in your app life-cycle... they are all listening for delegate methods.
So, if I only have 4-5 instances, why do I get 10 callbacks? Glad you asked. :p I believe there is a bug in Apple's region monitoring delegate methods that fire twice for each instance.
The solution would be to create your own singleton class for the location manager delegate and just use the one instance of your location manager for the whole application. This will prevent you from getting 4-5 x 2 callbacks. Then you'll only get 2 like everyone else.
If you would like to help, duplicate the radar in my answer on this question so we can get Apple to fix the issue once and for all.
why the didEnterRegion called twice ?

What does NSManagedContext reset do?

Here's my scenario: I have a thread running heavy calculations, saving the results via core data at the end. I have the thread set up with it's own autorelease pool and it's own NSManagedContext created within the thread. The user can change the inputs to the calculation on the main thread, in which case the calculation thread is terminated (via regular checks of a NSLocked variable) and relaunched with the new inputs. Everything is working fine here.
For performance reasons, the calculation thread doesn't have an undo manager and there is only one context save at the very end. If a termination command is detected I don't want to save the results. Right now I'm just skipping the context save and releasing it, which seems to work fine.
I noticed, however, that there's a reset method for NSManagedContext. Apple's documentation on this method isn't very helpful to me. It simply states that it returns the receiver's contents to it's base state and that all the receiver's managed objects are "forgotten".
What does that mean? Is it the equivalent to reverting to the last saved version? Is an undo manager required for proper operation of this method? Any reason I should use this method instead of what I'm doing now?
It sounds like you are using the context to cache changes independent of the context on the main thread, and if you don't want those changes to be recorded, you just throw them out by deleting the "local" context. This is good enough for the scenario you are describing. -reset might be useful if you didn't want to relaunch the background thread, but just start over using the same thread (and context), but with new inputs. Since you launch a new thread (thus creating a new NSManagedObjectContext on it), -reset is probably not very useful for you in this scenario. You already pretty much doing it as Apple recommends in several of their sample codes.

Removing Object With Timer

I have two NSMutableArrays, collectables and collectableViews.
My app consists of a character moving around and gathering collectables (coins, apples, bananas, etc) for points...
I would like the collectables to disappear after a certain amount of time.. however, I am confused as to where to put an NSTimer to not disrupt Model/View/Controller design.
For example, If I put an individual timer in each model, the model doesn't know of the view and cannot remove the view..
If I put the NSTimer in the controller, I would need to make another array consisting of all the collectables on the screen, in order of which one expires first. The timer's method would fire every second and remove each collectable when they are due.
Is there an easier, better way to do this?
Most games model this kind of 'state-monitoring' using one or more game clocks. You can do something like this:
Create a data structure containing a duration time, function
pointer, and array of object variables. For this example let's call
it DecayEvent.
Create a static, mutable array of DecayEvent's in your front (main)
controller, with some nice accessor methods
Choose an appropriate event processing interval. It needs to be
large enough to process what you think the maximum number of events
will be, but small enough not to retard user experience.
Create a method on your front controller that will process through
the array of decay events. Every time the method is called it will
iterate the array and decrement the event's duration time by the
event processing interval. If the decay events duration falls below
zero then 'fire the event' (basically, trigger its callback function
in another thread, with the callback arguments).
Create an NSTimer in your main thread. Set it to call your
processing method at every event processing interval.
You will have to tweak quite a bit to get everything working the way you want, but the steps above will generally work.
Good luck!
Your current situation tends that you should keep timer in your controller because controller has access to each data modal and views you can access arrays too. also another approach is to use NSNotificationCenter. First try and if that doesn't work then let us know.

Undoing Core Data insertions that are performed off the main thread

I'm working on some code that uses an NSOperation to import data. I'd like for the user to be able to undo the NSManagedObject instances that are created during the import operation.
From what I can tell, it's impossible to use the NSManagedObjectContext -undoManager for any operations that are performed off of the main thread. From the Core Data Programming Guide section on Use Thread Confinement to Support Concurrency, we have these two conditions:
Only objectID should be passed
between managed object contexts (on
separate threads)
Managed objects
must be saved in a context before
the objectID can be used.
This makes sense since the managed objects need to be moved from private storage (NSManagedObjectContext) to public storage (NSPersistentStore) before they can be shared.
Unfortunately, the -save: message also causes any managed objects in the undo stack to be removed. From the Memory Management Using Core Data section of the same guide:
Managed objects that have pending
changes (insertions, deletions, or
updates) are retained by their context
until their context is sent a save:,
reset , rollback, or dealloc message,
or the appropriate number of undos to
undo the change.
I've tried several things to work around this limitation, and everything eventually leads back to bulk of the work happening on the main thread (and spinning beach balls.) Any clues to getting undo working with objects created off the main thread would be very much appreciated.
--
An enhancement Radar has been submitted: rdar://problem/8977725
This answer will probably be a bit of a back and forth. If I understand the issue correctly, you are doing an import but when the import is done you want the user to be able to select what gets saved from the import?
If that is not correct, please fix my assumptions and I will update this answer.
If it is correct then what you can do is:
Change your background object creation to
NSEntityDescription *myEntity = ... //Entity from your context
[[NSManagedObject alloc] initWithEntity:myEntity
insertIntoManagedObjectContext:nil];
Store these entities in an array.
Pass the entities back to your main thread as needed.
Release on any objects you don't want to keep
Call [myMainContext insertObject:managedObject] on any you want to keep.
Perform a save on the NSManagedObjectContext.
Since these entities are not part of a NSManagedObjectContext yet they only exist in memory and should be thread safe since they are not yet tied down to a NSManagedObjectContext.
This is of course theoretical and will require testing. However it should accomplish your goal.
Not an expert, but I think what you're going to need to do is create a second context to perform the operations, then merge the two contexts together. You should be able to manage the merge as an undo step. Note, this only works if you're treating the entire set of operations as one undo step, as far as the user is concerned.
Suppose that you use a separate context for the background thread, and once it's done, push a [[backgroundContext undoManager] undo] onto the foreground thread's undo stack? I've never tried anything like that, but off the top of my head I can't think of a reason it shouldn't work.
One option may be to make your import thread persistent. Even when the thread is finished importing, it goes into an idle loop state. This way your threaded ManagedObjectContext is persisted in the proper thread. Then when the user wishes to undo a change, send a message to the thread to use the undomanager.
It's incredibly likely you've considered this and you're likely only looking for a solution using the existing undoManager, but just in case:
Since you're inserting objects and not updating existing ones, you do have the power to tag them with a transaction id as each batch is imported, deleting them in a background thread in the case of an undo. A simple incremented NSNumber is sufficient for the tag.
Inelegant, but workable.

OOP question about functions that struck me all of a sudden

May be my question is stupid. But i would like to get it cleared. We know that functions are loaded in memory only once and when you create new objects, only instance variables gets created, functions are never created. My question is, say suppose there is server and all clients access a method named createCustomer(). Say suppose all clients do something which fired createCustomer on server. So, if the method is in middle of execution and new client fires it. Will the new request be put on wait? or new request also will start executing the method? How does it all get managed when there is only one copy of function in memory? No book mentions answers to this type of questions. So i am posting here where i am bound to get answers :).
Functions are code which is then executed in a memory context. The code can be run many times in parallel (literally in parallel on a multi-processor machine), but each of those calls will execute in a different memory context (from the point of view of local variables and such). At a low level this works because the functions will reference local variables as offsets into memory on something called a "stack" which is pointed to by a processor register called the "stack pointer" (or in some interpreted languages, an analog of that register at a higher level), and the value of this register will be different for different calls to the function. So the x local variable in one call to function foo is in a different location in memory than the x local variable in another call to foo, regardless of whether those calls happen simultaneously.
Instance variables are different, they're referenced via a reference (pointer) to the memory allocated to the instance of an object. Two running copies of the same function might access the same instance variable at exactly the same time; similarly, two different functions might do so. This is why we get into "threading" or concurrency issues, synchronization, locks, race conditions, etc. But it's also one reason things can be highly efficient.
It's called "multi-threading". If each request has its own thread, and the object contains mutable data, each client will have the opportunity to modify the state of the object as they see fit. If the person who wrote the object isn't mindful of thread safety you could end up with an object that's in an inconsistent state between requests.
This is a basic threading issue, you can look it up at http://en.wikipedia.org/wiki/Thread_(computer_science).
Instead of thinking in terms of code that is executed, try to think of memory context of a thread that is changed. It does not matter where and what the actual code happens to be, and if it is the same code or a duplicate or something else.
Basically, it can happen that the function is called while it was already called earlier. The two calls are independent and may even happen to run in parallel (on a multicore machine). The way to achieve this independence is by using different stacks and virtual address spaces for each thread.
There are ways to synchronize calls, so additional callers have to wait until the first call finishes. This is also explained in the above link.