How do I fix yield not working in while loop? - while-loop

I get no console errors, but all of them isntantiate at the same time, so they are all one unit, and I want a delay between their spawn. (they are enemies traveling a path)
#pragma strict
// Instantiate a rigidbody then set the velocity
var projectile : Transform;
var cnt : int = 0;
function Update () {
if (buttonFeatures.started) {
while (cnt < 4) {
// Instantiate the projectile at the position and rotation of this transform
wait();
var clone : Transform;
clone = Instantiate(projectile, transform.position, transform.rotation);
cnt++;
}
}
}
function wait(){
yield WaitForSeconds (10);
}

Your problem is you're trying to something similar to yield from Update(), which can't be done.
You can't obviously block Update() for 10 seconds, but calling a method that usesyield will return *immediately *and start a coroutine with that method, so what you're seeing is:
Update calls wait()
Update keeps going without waiting for wait() to return
wait() starts waiting for 10 seconds on it's own as a coroutine
Update continues through the loop, calling wait() 3 more times, not waiting each time.
To confirm this you can change wait():
function wait(){
yield WaitForSeconds (10);
Debug.Log("Done Waiting"); //You'll see 3 of these pop up in your console in 10 seconds later
}
You have two main options here. Either replace wait() with your logic:
function Update () {
if (buttonFeatures.started) {
while (cnt < 4) {
InstantiateProjectile(cnt*10)// Instantiate the projectile at the position and rotation of this transform in X seconds. This will return immediately
cnt++;
}
}
}
function InstantiateProjectile(delay : int){
yield WaitForSeconds(delay);
var clone : Transform;
clone = Instantiate(projectile, transform.position, transform.rotation);
}
Or start a co-routine in Start():
function Start(){
UpdateProjectiles();
}
function UpdateProjectiles (){
while(true){
if (buttonFeatures.started) {
while (cnt < 4) {
yield WaitForSeconds (10); //This works because it's not in Update
var clone : Transform;
clone = Instantiate(projectile, transform.position, transform.rotation); // Instantiate the projectile at the position and rotation of this transform
cnt++;
}
}
yield; //This causes this coroutine to behave the way Update would (running once a frame)
}
}
The while(true) in the second example might be a little alarming, but it's performance is no different than using Update() because of the yield. In fact, many people use the majority of their "traditional" Update() logic in co-routines, as they allow better encapsulation of state management logic, and are great for periodic tasks.
Note: I didn't want to distort your code too much and obscure it's meaning, but you might want to reconsider certain parts of your code:
You have a while loop with a count, that can easily be a for loop.
You have a loop that seems to be replacing objects. Instantiate can be one of the most expensive calls you can make, because for every call you make to it, eventually you'll pay the cost of the GC cleaning up an object.
You don't want to be destroying lots of objects and calling Instantiate to replace them with identical ones, because the GC will start slowing your game to a standstill keeping up. Right now as your code stands, if projectiles start being spawned in a situation where they're being destroyed very quickly, I won't be surprised if the game completely freezes.
Instead, prefer reusing objects, with object pools. There are tutorials on how to do it, such as this one. At the most basic level, it can be something as simple as giving your projectiles a Reset method. Then you could replace Destroy with a method that calls Reset and stores them in a Stack or List, where they can be accessed again. But you'll want to encapsulate all that logic, so look at that tutorial for specifics.

replace this line instead of making the function call:
yield return new WaitForSeconds(10);

Related

How to return an int value stuck in a for loop but a callback in Kotlin?

