For some current projects, I'm working with several data structures that are pretty large (in the area of 10K elements). To be able to access this data in lists, I need to use loops and iterators, which can be a pain when the problem area is in the latter half of the list.
So I find myself spending alot of time with my finger on the F8 button in Eclipse's debugger to loop through each element of an iterating loop. This gets worse when have to step through that particular section several times to get an idea why the code is reacting a particular way.
If one has a general idea how many times a loop is to execute before a problem area is hit, is there a way to set a loop breakpoint to execute up to that point then pause?
Use conditional breakpoints.
http://wiki.eclipse.org/FAQ_How_do_I_set_a_conditional_breakpoint%3F
I believe there's a better way to do this, but you can create a trivial block of code in the loop that only executes at a certain iteration, and put the breakpoint inside of it.
if (loopIndex == 1000) {
int number = 14; //Break here
}
Using this as an example:
for(int i=0;i<10000;i++){
System.out.println(i);
}
Set a breakpoint on the print line, then right click on it and select Breakpoint Properties.... From here you can set a condition to trigger the breakpoint. This is the similar to a conditional you would have in an if-statement. If you wanted to trigger the breakpoint when i equals 6000, check the Conditional box and try this:
Related
I have a UIAnimation that pulls out a message log, but I need to populate the message log using a for loop as well. I have the animation taking place before the for loop begins, however, the animation doesn't actually begin until after the for loop finishes executing (even though the loop is located after the UIAnimation).
I've tried putting the contents of the for loop within an autoreleasepool (did not work)
I've tried running the for loop on a background thread, however, most of the code within the loop needs to be executed on the main thread, and I haven't had success with that approach.
The for loop is very large, and most of the code is irrelevant to the question, so you can set this up using any UIAnimation, and any relatively time consuming for loop...
for example:
let someView = UIView(frame:CGRect(x:self.view.frame.size.width,y:0,width:self.view.frame.size.width,height:self.view.frame.size.height))
someView.backgroundColor = .red
UIView.animate(withDuration:0.3,animations:{
self.someView.frame.origin.x = 0
})
//You can wrap this with something like:
//DispatchQueue.global(qos: .background).async(execute: {
//But this^ doesn't work on the majority of the code within the loop
for i in 0...1000{
print("hopefully this loop takes a few seconds to finish executing")
print("mainthread tasks being executed")
print("populating UITable in my particular case, and rendering Images/Video/text")
}
The closest that I can get to making it better is to add a "completion" to my UIAnimation, (which will allow the UIView to pull out completely/immediately) but then there is still a second of wait time before the first messages appear...
Also, I am populating a UITableView within the for loop. Not sure if that has any extra relevance to the primary issue I'm having or not...
I'm pretty familiar with DispatchQueue and the differences between async/sync. If you have any potential solutions, or ideas, please let me know.
The animation does not happen immediately, when you call UIView.animate. In stead all the animations are collected and run at some appropriate time. This is why the animation only starts after your for loop is done.
So the way to fix it is to get the animation to run before your for loop runs. Now, accepting what you say, that the for must run on the main thread, you have a number of options. You could put the for loop inside a DispatchQueue.main.async{} or somehow throttle it down so that the animation gets going first. Your idea of using the completion is a good one but you mention some practical issues you picked up with it. So either solve those practical issues, try to run the for inside a DispatchQueue.main.async{} or even, based on practical considerations, start the for loop on the main thread but somewhere else, say in something like didLayoutSubviews (fixed) or as now together with the animation but after a few millis delay to allow the animation to get going.
It's an interesting question. This made me think!
Yes, you mentioned that you understand differences between async/sync but didn't mention if you tried animating in the main thread.
Did you try putting the
UIView.animate(...) in DispatchQueue.main.async{}?
I have an inventory of 30 variables that are randomly selected. When one variable is chosen a question that corresponds with that variable should appear. Instead no matter which variable is chosen, the block at the end of the code is chosen. I even got rid of the randomizer so I could choose which variable was chosen, but the code still went all the way to the bottom. How can I fix this?
Here is a screenshot of part of the code:
The problem with your code is that none of your if blocks can ever evaluate to false. After all, Inventory does contain every of it's items. Therefore every say is executed, but everey output is replaced by the subsequent one. Due to the speed with which this happens, you can only see the last one.
A solution is to select an item into another variable and compare this variable to the list, like so:
My goal is to build a 5x5 grid of images. In the following code, row, col and rowcol were created as variables local to the sprite, and newcol, newrow and cats are global. (By the way, is it possible to tell which variables are local and which are global? It's easy to forget or make mistakes.)
The result is a 5x1 grid only, as seen here.
I am unclear as to the order of execution of these statements. Does when I start as a clone get called before or after add_cat gets called the second time? My tentative conclusion is that it gets called afterwards, yet the clone's global variables seem to contain their values from beforehand instead.
When I attempted to debug it with ask and say and wait commands, the results varied wildly. Adding such pauses in some places fixed the problem completely, resulting in a 5x5 grid. In other places, they caused a 1x5 grid.
The main question is: How to fix this so that it produces a 5x5 grid?
Explanation
Unfortunately, the execution order in Scratch is a little bizarre. Whenever you edit a script (by adding or removing blocks, editing inputs, or dragging the entire script to a new location in the editor), it gets placed at the bottom of the list (so it runs last).
A good way to test this out is to create a blank project with the following scripts:
When you click the green flag, the sprite will either say "script one" or "script two", depending on which runs first. Try clicking and dragging one of the when green flag clicked blocks. The next time you click the green flag, the sprite will say whichever message corresponds to the script you just dragged.
This crazy order can make execution incredibly unpredictable, especially when using clones.
The solution
The only real solution is to write code that has a definite execution order built-in (rather than relying on the whims of the editor). For simpler scripts, this generally means utilizing the broadcast and wait block to run particular events in the necessary order.
For your specific project, I see two main solutions:
Procedural Solution
This is the most straightforward script, and it's probably what I would choose to go with:
(row and col are both sprite-only variables)
Because clones inherit all sprite-only variable values when they are created, each clone will be guaranteed to have the correct row and col when it is created.
Recursive Solution
This solution is a bit harder to understand than the first, so I would probably avoid it unless you're just looking for the novelty:
I have written below code for Back button event.
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
SceneManager.LoadScene("PreviousLevel");
}
}
In almost all cases this is fine. But I have found a small issue. When the user pauses the game, this doesn't work. When the user pauses the game, I do Time.timeScale=0. Initially, I gave a thought of modifying pause method and instead of doing Time.timeScale=0, use a bool variable and modify other pause logic accordingly. But then I also realized that I have over 14 co-routines whose logic is heavily dependent on Time.timeScale and modifying those will take a lot of time. They are heavily dependent on time.timeScale.
I wanted to know, is there any other method where I can write back button logic and which is not dependent on Time.timeScale.
It should work, input polling in Unity is not dependent on the time scale.
Try by inserting a Debug.Log inside the condition, and you should see it in the console.
Watch out if you put the if inside FixedUpdate and not Update: in that case it won't work since FixedUpdate is completely skipped when time scale is 0.
However, if you want a "dirty" trick, you can slow the timescale to a very low number, without using 0, i.e.: 10e-8. But use it with a lot of care, since it can lead to unwanted behaviour.
Input is dependent on time scale: GetButton() works normally but GetAxis() works inconsistently, for example getting mouse movement with GetAxis() works as expected, but getting Horizontal and Vertical returns 0 when timeScale is 0. You can get around this by using Input.GetAxisRaw().
It should also be noted that any axis also counts as a button, so you can also use GetButton() on those but the return value will be bool instead of float.
Im basically trying to make a segment of code run over and over once they tap once, and run only if the previous run was completed.
How would I do this exactly, Im completely new to Swift.
At the end of your first loop, put a variable that sets to true and then under the IBAction where they tap once, check if that variable is true or not and if it is true, do your re-loop.
Another way you could do it is loop in the viewDidLoad, which is called before any visuals appear. This way, there's no way they could tap the button or whatever you're monitoring until the view has appeared, which is a separate function.
But I doubt you need to wait for a loop to finish, because the execution time of a loop is so fast it will have happened before they can tap (unless it's a very long loop).
1) IBAction ( code would start to run)
2) You could use a if statement to check to see if what you want done is done.
3) You could use a for to determine how long the code is ran.