{"action":"created","issue":{"url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/issues/59","labels_url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/issues/59/labels{/name}","comments_url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/issues/59/comments","events_url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/issues/59/events","html_url":"https://github.com/craftworkgames/MonoGame.Extended/issues/59","id":107299141,"number":59,"title":"Interfaces for a cleaner design and more flexibility","user":{"login":"craftworkgames","id":3201643,"avatar_url":"https://avatars.githubusercontent.com/u/3201643?v=3","gravatar_id":"","url":"https://api.github.com/users/craftworkgames","html_url":"https://github.com/craftworkgames","followers_url":"https://api.github.com/users/craftworkgames/followers","following_url":"https://api.github.com/users/craftworkgames/following{/other_user}","gists_url":"https://api.github.com/users/craftworkgames/gists{/gist_id}","starred_url":"https://api.github.com/users/craftworkgames/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/craftworkgames/subscriptions","organizations_url":"https://api.github.com/users/craftworkgames/orgs","repos_url":"https://api.github.com/users/craftworkgames/repos","events_url":"https://api.github.com/users/craftworkgames/events{/privacy}","received_events_url":"https://api.github.com/users/craftworkgames/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/labels/question","name":"question","color":"cc317c"}],"state":"closed","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/milestones/5","html_url":"https://github.com/craftworkgames/MonoGame.Extended/milestones/Version%200.5","labels_url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/milestones/5/labels","id":1491350,"number":5,"title":"Version 0.5","description":"By the end of this version I want to have completed small game demo to show off the library and make improvements discovered by using it in a real game.","creator":{"login":"craftworkgames","id":3201643,"avatar_url":"https://avatars.githubusercontent.com/u/3201643?v=3","gravatar_id":"","url":"https://api.github.com/users/craftworkgames","html_url":"https://github.com/craftworkgames","followers_url":"https://api.github.com/users/craftworkgames/followers","following_url":"https://api.github.com/users/craftworkgames/following{/other_user}","gists_url":"https://api.github.com/users/craftworkgames/gists{/gist_id}","starred_url":"https://api.github.com/users/craftworkgames/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/craftworkgames/subscriptions","organizations_url":"https://api.github.com/users/craftworkgames/orgs","repos_url":"https://api.github.com/users/craftworkgames/repos","events_url":"https://api.github.com/users/craftworkgames/events{/privacy}","received_events_url":"https://api.github.com/users/craftworkgames/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":3,"state":"open","created_at":"2016-01-08T12:26:34Z","updated_at":"2016-01-08T12:51:58Z","due_on":null,"closed_at":null},"comments":5,"created_at":"2015-09-19T00:31:35Z","updated_at":"2016-01-08T15:51:39Z","closed_at":"2016-01-08T12:34:16Z","body":"I've been thinking about this for a while. I think it's time we talked about creating some interfaces for common methods and properties.\r\n\r\n## Updating\r\n\r\nThe first one is to cover the reuse of an `Update` method so that many *updatables* can be added to a collection of `List<IUpdate> _updatables`. Something like this:\r\n\r\n    public interface IUpdate\r\n    {\r\n         void Update(GameTime gameTime);\r\n    }\r\n\r\nPersonally I've never been a huge fan of `GameTime`. I'd rather just pass around a `float deltaSeconds` in most cases because it makes the class reusbale outside MonoGame / XNA. Most people that using MonoGame seem to like `GameTime` so I guess I can live with that.\r\n\r\nUnfortunately, the framework already contains an interface called [`IUpdatable`](https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.iupdateable_members.aspx) that looks like this:\r\n\r\n```\r\n  public interface IUpdateable\r\n  {\r\n    bool Enabled { get; }\r\n    int UpdateOrder { get; }\r\n    event EventHandler<EventArgs> EnabledChanged;\r\n    event EventHandler<EventArgs> UpdateOrderChanged;\r\n    void Update(GameTime gameTime);\r\n  }\r\n```\r\n\r\nThe problem with the `IUpdatable` interface is that it has too much going on. A lot of the time when you want to implement an `Update` method you don't need or want the other crap. Particularly `UpdateOrder`. Using this interface makes it more complicated to implement the class and IMHO doesn't add a lot of value.\r\n\r\nOf course, there's no reason why a class couldn't implement both interfaces.\r\n\r\n## Drawing\r\n\r\nSimilarly to the updating I propose we have a simpler `IDraw` interface.\r\n\r\n    public interface IDraw\r\n    {\r\n        void Draw(GameTime gameTime);\r\n    }\r\n\r\nThis would be the sibling on the [`IDrawable`](https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.idrawable_members.aspx) interface from the framework.\r\n\r\n## Common Properties\r\n\r\nI also think there's a few property based interfaces that are helpful.\r\n\r\n    public interface IRotatable\r\n    {\r\n        float Rotation { get; set; }\r\n    }\r\n\r\n    public interface IMovable\r\n    {\r\n        Vector2 Position { get; set; }\r\n    }\r\n\r\n    public interface IScalable\r\n    {\r\n        Vector2 Scale { get; set; }\r\n    }\r\n\r\n    public interface ITranfromable : IMovable, IRotatable, IScalable\r\n    {\r\n    }\r\n\r\n    public interface IColorable\r\n    {\r\n        Color Color { get; set; }\r\n    }\r\n\r\nThe benefit of breaking these up into one interface per property is that we can write nice extension methods, for example in an Animation library you might have some extension methods like this:\r\n\r\n    public void MoveTo(this IMovable movable,  Vector2 position);\r\n    public void RotateTo(this IRotatable rotatable, float angle);\r\n    public void ScaleTo(this IScalable scalable,  Vector2 scale);\r\n    public void FadeTo(this IScalable colorable,  Color color);\r\n\r\nThen these methods become available on any class that have the respective properties. The class can pick which of the properties it wants and leave out the others. For example, it's common to have `Position` and `Rotation` without scale or color.\r\n\r\n\r\n## Naming conventions and clashes\r\n\r\nI think the advantages of having interfaces like these is clear but [naming them is hard](http://martinfowler.com/bliki/TwoHardThings.html). The names I've proposed above are okay, but they could also be called `IMove`, `IRotate`, `IScale` and `IColor` or something else.\r\n\r\nOne concern is that game developers trying to use MonoGame.Extended in an existing project might end up with name clashes if they already have similar interfaces defined. Although, we may not be able to do anything about that unless we pick obscure names which I'd really rather avoid.\r\n\r\nThoughts?\r\n"},"comment":{"url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/issues/comments/170037212","html_url":"https://github.com/craftworkgames/MonoGame.Extended/issues/59#issuecomment-170037212","issue_url":"https://api.github.com/repos/craftworkgames/MonoGame.Extended/issues/59","id":170037212,"user":{"login":"cupstudio","id":2867593,"avatar_url":"https://avatars.githubusercontent.com/u/2867593?v=3","gravatar_id":"","url":"https://api.github.com/users/cupstudio","html_url":"https://github.com/cupstudio","followers_url":"https://api.github.com/users/cupstudio/followers","following_url":"https://api.github.com/users/cupstudio/following{/other_user}","gists_url":"https://api.github.com/users/cupstudio/gists{/gist_id}","starred_url":"https://api.github.com/users/cupstudio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cupstudio/subscriptions","organizations_url":"https://api.github.com/users/cupstudio/orgs","repos_url":"https://api.github.com/users/cupstudio/repos","events_url":"https://api.github.com/users/cupstudio/events{/privacy}","received_events_url":"https://api.github.com/users/cupstudio/received_events","type":"User","site_admin":false},"created_at":"2016-01-08T15:51:39Z","updated_at":"2016-01-08T15:51:39Z","body":"Awesome!  Thanks for taking the time to add some of that insight.  Right now I am working on updating my forms framework to fully rely on MGE for anything it can so that I can remove a lot of the duplicated functionality.  I will probably continue sharing SpriteBatches for things like buttons and other small controls.  When it comes to scrolling those controls obviously need to start a new SpriteBatch in order to use Scissor Rectangles.\r\n"}}