How to access a caller variable from a callback class whatever the caller is ?

Hi,

I use a unique callback class to handle many situation, in which I need to access variables or components from the caller. I found this way to do, not sure it’s the best, but it works :

public class MyCallBack : App42CallBack
{  
	public GameObject caller;

		switch (caller.name) {
		case "Server Panel":
 			caller.GetComponent<ServerManager>().Method();
			caller.GetComponent<ServerManager>().variable = true;
			caller.GetComponent<ServerManager>().Interactive(true);
  			break;
		case "NewUser Panel":
 			caller.GetComponent<NewUserManager>().Method();
			caller.GetComponent<NewUserManager>().variable = true;
			caller.GetComponent<NewUserManager>().Interactive(true);
			break;
		case "Login Panel":
			caller.GetComponent<LoginManager>().Method();
			caller.GetComponent<LoginManager>().variable = true;
			caller.GetComponent<LoginManager>().Interactive(true);
			break;
		}
}

In the caller class :

MyCallBack mcb = new MyCallBack();
mcb.caller = this.gameObject;

Is it possible to simplify the code with one generic reference and get rid of the switch ?

private ???? ref = caller.GetComponent<?????>();
ref.Method();
ref.variable = true;
ref.Interactive(true);

Thanks

hey bro yes you can achieve it with an abstract class
watch this example i made and try to understand it
this will invoke the right method

public abstract class BaseClass : MonoBehaviour
{
	string someString;
	public abstract void Method ();

	public virtual void setVariable ()
	{
		someString = "hello";
		print ("set variable of base class invoked so it was not overriden");
	}

	public abstract void setInteractive (bool interactive);


}
public class NewUserManager : BaseClass
{
	#region implemented abstract members of BaseClass

	public override void Method ()
	{
		print ("method of new user manager invoked");
	}

	public override void setVariable ()
	{
		print ("set variable of new user manager invoked");
	}

	public override void setInteractive (bool interactive)
	{
		print ("set interactive of new user manager invoked");
	}

	#endregion
}
public class LoginManager : BaseClass
{
	#region implemented abstract members of BaseClass
	public override void Method ()
	{
		print ("method of login manager invoked");
	}
	public override void setVariable ()
	{
		print ("set variable of login manager invoked");
	}
	public override void setInteractive (bool interactive)
	{
		print ("set interactive of login managerinvoked");
	}
	#endregion	
}
public class SomeOtherClass : MonoBehaviour
{
	public void doSomething(GameObject caller)
	{
		BaseClass bc = (BaseClass)caller.GetComponent(typeof(BaseClass));
		bc.Method ();
		bc.setInteractive (true);
		bc.setVariable ();
	}
}

Even though an abstract base class would work, in most cases it’s not recommended especially if the different classes doesn’t really share the same base structure. Also using base classes restrict you to one inheritance tree.

The better approach is to use an interface. An interface allows you to define methods / properties which a class must implement if the class implements that interface. An interface definition (unlike abstract classes) can’t contain actual code or variables (fields) but only method and property definitions. However interfaces have the advantange that a class can implement as many interfaces you like.

public interface IUIComponent
{
    void Method();
    bool variable {get; set;}
    void Interactive(bool aBoolParam);
}

A class can implement that interface:

public class ServerManager : MonoBehaviour, IUIComponent
{
    // [...]
    public void Method()
    {
        //...
    }
    public bool variable { get; set; }
    public void Interactive(bool aActive)
    {
        // ...
    }
}

And finally you can use the interface to access any component that implements that interface:

IUIComponent ui = caller.GetComponent<IUIComponent>();
ui.Method ();
ui.variable = true;
ui.setInteractive (true);

Note that “variable” is not a variable but a property. Properties can be used like variables but are actually a pair of methods, one get and one set method. In my example the ServerManager class implements an “auto-property” which basically does this for you:

private bool _internal_variable;
public bool variable {
    get { return _internal_variable;}
    set { _internal_variable = value;}
}

So when you assign a value to the property you actually call the “set” method which receives the assigned value inside the special “value” parameter. When you read the property you actually call the get method.

@ExtinctSpecie, and @Bunny83
I really thank you very much for those very detailed examples based on my own one !
I learned so much, and I am pretty sure both technics will be useful in a near future.

My post needed to be validate by a moderator. Since, I watched the Intermediate Gameplay Scripting tutorials, but they are so short (!) and I practiced a lot more. That make me realize that I forgot an important information : App42 is a plugin API from shephertz.com so I can’t edit it !

No matter, I have just tried this …

public class PowerManager : MonoBehaviour, App42CallBack { ... }

… and it work like a charm :smiley:

BTW, you answered to another question i post a few hours ago and was still awaiting moderation…

Great !

[EDIT]

For any one stuck like me with basic c#, you need to copy past all the code that was inside App42CallBack class inside your MonoBahaviour’s that contains the calling method and modify it’s callback function to “this” (without the double quotes)

app42service.SomeMethod(param1, param2,new MyCallBack());
// change to 
app42service.SomeMethod(param1, param2,this);

[\EDIT]