Use strings instead of keywords for game names

This commit changes the internal representation of game names in the
state data to be strings instead of keywords. This fixes a potential
memory leak relating to games that no longer have any players, since
strings, unlike keywords, are garbage collected when no longer in use.

Resolves issue #2

Signed-off-by: Sebastian Crane <seabass-labrax@gmx.com>
This commit is contained in:
Sebastian Crane 2022-03-30 12:11:10 +01:00
parent 6cce43f137
commit 6a594c5ad3
4 changed files with 29 additions and 27 deletions

View File

@ -6,15 +6,15 @@
[game]
[irclj.core]))
(defn keywordise-game [game]
(defn lower-case-game [game]
(when (string? game)
(keyword (str/lower-case game))))
(str/lower-case game)))
(defn sort-case-insensitive [coll]
(sort #(apply compare (map str/lower-case %&)) coll))
(defn match-string [& {:keys [state game player]}]
(as-> (keywordise-game game) x
(as-> (lower-case-game game) x
(game/get-players-of-game state x)
(disj x player)
(sort-case-insensitive x)
@ -22,7 +22,7 @@
(str "Anyone ready for " game "? " x)))
(defn list-players-string [& {:keys [state game]}]
(as-> (keywordise-game game) x
(as-> (lower-case-game game) x
(game/get-players-of-game state x)
(sort-case-insensitive x)
(map #(str " _" % "_") x)
@ -46,7 +46,7 @@
(str "Games with a list of players: "
(str/join
", "
(sort-case-insensitive (map name (game/get-games state))))))
(sort-case-insensitive (game/get-games state)))))
(defn help-string [& {:keys []}]
" !list - show all the games that have a list of players
@ -59,7 +59,7 @@
(let [message-parts (str/split message #"\s")
command (if-let [x (first message-parts)] (str/lower-case x) "")
game (second message-parts)
game-keyword (keywordise-game game)]
game-keyword (lower-case-game game)]
{:command command
:game game
:game-keyword game-keyword}))

View File

@ -4,6 +4,7 @@
(ns system
(:require [irc]
[clojure.data.json :as json]
[clojure.set :as set]
[clj-yaml.core :as yaml]))
(defn setify-vals [x]
@ -13,13 +14,14 @@
{} x))
(defn process-json [x]
(update x :games setify-vals))
(-> (set/rename-keys x {"games" :games})
(update :games setify-vals)))
(defn load-state [f]
(process-json
(try
(with-open [datafile (clojure.java.io/reader f)]
(json/read datafile :key-fn keyword))
(json/read datafile))
(catch Exception e nil))))
(defn save-state [f data]

View File

@ -5,13 +5,13 @@
(:require [clojure.test :refer :all]
[bot :refer :all]))
(def test-state '{:games {:hypothetical-shooter #{"abc" "xyz" "123"}
:quasi-rts #{"abc" "123"}
:imaginary-rpg #{"xyz" "abc"}}})
(def test-state '{:games {"hypothetical-shooter" #{"abc" "xyz" "123"}
"quasi-rts" #{"abc" "123"}
"imaginary-rpg" #{"xyz" "abc"}}})
(deftest keywordise-game-test
(is (= :quasi-rts
(keywordise-game "Quasi-RTS"))))
(deftest lower-case-game-test
(is (= "quasi-rts"
(lower-case-game "Quasi-RTS"))))
(deftest sort-case-insensitive-test
(is (= ["A" "b" "C"]
@ -38,7 +38,7 @@
(list-games-string :state test-state))))
(deftest split-message-test
(is (= {:command "!match" :game "Quasi-Rts" :game-keyword :quasi-rts}
(is (= {:command "!match" :game "Quasi-Rts" :game-keyword "quasi-rts"}
(split-message "!match Quasi-Rts "))))
(deftest dispatch-command-test
@ -46,7 +46,7 @@
(is (and
(= "Added 123 to the list of players for Imaginary-RPG!"
(dispatch-command state-atom "123" "!add Imaginary-RPG"))
(= {:games {:hypothetical-shooter #{"abc" "xyz" "123"}
:quasi-rts #{"abc" "123"}
:imaginary-rpg #{"xyz" "abc" "123"}}}
(= {:games {"hypothetical-shooter" #{"abc" "xyz" "123"}
"quasi-rts" #{"abc" "123"}
"imaginary-rpg" #{"xyz" "abc" "123"}}}
@state-atom)))))

View File

@ -5,31 +5,31 @@
(:require [clojure.test :refer :all]
[game :refer :all]))
(def test-state '{:games {:hypothetical-shooter #{"player-one" "player-two" "player-three"}
:quasi-rts #{"player-two" "player-four"}
:imaginary-rpg #{"player-one" "player-three" "player-four"}}})
(def test-state '{:games {"hypothetical-shooter" #{"player-one" "player-two" "player-three"}
"quasi-rts" #{"player-two" "player-four"}
"imaginary-rpg" #{"player-one" "player-three" "player-four"}}})
(deftest get-players-of-game-test
(is (=
'#{"player-two" "player-four"}
(get-players-of-game test-state :quasi-rts))))
(get-players-of-game test-state "quasi-rts"))))
(deftest add-player-of-game-test
(is (=
'#{"player-one" "player-two" "player-four"}
(get-in (add-player-of-game test-state :quasi-rts "player-one") [:games :quasi-rts]))))
(get-in (add-player-of-game test-state "quasi-rts" "player-one") [:games "quasi-rts"]))))
(deftest remove-player-of-game-test
(is (=
'#{"player-one" "player-three"}
(get-in (remove-player-of-game test-state :imaginary-rpg "player-four") [:games :imaginary-rpg]))))
(get-in (remove-player-of-game test-state "imaginary-rpg" "player-four") [:games "imaginary-rpg"]))))
(deftest get-games-test
(is (=
'#{:hypothetical-shooter :quasi-rts :imaginary-rpg}
'#{"hypothetical-shooter" "quasi-rts" "imaginary-rpg"}
(set (get-games test-state)))))
(deftest remove-game-test
(is (=
'#{:hypothetical-shooter :imaginary-rpg}
(set (keys (:games (remove-game test-state :quasi-rts)))))))
'#{"hypothetical-shooter" "imaginary-rpg"}
(set (keys (:games (remove-game test-state "quasi-rts")))))))