I am trying to get the size of this firebase collection size of documents, and for some reason in Kotlin, I can't seem to get this to work. I have declared a variable to be zero in an int function and I put it inside a for loop where it increments to the size of the range. Then when I return the value, it is zero. Here is the code I have provided, please help me as to why it is returning zero.
This is just what is being passed to the function
var postSize = 0
That is the global variable, now for below
val db = FirebaseFirestore.getInstance()
val first = db.collection("Post").orderBy("timestamp")
getPostSize(first)
This is the function
private fun getPostSize(first: Query){
first.get().addOnSuccessListener { documents ->
for(document in documents) {
Log.d(TAG, "${document.id} => ${document.data}")
getActualPostSize(postSize++)
}
}
return postSize
}
private fun getActualPostSize(sizeOfPost: Int): Int {
// The number does push to what I am expecting right here if I called a print statement
return sizeOfPost // However here it just returns it to be zero again. Why #tenffour04? Why?
}
It is my understanding, according to the other question that this was linked to, that I was suppose to do something like this.
This question has answers that explain how to approach getting results from asynchronous APIs, like you're trying to do.
Here is a more detailed explanation using your specific example since you were having trouble adapting the answer from there.
Suppose this is your original code you were trying to make work:
// In your "calling code" (inside onCreate() or some click listener):
val db = FirebaseFirestore.getInstance()
val first = db.collection("Post").orderBy("timestamp")
val postSize = getPostSize(first)
// do something with postSize
// Elsewhere in your class:
private fun getPostSize(first: Query): Int {
var postSize = 0
first.get().addOnSuccessListener { documents ->
for(document in documents) {
Log.d(TAG, "${document.id} => ${document.data}")
postSize++
}
}
return postSize
}
The reason this doesn't work is that the code inside your addOnSuccessListener is called some time in the future, after getPostSize() has already returned.
The reason asynchronous code is called in the future is because it takes a long time to do its action, but it's bad to wait for it on the calling thread because it will freeze your UI and make the whole phone unresponsive. So the time-consuming action is done in the background on another thread, which allows the calling code to continue doing what it's doing and finish immediately so it doesn't freeze the UI. When the time-consuming action is finally finished, only then is its callback/lambda code executed.
A simple retrieval from Firebase like this likely takes less than half a second, but this is still too much time to freeze the UI, because it would make the phone seem janky. Half a second in the future is still in the future compared to the code that is called underneath and outside the lambda.
For the sake of simplifying the below examples, let's simplify your original function to avoid using the for loop, since it was unnecessary:
private fun getPostSize(first: Query): Int {
var postSize = 0
first.get().addOnSuccessListener { documents ->
postSize = documents.count()
}
return postSize
}
The following are multiple distinct approaches for working with asynchronous code. You only have to pick one. You don't have to do all of them.
1. Make your function take a callback instead of returning a value.
Change you function into a higher order function. Since the function doesn't directly return the post size, it is a good convention to put "Async" in the function name. What this function does now is call the callback to pass it the value you wanted to retrieve. It will be called in the future when the listener has been called.
private fun getPostSizeAsync(first: Query, callback: (Int) -> Unit) {
first.get().addOnSuccessListener { documents ->
val postSize = documents.count()
callback(postSize)
}
}
Then to use your function in your "calling code", you must use the retrieved value inside the callback, which can be defined using a lambda:
// In your "calling code" (inside onCreate() or some click listener):
val db = FirebaseFirestore.getInstance()
val first = db.collection("Post").orderBy("timestamp")
getPostSizeAsync(first) { postSize ->
// do something with postSize inside the lambda here
}
// Don't try to do something with postSize after the lambda here. Code under
// here is called before the code inside the lambda because the lambda is called
// some time in the future.
2. Handle the response directly in the calling code.
You might have noticed in the above solution 1, you are really just creating an intermediate callback step, because you already have to deal with the callback lambda passed to addOnSuccessListener. You could eliminate the getPostSize function completely and just deal with callbacks at once place in your code. I wouldn't normally recommend this because it violates the DRY principle and the principle of avoiding dealing with multiple levels of abstraction in a single function. However, it may be better to start this way until you better grasp the concept of asynchronous code.
It would look like this:
// In your "calling code" (inside onCreate() or some click listener):
val db = FirebaseFirestore.getInstance()
val first = db.collection("Post").orderBy("timestamp")
first.get().addOnSuccessListener { documents ->
val postSize = documents.count()
// do something with postSize inside the lambda here
}
// Don't try to do something with postSize after the lambda here. Code under
// here is called before the code inside the lambda because the lambda is called
// some time in the future.
3. Put the result in a LiveData. Observe the LiveData separately.
You can create a LiveData that will update its observers about results when it gets them. This may not be a good fit for certain situations, because it would get really complicated if you had to turn observers on and off for your particular logic flow. I think it is probably a bad solution for your code because you might have different queries you want to pass to this function, so it wouldn't really make sense to have it keep publishing its results to the same LiveData, because the observers wouldn't know which query the latest postSize is related to.
But here is how it could be done.
private val postSizeLiveData = MutableLiveData<Int>()
// Function name changed "get" to "fetch" to reflect it doesn't return
// anything but simply initiates a fetch operation:
private fun fetchPostSize(query: Query) {
first.get().addOnSuccessListener { documents ->
postSize.value = documents.count()
}
}
// In your "calling code" (inside onCreate() or some click listener):
val db = FirebaseFirestore.getInstance()
val first = db.collection("Post").orderBy("timestamp")
fetchPostSize(first)
postSizeLiveData.observer(this) { postSize ->
// Do something with postSize inside this observer that will
// be called some time in the future.
}
// Don't try to do something with postSize after the lambda here. Code under
// here is called before the code inside the lambda because the lambda is called
// some time in the future.
4. Use a suspend function and coroutine.
Coroutines allow you to write synchronous code without blocking the calling thread. After you learn to use coroutines, they lead to simpler code because there's less nesting of asynchronous callback lambdas. If you look at option 1, it will become very complicated if you need to call more than one asynchronous function in a row to get the results you want, for example if you needed to use postSize to decide what to retrieve from Firebase next. You would have to call another callback-based higher-order function inside the lambda of your first higher-order function call, nesting the future code inside other future code. (This is nicknamed "callback hell".) To write a synchronous coroutine, you launch a coroutine from lifecycleScope (or viewLifecycleOwner.lifecycleScope in a Fragment or viewModelScope in a ViewModel). You can convert your getter function into a suspend function to allow it to be used synchronously without a callback when called from a coroutine. Firebase provides an await() suspend function that can be used to wait for the result synchronously if you're in a coroutine. (Note that more properly, you should use try/catch when you call await() because it's possible Firebase fails to retrieve the documents. But I skipped that for simplicity since you weren't bothering to handle the possible failure with an error listener in your original code.)
private suspend fun getPostSize(first: Query): Int {
return first.get().await().count()
}
// In your "calling code" (inside onCreate() or some click listener):
lifecycleScope.launch {
val db = FirebaseFirestore.getInstance()
val first = db.collection("Post").orderBy("timestamp")
val postSize = getPostSize(first)
// do something with postSize
}
// Code under here will run before the coroutine finishes so
// typically, you launch coroutines and do all your work inside them.
Coroutines are the common way to do this in Kotlin, but they are a complex topic to learn for a newcomer. I recommend you start with one of the first two solutions until you are much more comfortable with Kotlin and higher order functions.

