Created
October 22, 2014 21:08
-
-
Save MrSmith33/4a21a1e7e46fa6c0ac22 to your computer and use it in GitHub Desktop.
Modular
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module modular.modules.eventdispatchermodule; | |
import modular; | |
// Basic event | |
abstract class Event | |
{ | |
bool continuePropagation = true; | |
} | |
void subscribeToEvent(E : Event)(EventDispatcherModule dispatcher, void delegate(E event) handler) | |
{ | |
dispatcher.subscribe(typeid(E), cast(EventHandler)handler); | |
} | |
void postEvent(E : Event)(EventDispatcherModule dispatcher, E event) | |
{ | |
dispatcher.post(typeid(E), cast(Event)event); | |
} | |
private alias EventHandler = void delegate(Event event); | |
/// Event | |
class EventDispatcherModule : IModule | |
{ | |
override string name() @property { return "EventDispatcherModule"; } | |
override string semver() @property { return "0.1.0"; } | |
override void load() { } | |
override void init(IModuleManager moduleman) {} | |
void subscribe(TypeInfo evtype, void delegate(Event event) handler) | |
{ | |
_eventHandlers[evtype] ~= handler; | |
} | |
void post(TypeInfo evtype, Event event) | |
{ | |
auto handlers = evtype in _eventHandlers; | |
if (!handlers) return; | |
foreach(handler; *handlers) | |
{ | |
handler(event); | |
if (!event.continuePropagation) return; | |
} | |
} | |
private: | |
EventHandler[][TypeInfo] _eventHandlers; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module modular.imodule; | |
import modular; | |
/// Basic module interface. | |
interface IModule | |
{ | |
// i.e. "Test Module" | |
string name() @property; | |
// valid semver version string. i.e. 0.1.0-rc.1 | |
string semver() @property; | |
// load/create needed resources | |
void load(); | |
// get references to other modules | |
void init(IModuleManager moduleman); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module modular.imodulemanager; | |
import modular; | |
interface IModuleManager | |
{ | |
/// Returns reference to module instance if moduleName was registered. | |
IModule findModule(string moduleName); | |
} | |
M getModule(M)(IModuleManager modman, string moduleName = M.stringof) | |
{ | |
import std.exception : enforce; | |
IModule mod = modman.findModule(moduleName); | |
M exactModule = cast(M)mod; | |
enforce(exactModule); | |
return exactModule; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module modular.modules.mainloopmodule; | |
import modular; | |
import modular.modules.eventdispatchermodule; | |
/// Updatable module interaface. | |
/// Look at MainLoopModule.registerUpdatableModule(IUpdatableModule) | |
interface IUpdatableModule | |
{ | |
/// Will be called by MainLoopModule every frame | |
void update(double delta); | |
} | |
interface IMainLoopModule | |
{ | |
void registerUpdatableModule(IUpdatableModule updatableModule); | |
bool isRunning() @property; | |
bool isRunning(bool newIsRunning) @property; | |
} | |
class GameStopEvent : Event | |
{ | |
} | |
/// Module where the main loop is located | |
class MainLoopModule : IMainLoopModule, IModule | |
{ | |
override string name() @property { return "MainLoopModule"; } | |
override string semver() @property { return "0.1.0"; } | |
override void load() {} | |
override void init(IModuleManager moduleman) | |
{ | |
evdisp = moduleman.getModule!EventDispatcherModule(); | |
} | |
private: | |
EventDispatcherModule evdisp; | |
IUpdatableModule[] updatableModules; | |
bool _isRunning; | |
public: | |
// There is an option to auto-register all modules found in IModuleManager | |
// if they can be cast to IUpdatableModule | |
override void registerUpdatableModule(IUpdatableModule updatableModule) | |
{ | |
updatableModules ~= updatableModule; | |
} | |
/// Main loop execution condition. Will run if true. | |
override bool isRunning() @property | |
{ | |
return _isRunning; | |
} | |
/// ditto | |
override bool isRunning(bool newIsRunning) @property | |
{ | |
return _isRunning = newIsRunning; | |
} | |
/// Simple main loop | |
void mainLoop() | |
{ | |
import std.datetime : TickDuration, Clock, msecs, usecs; | |
import core.thread : Thread; | |
isRunning = true; | |
TickDuration lastTime = Clock.currAppTick; | |
TickDuration newTime = TickDuration.from!"seconds"(0); | |
while(isRunning) | |
{ | |
newTime = Clock.currAppTick; | |
double delta = (newTime - lastTime).usecs / 1_000_000.0; | |
lastTime = newTime; | |
update(delta); | |
Thread.sleep(10.msecs); | |
} | |
// loop stop | |
// event example | |
evdisp.postEvent(new GameStopEvent); | |
} | |
private void update(double delta) | |
{ | |
foreach(mod; updatableModules) | |
{ | |
mod.update(delta); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module modular.modulemanager; | |
import modular; | |
/// Simple implementation of IModuleManager | |
// See GameModule for example usage | |
class ModuleManager : IModuleManager | |
{ | |
IModule[string] modules; | |
void registerModule(IModule moduleInstance) | |
{ | |
assert(moduleInstance); | |
modules[moduleInstance.name] = moduleInstance; | |
} | |
void loadModules() | |
{ | |
foreach(IModule m; modules) | |
{ | |
m.load(); | |
writefln("Loaded module %s %s", m.name, m.semver); | |
} | |
} | |
void initModules() | |
{ | |
foreach(IModule m; modules) | |
{ | |
m.init(this); | |
writefln("Inited module %s %s", m.name, m.semver); | |
} | |
} | |
override IModule findModule(string moduleName) | |
{ | |
return modules[moduleName]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module modular.modules.networkmodule; | |
import modular; | |
import modular.modules.mainloopmodule; | |
class NetworkModule : IModule, IUpdatableModule | |
{ | |
override string name() @property { return "NetworkModule"; } | |
override string semver() @property { return "0.1.0"; } | |
override void load() | |
{ | |
// load enet | |
registerPacket!PacketMapPacket(); | |
} | |
override void init(IModuleManager moduleman) | |
{ | |
mainmod = moduleman.getModule!MainLoopModule("MainLoopModule"); | |
mainmod.registerUpdatableModule(this); | |
} | |
override void update(double delta) | |
{ | |
// enet_host_service | |
} | |
// | |
void registerPacket(P)() | |
{ | |
packets ~= typeid(P); | |
} | |
private: | |
MainLoopModule mainmod; | |
TypeInfo[] packets; | |
} | |
struct PacketMapPacket | |
{ | |
string[] packets; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment