Can checking for a condition be turned off when that condition is met and how would this be implemented (using language of your choosing)?
Example:
Say an if-statement runs inside an update function, I would like this if-statement not to be called when the statement has run true once in the lifecycle of the program. I'm thinking this might be achieved by wrapping the statement in a function variable(javascript) then reassigning that variable to return void if/when the condition is true.
Ok let’s say you have this (C++):
void update() {
// code
if (condition) {
// code
}
// code
}
What you can do is:
void update() {
// code
static bool already_ran = false;
if (!already_ran && condition) {
alreadu_ran = true;
// code
}
// code
}
static means that the variable retains it's value over function calls and in C/C++ the logical operators (&& in this example) are short-circuited. That means that they don’t evaluate the second operand unless they need. For instance if !already_ran is false then the whole expression is false regardless of condition so condition is not evaluated.
Not 100% sure this is more efficient than using a simple condition to run the increaseValue() function but here is the code I am using and it seems to work (in as3 at least). Update is being called approx 30 times a second.
public function update(){
if(isHit){ //isHit is part of another condition used by collision
increaseValues = function() {
this.height += 1;
this.width += 1;
this.x -= 1;
this.y -= 1;
this.alpha += -0.1;
if (this.alpha == 0){
increaseValues = function(){
return;
}
}
}
}
increaseValues();
}
Related
I want make one time or once execution syntax inside forever loop (void loop) for any program languages.
What i found the solution is with make new variable boolean "executed" and set to true after executed.
It's okay, but what if i want do once execution to other syntax? Should i make new variable boolean again? It will not effecient. Imagine theres many syntax but i must make new bool executiin for each syntax.
The solution is function i think
For example
void loop()
{
lcd.print("OK");
}
THIS IS WILL PRINT FOREVER
I wish theres function like this
void loop()
{
once(lcd.print("OK"));
}
so "once" is a function with parameter string which its for command/syntax.
once("command")
Several ways to approach this
Following is a very common way of how such an operation is usual made.
As you already suggested, with an global boolean:
bool once = true; // global variable
void loop() {
if (once) { // being called only once
lcd.print("OK");
once = false;
}
}
Do something only once after a specific time:
void loop() {
// millis() is the time in milliseconds after the startup
//if you want to print something once after a specific amount of time
//this also includes a little "wait time" of 100 milliseconds as the statement might be asked with a delay
if (mills() >= 1000 && mills() <= 1100) {// time in milliseconds
lcd.print("OK");
}
}
And thanks to this thread, with exiting the loop (might be not what you are searching for):
void loop() {
lcd.print("OK");
exit(0); //The 0 is required to prevent compile error.
}
But I suppose you are trying to make some kind of an interface, where a specific answer is printed regarding to the user input (probably many possibilities)?!
In that case it kind of depends on what inputs you are getting:
In case of Integers:
void loop() {
switch (input) { //input must be an integer
case 0:
lcd.print("OK"); //prints "ok" if input is 0
case 1:
lcd.print("Hello"); //prints "Hello" if input is 1
}
}
In case of Stings/chars, you need to go with an "if loop" trough every possible input(or with an array of Strings/chars):
void loop() {
lcd.print("Turn off?"); //asks if it should do something
if (input == "yes") { //String input
lcd.print("OK, shut down!");
//do something
}
else if (input == 'n' || input == 'N') { //char input
lcd.print("OK, no shut down!");
//do something
}
}
A function you are looking for, where a specific answer only prints ONCE regarding to an input can be just archived by if/else loops. If a String should be just printed once at startup, print it in the "setup()" constructor. Otherwise just with global booleans something like that is possible.
Note that those are only my suggestions based on my experience, but it does not necessarily mean that other solutions are not available.
Hope that helps still :)
Here is one way you can do it:
void loop()
{
{ // execute once. Can put this in a separate function also
static bool executed = (lcd.print("OK"), true);
}
}
You're guaranteed that this variable is initialized once.
If you want the once syntax in your question, you can achieve something similar with a macro:
#define ONCE(...) \
{\
static bool executed = ([&]{__VA_ARGS__;}(), true); \
}
void loop()
{
ONCE(lcd.print("OK"))
}
In C++, there is std::call_once which is even multi_thread, then you can do it generically:
template <typename F>
void simple_do_once(F f)
{
static std::once_flag flag;
std::call_once(flag, f);
}
As lambda have unique type, you have one flag by lambda:
Demo
I have a condition like the following where I just want to have the second bool be the trigger for a single time, since this condition is invoked relatively often I don't like the idea of doing the assignment of it being false every time the condition is true so, I tried to take advantage of the order of logical AND and OR and the post increment operator. But it appears to work don't do what I expected it to do. So is there a way to make a post state switch for this line?
where firstTitleNotSet is:
bool firstTitleNotSet;
if (titleChangedSinceLastGet() || (p_firstTitleNotSet && p_firstTitleNotSet++))
The idea is that the first part is the primary trigger and the second is the trigger that only has to trigger the first time.
While I easily could do
if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
firstTitleNotSet = false;
//...
}
I don't like this as it is reassigning false when ever the conditional block is invoked.
So is there some way of "post change" the value of a bool from true to false? I know that this would work the other way around but this would negate the advantage of the method most time being the true trigger and therefor skipping the following check.
Note: The reasons for me making such considerations isntead of just taking the second case is, that this block will be called frequently so I'm looking to optimize its consumed runtime.
Well, you could do something like:
if (titleChangedSinceLastGet() ||
(p_firstTitleNotSet ? ((p_firstTitleNotSet=false), true):false))
An alternative syntax would be:
if (titleChangedSinceLastGet() ||
(p_firstTitleNotSet && ((p_firstTitleNotSet=false), true)))
Either one looks somewhat ugly. Note, however, that this is NOT the same as your other alternative:
if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
p_firstTitleNotSet = false;
//...
}
With your proposed alternative, pontificate the fact that p_firstTitleNotSet gets reset to false no matter what, even if the conditional was entered because titleChangedSinceLastGet().
A more readable way than the assignment inside a ternary operator inside an or inside an if would be just moving the operations to their own statements:
bool needsUpdate = titleChangedSinceLastGet();
if(!needsUpdate && firstTitleSet)
{
needsUpdate = true;
firstTitleSet = false;
}
if(needsUpdate)
{
//...
}
This is likely to produce very similar assembly than the less readable alternative proposed since ternary operators are mostly just syntactic sugar around if statements.
To demonstrate this I gave GCC Explorer the following code:
extern bool first;
bool changed();
int f1()
{
if (changed() ||
(first ? ((first=false), true):false))
return 1;
return 0;
}
int f2()
{
bool b = changed();
if(!b && first)
{
b = true;
first = false;
}
return b;
}
and the generated assembly had only small differences in the generated assembly after optimizations. Certainly have a look for yourself.
I maintain, however, that this is highly unlikely to make a noticeable difference in performance and that this is more for interest's sake.
In my opinion:
if(titleChangedSinceLastUpdate() || firstTitleSet)
{
firstTitleSet = false;
//...
}
is an (at least) equally good option.
You can compare the assembly of the above functions with this one to compare further.
bool f3()
{
if(changed() || first)
{
first = false;
return true;
}
return false;
}
In this kind of situation, I usually write:
bool firstTitleNotSet = true;
if (titleChangedSinceLastGet() || firstTitleNotSet)
{
if (firstTileNotSet) firstTitleNotSet = false;
//...
}
That second comparison will likely be optimized by the compiler.
But if you have a preference for a post-increment operator:
int iterationCount = 0;
if (titleChangedSinceLastGet() || iterationCount++ != 0)
{
//...
}
Note that this will be a problem if iterationCount overflows, but the same is true of the bool firstTitleNotSet that you were post-incrementing.
In terms of code readability and maintainability, I would recommend the former. If the logic of your code is sound, you can probably rely on the compiler to do a very good job optimizing it, even if it looks inelegant to you.
That should work:
int firstTitleSet = 0;
if (titleChangedSinceLastGet() || (!firstTitleSet++))
If you wish to avoid overflow you can do:
int b = 1;
if (titleChangedSinceLastGet() || (b=b*2%4))
at the first iteration b=2 while b=0 at the rest of them.
So, i have a class called Vuelo, it has a method in which i can add a passenger to an airplane flight, i must check that the passenger id is not already in the array (the array is at first with all zeros), i must also check that there is enough space for another passenger to be added (max 10)
bool Vuelo :: agregarPasajero(int id)
{
int i = 0;
for(int iC = 0; iC < 10; iC++)
{
if (listaPasajeros[iC] == id)
{
i++;
return false;
}
}
if(i == 0)
{
if(cantidadPasajeros >= 10)
{
return false;
}
else
{
return true;
cantidadPasajeros++;
}
}
}
If i is not zero, you get to the end of the function without any kind of return statement. Since you declared the function to always return a bool, you should provide one for that case.
Now, you may know that i will never be zero at that spot, but the logic for that is fairly complex (I missed it on the first reading), and a compiler cannot be expected to realize that there is in fact no chance of control flow ever getting to the end of the function without encountering a return. In this case it's best to add a dummy return.
You can probably get away with not having a dummy return if you remove the bogus i == 0 test. i will necessarily always be zero at that point, since if it were ever increased, the function immediately returns false.
The statement cantidadPasajeros++; will never be executed since it is located after a return statement. Any halfway decent compiler also warns on that.
I want to check a condition inside a loop and execute a block of code when it's first met. After that, the loop might repeat but the block should be ignored. Is there a pattern for that? Of course it's easy to declare a flag outside of the loop. But I I'm interested in an approach that completely lives inside the loop.
This example is not what I want. Is there a way to get rid of the definition outside of the loop?
bool flag = true;
for (;;) {
if (someCondition() && flag) {
// code that runs only once
flag = false;
}
// code that runs every time
}
It's fairly hacky, but as you said it's the application main loop, I assume it's in a called-once function, so the following should work:
struct RunOnce {
template <typename T>
RunOnce(T &&f) { f(); }
};
:::
while(true)
{
:::
static RunOnce a([]() { your_code });
:::
static RunOnce b([]() { more_once_only_code });
:::
}
For a less convoluted version of Mobius's answer:
while(true)
{
// some code that executes every time
for(static bool first = true;first;first=false)
{
// some code that executes only once
}
// some more code that executes every time.
}
You could also write this using ++ on a bool, but that's apparently deprecated .
a possibly cleaner way to write this, albeit still with a variable, would be as follows
while(true){
static uint64_t c;
// some code that executes every time
if(c++ == 0){
// some code that executes only once
}
// some more code that executes every time.
}
The static allows you to declare the variable inside the loop, which IMHO looks cleaner. If your code that executes every time makes some testable change, you could get rid of the variable and write it like this:
while(true){
// some code that executes every time
if(STATE_YOUR_LOOP_CHANGES == INITIAL_STATE){
// some code that executes only once
}
// some more code that executes every time.
}
#include <iostream>
using namespace std;
int main()
{
int fav_num = 0;
while (true)
{
if ( fav_num == 0)
{
cout <<"This will only run if variable fav_number is = 0!"<<endl;
}
cout <<"Please give me your favorite number."<<endl;
cout <<"Enter Here: ";
cin >>fav_num;
cout <<"Now the value of variable fav_num is equal to "<<fav_num<<" and not 0 so, the if statement above won't run again."<<endl;
}
return 0;
}
OUTPUT
This will only run if variable fav_number is = 0!
Please give me your favorite number.
Enter Here: 1
Now the value of variable fav_num is equal to 1 and not 0 so, the "if statement" above won't run again.
If you know you only want to run this loop once, why not use break as the last statement in the loop.
1 while(true)
2 {
3 if(someCondition())
4 {
5 // code that runs only once
6 // ...
7 // Should change the value so that this condition must return false from next execution.
8 }
9
10 // code that runs every time
11 // ...
12 }
If you expecting the code without any external flag then you need to change the value of condition in last statement of the condition. (7th line in code snippet)
I am trying to increment a lap counter in my game by one but because I have to put this code in the game loop my counter goes over every time by about 500 instead or moving up one. Here is my code. The checkpointPassed variable is only true when a checkpoint is passed through. I know this works and the checkpoint number is the current checkpoint and they start at 0.
if(checkpointNumber == 0 && checkpointPassed == true)
{
lapNumber += 1;
}
I can't post the game loop because it is quite large.
Any Help is appreciated.
EDIT
Here is some more of the code so you can see what I am trying to do.
if(distance > carRadius && markerCounter < 5000)
{
if(checkpointPassed == true)
{
markerCounter++;
}
}
if(checkpointNumber == 0 && checkpointPassed == true)
{
lapNumber += 1;
}
if(distance < carRadius)
{
markerCounter++;
cross->SetX(checkpointX);
cross->SetY(checkpointY);
cross->SetZ(checkpointZ);
checkpointNumber += 1;
checkpointPassed = true;
}
if(markerCounter > 4999)
{
checkpointPassed = false;
cross->SetPosition(0,-50,0);
markerCounter = 0;
}
Add another two variable called inCheckpoint, which stores whether the user is currently "inside" the checkpoint or not. This allows you to detect when the user enters a checkpoint and only increment the lapNumber then. The code would look as follows:
if(checkpointNumber == 0 && checkpointPassed == true)
{
if (inCheckpoint == false) /* previously not inside a checkpoint */
lapNumber += 1;
inCheckpoint = true;
}
else
{
inCheckpoint = false;
}
UPDATE: Don't rely on checkpointPassed:
if(distance < carRadius)
{
if (inCheckpoint == false) /* previously not inside a checkpoint */
lapNumber += 1;
inCheckpoint = true;
}
else
{
inCheckpoint = false;
}
You could set/pass a gueard value that indicates how many iterations in the game loop you are (or whether this is the first iteration). If it is the first iteration (within the current lap), increment the variable as you do now, otherwise don't
You will need to reset this guard value for each lap -- e.g. right after you increment lapNumber.
You might need to cancel the 'checkpointPassed` state.
if (checkpointNumber == 0 && checkpointPassed == true)
{
lapNumber += 1;
checkpointPassed = false;
}
This means that you won't be counting the lap again until the next time a checkpoint is passed, which is presumably when you need it counted.
However, if you need checkpointPassed true later in the loop, then you'll need to think whether you need yet another variable, such as lapCounted, which is set to false when checkpointPassed is set to true, and reset to true by the code above (instead of setting checkpointPassed, not as well as setting it).
If I understand correctly what you said, your 'if' statement is inside the main loop and when you pass a checkpoint, 'checkpointPassed' becomes true. For how long?
If it stays 'true' for a few iterations, then each time your game loop does an iteration,your lap counter is incremented. In this case, you should either set checkPointPassed to false at the end of the iteration, or use a different variable, that you set to true at the same time that checkPointPassed becomes true and false after incrementing.
If this does not answer your question, can you give a little more context as with only this part of the code, it is hard to figure out what you want to do.