- Home /
How to make a function wait untill a specific bool is true?
Here's a piece of code that i want to execute but how can i wait for a specific bool to be true inside a function
bool one = false;
bool two = false;
public bool A(){
if (B())
return true;
else
return false;
}
private bool B(){
one = false;//1
StartCoroutine (C ());//2
// I need to wait until bool two is true and then return one
yield return one;//5
}
private IEnumerator C (){
two = false;//3
yield return new WaitForSeconds (1f);
if(something is true)
one = true;
else
one = false;
yield return one;
two = true;//4
}
My current execution order is 1,2,5,3,4 but i need the execution order as 1,2,3,4,5. Please Help??
Answer by Hellium · Jan 18, 2018 at 10:53 AM
Further to your real code, here is how I would do it. I haven't tested the following code though.
#region Checking For Internet
public void CheckForInternet( System.Action onInternetAvailable, System.Action onInternetUnavailable )
{
if( !IsInternetReachable() )
{
if( onInternetUnavailable != null )
onInternetUnavailable();
return ;
}
StartCoroutine( CheckForInternetConnectivityIEnum( onInternetAvailable, onInternetUnavailable ) ) ;
}
private bool IsInternetReachable()
{
return Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork || Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork ;
}
System.Collections.IEnumerator CheckForInternetConnectivityIEnum(System.Action onInternetAvailable, System.Action onInternetUnavailable)
{
WWW www = new WWW ("some api which gives sucess 1");
yield return www;
if ( www.error == null )
{
JsonData jsonDat = JsonMapper.ToObject (www.text);
Debug.Log( "Login API success = " + jsonDat["success"] );
if ( jsonDat["success"].ToString() == "1" )
{
if( onInternetAvailable != null )
onInternetAvailable();
}
else
{
if( onInternetUnavailable != null )
onInternetUnavailable();
}
}
else if( onInternetUnavailable != null )
onInternetUnavailable();
}
#endregion
And call it as follow :
public void Foo()
{
CheckForInternet( OnInternetAvailable, OnInternetUnavailable ) ;
}
public void OnInternetAvailable()
{
Debug.Log("Internet is available");
}
public void OnInternetUnavailable ()
{
Debug.LogWarning("Internet is unavailable");
}
INITIAL ANSWER
I don't think what you are trying to achieve is possible without more coroutines and callbacks. Here is my suggestion:
bool one = false;
bool two = false;
public void A( System.Action<bool> onResultFetched )
{
StartCoroutine( B( onResultFetched ) );
}
private System.Collections.IEnumerator B( System.Action<bool> onResultFetched )
{
one = false;
yield return StartCoroutine( C() );
onResultFetched.Invoke( one );
}
private System.Collections.IEnumerator C()
{
two = false;
yield return new WaitForSeconds( 1f );
if ( something is true )
one = true;
else
one = false;
two = true;
}
And then, you call A
with a callback:
private void Test()
{
A( ( result ) => Debug.Log( result ) );
}
wow!! this works great but how do i get the return type from Test is that possible i could alter my code according to yours but i would be needing a return type from Test
What do you mean by "get the return type from Test"? Do you want Test
to have a return type? Or do you want A
to have a return type?
It's possible to have a return type to A
or Test
but you won't be able to return the value of one
or two
.
I just want to receive a Boolean value from the function Test() on the bases of A( ( result ) => Debug.Log( result ) ); result.
please see the code attached
#region Checking For Internet
public bool CheckForInternet(){
if (CheckForInternetReachability ()) {
Debug.Log ("1");
// StartCoroutine (CheckForInternetConnectivityIEnum ());
bool output= false;
Debug.Log("output"+output);
CheckForInternetConnectivity ((result) =>( output = result));
Debug.Log("output"+output);
if (output) {
Debug.Log ("1t");
return true;
} else {
Debug.Log ("1f");
return false;
}
} else {
Debug.Log ("1ff");
return false;
}
}
private bool CheckForInternetReachability(){
if (Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork || Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork) {
Debug.Log ("2");
return true;
} else {
Debug.Log ("2f");
return false;
}
}
private bool IsNetApiWorking;
bool IsApiHitted = false;
private IEnumerator CheckForInternetConnectivity(Action<bool> onResultFetched){
Debug.Log ("net check 11111");
IsNetApiWorking = false;
Debug.Log ("net check 2222");
yield return StartCoroutine (CheckForInternetConnectivityIEnum ());
onResultFetched.Invoke (IsNetApiWorking);
}
IEnumerator CheckForInternetConnectivityIEnum(){
IsApiHitted = false;
WWW www = new WWW ("some api which gives sucess 1");
yield return www;
Debug.Log ("net check 33333");
if (www.error == null) {
Debug.Log ("net check 44444");
JsonData jsonDat = Json$$anonymous$$apper.ToObject (www.text);
Debug.Log ("Login API success = " + jsonDat ["success"]);
if (jsonDat ["success"].ToString () == "1") {
Debug.Log ("net check 55555");
IsNetApiWorking = true;
}
else {
Debug.Log ("net check 6666");
IsNetApiWorking = false;
}
}
else {
Debug.Log ("net check 77777");
IsNetApiWorking = false;
}
IsApiHitted = true;
Debug.Log ("net check 88888");
}
#endregion
Thanks allot @Hellium you are a true savior you helped me allot I'm totally new to callbacks but I'm understanding them. I will accept this answer but i just need one more thing how to return a Boolean value from the function Foo()
or function CheckForInternet()
or like which of the callbacks called
The problem is that you can't do it because you rely on asynchronous checking (because of the coroutine). Because of this, you have no choice but using callbacks, and you can't return a value (only possible in a synchronous system)
So there isn't a way out of this ?? Could I use System.Threading.SpinWait.SpinUntil
but that would max out my CPU usage. Right?
Answer by andreim44 · Jan 18, 2018 at 10:15 AM
I think you're looking for
yield return new WaitUntil( () => B() );
// where B is your boolean method.
In your case, use
yield return new WaitUntil( () => two == true );
could you please explain it better? my boolean method is B so i cannot yield the method B where do i use yield return wait until in fucntion B or IEnumrator C
As I understand, you would use this where your comment is, where you want to wait for two to be true. (you would have to turn method B into a coroutine to be able to use wait however)
but that in turn would end up changing the return type of the B which i'm afraid will change whole my game flow