Jump to content
  • Advertisement
Sign in to follow this  
adt7

[.net] Is there a better way to present this interface?

This topic is 2859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently split out my "engine" code from my recently completed project so that I can use it as a library for any future projects.

I'm having difficulty with providing the interface I want from my library however.

Currently my InputManager has a method that can be used to map an actions to a button(s) with the following header:

public void AddMapping(InputAction action, params Buttons[] buttons)


InputAction is an enum, which is currently defined as follows:

public enum InputAction
{
Jump,
Use,
...
}


So for example the method could be used to map the A and B buttons to the Jump action:

InputManager.AddMapping(InputAction.Jump, Buttons.A, Buttons.B)


This all worked fine when the "engine" was part of the same project as the game, however now that I've seperated the two it causes problems.

I don't want InputAction to be predefined, I want this to be defined by the users (currently only me) of the library so they can have more flexibility.

The problem I'm having is that enums can't be inherited from though, so I can't define InputActions as an "abstract" enum and then have people inherit from it to add their own options.

One option would be to switch to the following, but it doesn't really sit well with me, as it's too generic and doesn't make the intention of the method clear.

public void AddMapping(Enum action, params Buttons[] buttons)


Defining InputActions as an abstract class and then expecting people to inherit use const int Value = 0 etc seems a complete mess to me and it's not obvious how it should be used.

The only other options I can think of is just to have InputAction to be completely generic:

public enum InputAction
{
Action1,
Action2,
...
}


This approach seems to defeat the point of using an enum though, as if I'm going down this route I might as well just use an int to define my actions.

So, is there a better way to present this interface across a library boundary, or am I stuck with picking one of the solutions above?

Share this post


Link to post
Share on other sites
Advertisement
You could use a Dictionary and store KeyValue pairs with whatever key mappings you want.



Dictionary<string, int> keyMappings = new Dictionary<string, int>();

keyMappings["jump"] = 13;
keyMappings["fire"] = 11;
keyMappings["walkForward"] = 5;
...



Share this post


Link to post
Share on other sites
I think I'll just go with using strings rather than an enum for now.

Doing string lookups each update doesn't seem the best way of doing things, but it's not like I'm trashing the CPU with enough that it's actually going to matter.

Share this post


Link to post
Share on other sites
Quote:
Original post by adt7
I think I'll just go with using strings rather than an enum for now.

Doing string lookups each update doesn't seem the best way of doing things, but it's not like I'm trashing the CPU with enough that it's actually going to matter.


Could you use objects instead of enums? That way you won't end up with 'typo' errors the compiler misses.

If you have an InputAction class, it just becomes a pointer/refernece compare. You can put a string in there for debugging:

InputAction Jump( "Jump" )
InputAction Punch( "Punch" )


AddMapping( Jump, Buttons.A, Buttons.B )
AddMapping( Punch, Buttons.A, Buttons.B )

InputAction action = Punch

Jump != action
Punch == action

Since they are all InputActions you can store them in lists, or arrays, or dictionaries. As long as they are classes, you get equality only if the pointer matches, unless you overload IsEqual().

Of course you cant switch on them, but you can load them into a dictionary with delegates just fine.

If you InputAction an interface only, the end user can do whatever he wants with the implementation, which might be useful for actions if you need to extend them for client reasons (is it currently valid, etc).



Why would this not work?

Share this post


Link to post
Share on other sites
You are talking about actions... use an action. By that I mean a System.Action. The you don't need the user to implement an interface, just provide a void method with no args. If there are arguments use Action<T>, Action<T,U> etc.

public void AddMapping(Action action, params Buttons[] buttons)
{
//mapping code
}

AddMapping( ()=> Console.WriteLine ("I happen when A is pressed"), Buttons.A );


If you need to "jump", Jump() rather than InputAction.Jump

AddMapping( () => Jump(), Buttons.A ), or better yet...

AddMapping( Jump, Buttons.A )

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!