How can I force shell to push an object after self destroying with delay (Unity3D)

I have an object inside a boundary and I shoot into the object (to understand my code see this lesson: https://unity3d.com/learn/tutorials/projects/space-shooter/creating-hazards?playlist=17147). Shell (bullet) should be destroyed after collision with object, but not instantly - after some delay (i.e. they collides and after some amount of seconds shell disappears). Shell's collider should be with a trigger, but because of it she flies through the object. Shell should disappear after it affected the object. I made the delay in order to have time for affecting. But if there a way it can disappear instantly then that's great. I just wanted give time to shell to apply a force.
void OnTriggerEnter(Collider other) {
if (other.tag == "Boundary")
{
return;
}
//Destroy (gameObject);
StartCoroutine(WaitAndDestroy());
}
IEnumerator WaitAndDestroy() {
yield return new WaitForSeconds(2);
Destroy (gameObject);
}
Try to move StartCoroutine(WaitAndDestroy()); above the return statement.
It is nesessary to use OnCollisionEnter(Collision other), and put Destroy(other.gameObject) into it. And colliders should be without triggers - on both interacting objects.

How to benchmark if I need a reset in each iteration?

I've written a small Sudoku solver using backtracking. Now I want to benchmark the speed of this function. Here is my current code:
type Board struct {
Cells [9][9]int
}
func BenchmarkBacktrack(b *testing.B) {
for i := 0; i < b.N; i++ {
b.StopTimer()
// prevent the modification of the orignal board
copy := &Board{
Cells: exampleBoard.Cells,
}
b.StartTimer()
copy.Backtrack()
}
}
Since &Board is pointer I would solve the Sudoku in the first iteration and in the next one I would backtrack a solved board. Therefore, I reset the board at the beginning of each iteration. exampleBoard is filled with sample values.
Is their a better way to benchmark the function without stopping and restarting the timer over and over?
And wouldn't cost the function calls a small amount of time that impacts the benchmark?
And wouldn't cost the function calls a small amount of time that that impacts the benchmark?
Of course they would. So does the for loop, which is included in the benchmark. Plus overhead of calling copy.Backtrack function. But the thing is, this should be all irrelevant, unless you're benchmarking a single operation taking nanoseconds (in which case you shouldn't). Creation of an empty board is probably a trivial operation, so I wouldn't touch the timers at all. If it's not trivial, then you're doing it right – call StopTimer. This is exactly why it was invented:
StopTimer stops timing a test. This can be used to pause the timer while performing complex initialization that you don't want to measure.
You could try providing a func NewBoard([9][9]int) *Board method, which just initializes a board from the example data. Then write a benchmark for Backtrack() on a new board and a separate benchmark for NewBoard().
Subtracting the two numbers should give you an idea of the speed of your Backtrack method alone.
type Board struct {
Cells [9][9]int
}
var scratch *Board
func NewBoard(cells [9][9]int) *Board {
return &Board{Cells: cells}
}
func BenchmarkBacktrack(b *testing.B) {
for i := 0; i < b.N; i++ {
scratch = NewBoard(exampleBoard.Cells)
scratch.Backtrack()
}
func BenchmarkNewBoard(b *testing.B) {
for i := 0; i < b.N; i++ {
scratch = NewBoard(exampleBoard.Cells)
}
Also note the use of scratch variable. Trying to create a loop local variable inside the benchmark loop could lead the compiler to optimise away the call to NewBoard() depending on presence/absence of side-effects. For parity, you need to use the scratch variable in both benchmarks.

Pre-processing a loop in Objective-C

I am currently writing a program to help me control complex lights installations. The idea is I tell the program to start a preset, then the app has three options (depending on the preset type)
1) the lights go to one position (so only one group of data sent when the preset starts)
2) the lights follows a mathematical equation (ex: sinus with a timer to make smooth circles)
3) the lights respond to a flow of data (ex midi controller)
So I decided to go with an object I call the AppBrain, that receive data from the controllers and the templates, but also is able to send processed data to the lights.
Now, I come from non-native programming, and I kinda have trust issues concerning working with a lot of processing, events and timing; as well as troubles with understanding 100% the Cocoa logic.
This is where the actual question starts, sorry
What I want to do, would be when I load the preset, I parse it to prepare the timer/data receive event so it doesn't have to go trough every option for 100 lights 100 times per second.
To explain more deeply, here's how I would do it in Javascript (crappy pseudo code, of course)
var lightsFunctions = {};
function prepareTemplate(theTemplate){
//Let's assume here the template is just an array, and I won't show all the processing
switch(theTemplate.typeOfTemplate){
case "simpledata":
sendAllDataTooLights(); // Simple here
break;
case "periodic":
for(light in theTemplate.lights){
switch(light.typeOfEquation){
case "sin":
lightsFunctions[light.id] = doTheSinus; // doTheSinus being an existing function
break;
case "cos":
...
}
}
function onFrame(){
for(light in lightsFunctions){
lightsFunctions[light]();
}
}
var theTimer = setTimeout(onFrame, theTemplate.delay);
break;
case "controller":
//do the same pre-processing without the timer, to know which function to execute for which light
break;
}
}
}
So, my idea is to store the processing function I need in an NSArray, so I don't need to test on each frame the type and loose some time/CPU.
I don't know if I'm clear, or if my idea is possible/the good way to go. I'm mostly looking for algorithm ideas, and if you have some code that might direct me in the good direction... (I know of PerformSelector, but I don't know if it is the best for this situation.
Thanks;
I_
First of all, don't spend time optimizing what you don't know is a performance problem. 100 iterations of the type is nothing in the native world, even on the weaker mobile CPUs.
Now, to your problem. I take it you are writing some kind of configuration / DSL to specify the light control sequences. One way of doing it is to store blocks in your NSArray. A block is the equivalent of a function object in JavaScript. So for example:
typedef void (^LightFunction)(void);
- (NSArray*) parseProgram ... {
NSMutableArray* result = [NSMutableArray array];
if(...) {
LightFunction simpledata = ^{ sendDataToLights(); };
[result addObject:simpleData];
} else if(...) {
Light* light = [self getSomeLight:...];
LightFunction periodic = ^{
// Note how you can access the local scope of the outside function.
// Make sure you use automatic reference counting for this.
[light doSomethingWithParam:someParam];
};
[result addObject:periodic];
}
return result;
}
...
NSArray* program = [self parseProgram:...];
// To run your program
for(LightFunction func in program) {
func();
}

