Skip to content

Instantly share code, notes, and snippets.

@programmation
Last active August 3, 2018 03:32
Show Gist options
  • Save programmation/acd140048f7a3641d5609005868173b2 to your computer and use it in GitHub Desktop.
Save programmation/acd140048f7a3641d5609005868173b2 to your computer and use it in GitHub Desktop.
Framework defaults by Interface extensions
using System;
using System.Drawing;
// adapted from https://stackoverflow.com/a/37980328
namespace FrameworkInterface
{
public class Program
{
public static void Main(string[] args)
{
var model3 = new Tesla(new Robot() { Name = "Tesla" });
model3.AddMoveHandler ((s, e) => { ReportPosition($"{e.Name} Event", e.Speed, e.Position); });
model3.Move(42, 1, 1);
var googleCar = new GoogleCar(new Robot());
googleCar.set_Name("GoogleCar");
googleCar.AddMoveHandler((s, e) => { ReportPosition($"{e.Name} Event", e.Speed, e.Position); });
googleCar.Move(20, 2, 3);
Console.WriteLine($"{model3.AutoName} Speed: {model3.AutoSpeed} Position {model3.AutoPosition}");
Console.WriteLine($"{googleCar.get_Name()} Speed: {googleCar.get_Speed()} Position {googleCar.get_Position()}");
Console.ReadLine();
}
public static void ReportPosition(string robotName, double speed, PointF position)
{
Console.WriteLine($"Robot: {robotName} Speed: {speed} Position {position}");
}
}
public class MovedEventArgs : EventArgs
{
public string Name { get; private set; }
public double Speed { get; private set; }
public PointF Position { get; private set; }
public MovedEventArgs(string name, double speed, PointF position)
{
Name = name;
Speed = speed;
Position = position;
}
}
// Interface for the framework base class
public interface IRobot
{
event EventHandler<MovedEventArgs> Moved;
string Name { get; set; }
double Speed { get; }
PointF Position { get; set; }
void Move(double milliseconds, float deltaX, float deltaY);
void Move(TimeSpan interval, float deltaX, float deltaY);
}
// Framework base class
public class Robot : IRobot
{
public event EventHandler<MovedEventArgs> Moved;
public string Name { get; set; }
public double Speed { get; private set; }
public PointF Position { get; set; }
public void Move(double milliseconds, float deltaX, float deltaY)
{
Move(TimeSpan.FromMilliseconds(milliseconds), deltaX, deltaY);
}
public void Move(TimeSpan interval, float deltaX, float deltaY)
{
var position = Position;
Position = new PointF(Position.X + deltaX, Position.Y + deltaY);
Speed = Math.Sqrt(deltaX * deltaX + deltaY * deltaY) / interval.TotalMilliseconds;
Moved?.Invoke(this, new MovedEventArgs(Name, Speed, Position));
}
}
// Interface to be injected into non-framework classes
public interface IRobotic
{
IRobot Robot { get; }
}
// Default implementation of injected interface
public static class IRoboticHelper
{
public static string get_Name(this IRobotic robotic)
=> robotic.Robot.Name;
public static string set_Name(this IRobotic robotic, string name)
=> robotic.Robot.Name = name;
public static double get_Speed(this IRobotic robotic)
=> robotic.Robot.Speed;
public static PointF get_Position(this IRobotic robotic)
=> robotic.Robot.Position;
public static void AddMoveHandler(this IRobotic robotic, EventHandler<MovedEventArgs> handler)
{
robotic.Robot.Moved += handler;
}
public static void RemoveMoveHandler(this IRobotic robotic, EventHandler<MovedEventArgs> handler)
{
robotic.Robot.Moved -= handler;
}
public static void Move(this IRobotic robotic, double milliseconds, float x, float y)
{
robotic.Robot.Move(milliseconds, x, y);
}
public static void Move(this IRobotic robotic, TimeSpan interval, float x, float y)
{
robotic.Robot.Move(interval, x, y);
}
}
// Non-framework base class
public abstract class Automaton : IRobotic
{
public IRobot Robot { get; private set; }
public string AutoName => Robot?.Name;
public double AutoSpeed => Robot?.Speed ?? -1;
public PointF AutoPosition => Robot?.Position ?? PointF.Empty;
protected Automaton(IRobot robot)
{
Robot = robot;
}
}
// Application class
public class Tesla : Automaton
{
public Tesla(IRobot robot) : base(robot)
{
}
}
// Application class
public class GoogleCar : Automaton
{
public GoogleCar(IRobot robot) : base(robot)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment