Skip to content

Instantly share code, notes, and snippets.

@pbackus
Created December 19, 2019 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pbackus/f61734804a627d379c7916f783ea7725 to your computer and use it in GitHub Desktop.
Save pbackus/f61734804a627d379c7916f783ea7725 to your computer and use it in GitHub Desktop.
Actions and Entities
import std.stdio: writeln;
interface Entity
{
string name();
}
class EntityAdapter(T) : Entity
{
T payload;
this(T payload)
{
this.payload = payload;
}
override string name()
{
return payload.name;
}
}
Entity entity(T)(T payload)
{
return new EntityAdapter!T(payload);
}
struct Player
{
string name;
int level;
}
struct NPC
{
string name;
}
interface Action
{
void applyTo(ref Entity);
}
class ActionAdapter(T) : Action
{
T payload;
this(T payload)
{
this.payload = payload;
}
override void applyTo(ref Entity entity)
{
payload.applyTo(entity);
}
}
Action action(T)(T payload)
{
return new ActionAdapter!T(payload);
}
struct SayHello
{
void applyTo(ref Entity entity)
{
writeln("Hello, ", entity.name, ".");
}
}
struct SayGoodbye
{
void applyTo(ref Entity entity)
{
writeln("Goodbye, ", entity.name, ".");
}
}
void main()
{
Action[] actions = [action(SayHello()), action(SayGoodbye())];
Entity[] entities = [entity(Player("Link", 12)), entity(NPC("Zelda"))];
foreach (action; actions)
foreach (entity; entities)
action.applyTo(entity);
}
/+dub.sdl:
dependency "sumtype" version="~>0.9.4"
+/
import std.stdio: writeln;
import std.traits: hasMember;
import sumtype;
enum bool isEntity(T) = hasMember!(T, "name");
struct Player
{
string name;
int level;
}
struct NPC
{
string name;
}
static assert(isEntity!Player);
static assert(isEntity!NPC);
alias Entity = SumType!(Player, NPC);
enum bool isAction(T) = hasMember!(T, "applyTo");
struct SayHello
{
void applyTo(T)(ref T entity)
if (isEntity!T)
{
writeln("Hello, ", entity.name, ".");
}
}
struct SayGoodbye
{
void applyTo(T)(ref T entity)
if (isEntity!T)
{
writeln("Goodbye, ", entity.name, ".");
}
}
alias Action = SumType!(SayHello, SayGoodbye);
void applyTo(Action action, Entity entity)
{
entity.match!(
e => action.match!(
a => a.applyTo(e)
)
);
}
void main()
{
Action[] actions = [Action(SayHello()), Action(SayGoodbye())];
Entity[] entities = [Entity(Player("Link", 12)), Entity(NPC("Zelda"))];
foreach (action; actions)
foreach (entity; entities)
action.applyTo(entity);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment