summaryrefslogtreecommitdiff
path: root/src/io
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2017-11-28 17:14:02 +0100
committernsensfel <SpamShield0@noot-noot.org>2017-11-28 17:14:02 +0100
commitf539b7072c357339328d9bfd54f1f1ed51828586 (patch)
treeb6205dd79c78090831e812aceac177d2a9f35d28 /src/io
parent80358376b9300a0d73cb8b62dfa9fdd65240ca66 (diff)
Trying to tidy up this mess.
Diffstat (limited to 'src/io')
-rw-r--r--src/io/database_shim.erl94
-rw-r--r--src/io/timed_cache.erl85
-rw-r--r--src/io/timed_caches_manager.erl141
3 files changed, 320 insertions, 0 deletions
diff --git a/src/io/database_shim.erl b/src/io/database_shim.erl
new file mode 100644
index 0000000..243051b
--- /dev/null
+++ b/src/io/database_shim.erl
@@ -0,0 +1,94 @@
+-module(database_shim).
+-export
+(
+ [
+ generate_db/1,
+ fetch/2,
+ commit/3
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+create_db (_Heir) ->
+ ets:new
+ (
+ db_shim,
+ [
+ set,
+ public,
+ named_table,
+ {keypos, 1},
+ {read_concurrency, true}
+ ]
+ ),
+ io:format("~ndb_shim ets created.~n").
+
+add_to_db (ID, Val) ->
+ io:format("~nadd to db_shim: ~p.~n", [{ID, Val}]),
+ ets:insert(db_shim, {ID, Val}).
+
+generate_char_instances (Battlemap, Characters) ->
+ lists:map
+ (
+ fun (Char) ->
+ {
+ character:get_id(Char),
+ character_instance:new_instance_of
+ (
+ Char,
+ (rand:uniform(2) - 1), % team,
+ {
+ rand:uniform(battlemap:get_width(Battlemap) - 1), % X
+ rand:uniform(battlemap:get_heigth(Battlemap) - 1) % Y
+ }
+ )
+ }
+ end,
+ Characters
+ ).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+generate_db (Heir) ->
+ Pid = self(),
+ spawn(fun () -> create_db(Heir), Pid ! ok, receive ok -> ok end end),
+ receive
+ ok -> ok
+ end,
+ Players = [<<"0">>, <<"1">>],
+ Battlemap = battlemap_shim:generate_random(),
+ Characters = character_shim:generate_random(rand:uniform(12) + 4),
+ CharacterInsts = generate_char_instances(Battlemap, Characters),
+ BattlemapInstance =
+ battlemap_instance_shim:generate_random
+ (
+ CharacterInsts,
+ Players
+ ),
+ add_to_db({battlemap_db, battlemap:get_id(Battlemap)}, Battlemap),
+ lists:map
+ (
+ fun (Char) ->
+ add_to_db({character_db, character:get_id(Char)}, Char)
+ end,
+ Characters
+ ),
+ add_to_db
+ (
+ {battlemap_instance_db, battlemap_instance:get_id(BattlemapInstance)},
+ BattlemapInstance
+ ).
+
+fetch (DB, ObjectID) ->
+ io:format("~ndb_shim lookup: ~p.~n", [{DB, ObjectID}]),
+ case ets:lookup(db_shim, {DB, ObjectID}) of
+ [{_Key, Value}] -> {ok, Value};
+ [] -> nothing
+ end.
+
+commit (DB, ObjectID, Value) ->
+ add_to_db({DB, ObjectID}, Value),
+ timed_cache:invalidate(DB, ObjectID).
diff --git a/src/io/timed_cache.erl b/src/io/timed_cache.erl
new file mode 100644
index 0000000..c86caab
--- /dev/null
+++ b/src/io/timed_cache.erl
@@ -0,0 +1,85 @@
+-module(timed_cache).
+-behavior(gen_server).
+
+%%%% gen_server exports
+-export
+(
+ [
+ init/1,
+ handle_cast/2,
+ handle_call/3, %% No reply will ever be given.
+ terminate/2,
+ code_change/3,
+ format_status/2,
+ handle_info/2
+ ]
+).
+
+%%%% actual interface
+-export
+(
+ [
+ fetch/2,
+ invalidate/2
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+add_to_cache (DB, ObjectID) ->
+ {ok, TimerPID} = gen_server:start(?MODULE, {DB, ObjectID}, []),
+ {ok, Data} = database_shim:fetch(DB, ObjectID),
+ ets:insert(DB, {ObjectID, TimerPID, Data}),
+ Data.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% gen_server
+
+init ({DB, ObjectID}) ->
+ {ok, {DB, ObjectID}}.
+
+handle_call (invalidate, _, State) ->
+ {stop, normal, State};
+handle_call (ping, _, {DB, ObjectID}) ->
+ {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout(DB)}.
+
+handle_cast (invalidate, State) ->
+ {stop, normal, State};
+handle_cast (ping, {DB, ObjectID}) ->
+ {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout(DB)}.
+
+terminate (_, {DB, ObjectID}) ->
+ ets:delete(DB, ObjectID).
+
+code_change (_, State, _) ->
+ {ok, State}.
+
+format_status (_, [_, State]) ->
+ [{data, [{"State", State}]}].
+
+handle_info(timeout, State) ->
+ {stop, normal, State};
+handle_info(_, {DB, ObjectID}) ->
+ {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout(DB)}.
+
+%%%% interface
+fetch (DB, ObjectID) ->
+ io:format("~nfetch from cache: ~p.~n", [{DB, ObjectID}]),
+ case ets:lookup(DB, ObjectID) of
+ [] -> add_to_cache(DB, ObjectID);
+
+ [{_, TimerPID, Data}] ->
+ gen_server:cast(TimerPID, ping),
+ Data
+ end.
+
+invalidate (DB, ObjectID) ->
+ case ets:lookup(DB, ObjectID) of
+ [] -> ok;
+
+ [{_, TimerPID, _}] ->
+ gen_server:stop(TimerPID)
+ end.
diff --git a/src/io/timed_caches_manager.erl b/src/io/timed_caches_manager.erl
new file mode 100644
index 0000000..ad66fbb
--- /dev/null
+++ b/src/io/timed_caches_manager.erl
@@ -0,0 +1,141 @@
+-module(timed_caches_manager).
+-behavior(gen_server).
+
+%%%% gen_server exports
+-export(
+ [
+ init/1,
+ handle_cast/2,
+ handle_call/3,
+ terminate/2,
+ code_change/3,
+ format_status/2,
+ handle_info/2
+ ]
+).
+
+%%%% actual interface
+-export(
+ [
+ add_cache/3,
+ inherit_cache/3,
+ delete_cache/2,
+ get_timeout/1
+ ]
+)
+.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%% Manager %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+delete_cache (DB) ->
+ ets:delete(DB).
+
+add_cache (DB, none) ->
+ io:format("~nTimed Caches Manager added a new cache. ~n"),
+ ets:new(
+ DB,
+ [
+ set,
+ public,
+ named_table,
+ {keypos, 2},
+ {read_concurrency, true},
+ {heir, none}
+ ]
+ );
+add_cache (DB, Heir) ->
+ io:format("~nTimed Caches Manager added a new cache. ~n"),
+ ets:new(
+ DB,
+ [
+ set,
+ public,
+ named_table,
+ {keypos, 2},
+ {read_concurrency, true},
+ {heir, Heir, DB}
+ ]
+ ).
+
+inherit_cache (CacheList, DB, Heir) ->
+ case lists:member(DB, CacheList) of
+ true ->
+ ets:setopts(DB, {heir, Heir, DB}),
+ CacheList;
+
+ false ->
+ [DB|CacheList]
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% gen_server
+init (CacheList) ->
+ io:format("~nStarting Timed Caches Manager..."),
+ {ok, CacheList}.
+
+handle_call ({delete, CacheName}, _Caller, State) ->
+ {noreply, delete_cache(State, CacheName)};
+handle_call ({add, CacheName, Heir}, _Caller, State)->
+ {noreply, add_cache(State, CacheName, Heir)};
+handle_call ({inherit, CacheName, Heir}, _Caller, State)->
+ {noreply, inherit_cache(State, CacheName, Heir)};
+handle_call (terminate, _, State) ->
+ {stop, normal, State}.
+
+handle_cast ({delete, CacheName}, State) ->
+ {noreply, delete_cache(State, CacheName)};
+handle_cast ({add, CacheName, Heir}, State)->
+ {noreply, add_cache(State, CacheName, Heir)};
+handle_cast ({inherit, CacheName, Heir}, State)->
+ {noreply, inherit_cache(State, CacheName, Heir)};
+handle_cast (terminate, State) ->
+ {stop, normal, State}.
+
+terminate (_Reason, []) ->
+ ok;
+terminate (Reason, [CacheName|OtherCaches]) ->
+ delete_cache(CacheName),
+ terminate(Reason, OtherCaches).
+
+code_change (_, State, _) ->
+ {ok, State}.
+
+format_status (_, [_, State]) ->
+ [{data, [{"State", State}]}].
+
+handle_info(_, State) ->
+ {noreply, State}.
+
+%%%% actual interface
+delete_cache (CacheList, DB) ->
+ case lists:member(DB, CacheList) of
+ true ->
+ delete_cache(DB),
+ lists:delete(DB, CacheList);
+ false ->
+ CacheList
+ end.
+
+add_cache (CacheList, DB, Heir) ->
+ case lists:member(DB, CacheList) of
+ true when (Heir =:= none) ->
+ CacheList;
+
+ true ->
+ ets:setopts(DB, {heir, Heir, DB}),
+ CacheList;
+
+ false ->
+ add_cache(DB, Heir),
+ [DB|CacheList]
+ end.
+
+get_timeout(battlemap_db) ->
+ 60000;
+get_timeout(_) ->
+ 60000.