Continuations using Async CTP

Is it possible to use Async CTP to emulate continuations and tail recursion?
I'm thinking something along the lines of:
async Task Loop(int count)
{
if (count == 0)
retrun;
await ClearCallStack();
//is it possible to continue here with a clean call stack?
Loop(count -1)
}
I guess one needs a custom scheduler and such, but would it be possible?
(that is, can it be used to recurse w/o blowing the call stack)
Yes, this is entirely possible.
In the newest Async CTP (Refresh for VS2010 SP1), there's a "GeneralThreadAffineContext" class in the Unit Testing sample (either in VB or C#). That provides the requisite helper code for just running an async method in a general purpose thread-affine manner.
By thread affinity, we mean that the async continuations get processed on the same context as the original thread, similarly to the behavior for WinForms/WPF, but without spinning up the real WPF or WinForms message loop.
Task.Yield()'s design is to defer the rest of the current method to the SynchronizationContext, so you don't even need to write your own await ClearCallStack(). Instead, your sample will boil down to:
async Task DoLoop(int count)
{
// yield first if you want to ensure your entire body is in a continuation
// Final method will be off of Task, but you need to use TaskEx for the CTP
await TaskEx.Yield();
if (count == 0)
return;
//is it possible to continue here with a clean call stack?
DoLoop(count -1)
}
void Loop(int count)
{
// This is a stub helper to make DoLoop appear synchronous. Even though
// DoLoop is expressed recursively, no two frames of DoLoop will execute
// their bodies simultaneously
GeneralThreadAffineContext.Run(async () => { return DoLoop(count); });
}