summaryrefslogtreecommitdiff
path: root/src/state.lisp
blob: ef4050dcf2c1c7be5c8066b1f202c1d3fa23e5f3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
;; SPDX-License-Identifier: EUPL-1.2
;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
(defpackage :ukkoclot/src/state
  (:documentation "Holds the global state")
  (:nicknames :state)
  (:use :c2cl :ukkoclot/src/rw-lock)
  (:import-from :com.dieggsy.f-string :enable-f-strings)
  (:import-from :conf :*config* :bot-token)
  (:import-from :sqlite :sqlite-handle)
  (:export
   #:*state*
   #:state
   #:make-state
   #:state-p
   #:db
   #:base-uri
   #:power-on
   #:set-power-on
   #:username%
   #:set-username%
   #:id%
   #:set-id%))
(in-package :ukkoclot/src/state)

(enable-f-strings)

(defstruct (state (:constructor make-state%))
  (lock (make-rw-lock :name "state's lock") :type rw-lock :read-only t)
  (db (error "No value given for DB") :type sqlite-handle :read-only t)
  (base-uri (error "No value given for base-uri") :type string :read-only t)
  (power-on t :type boolean)
  (username% nil :type (or string null))
  (id% nil :type (or integer null)))

(defun make-state (db &optional (config *config*))
  (check-type db sqlite-handle)
  (let ((base-uri #f"https://api.telegram.org/bot{(bot-token config)}/"))
    (make-state% :db db :base-uri base-uri)))

(defvar *state* nil
  "Bot's general state.  You should initialise this with a value before doing anything fun.")

(defun db (&optional (state *state*))
  "Get the database handle of the bot."
  (with-slots (lock db) state
    (with-read-lock (lock)
      db)))

(defun base-uri (&optional (state *state*))
  "Get the base URI of the bot."
  (with-slots (lock base-uri) state
    (with-read-lock (lock)
      base-uri)))

(defun power-on (&optional (state *state*))
  "Get whether the bot is running"
  (with-slots (lock power-on) state
    (with-read-lock (lock)
      power-on)))

(defun set-power-on (new-value &optional (state *state*))
  "Set the value of the power-on"
  (with-slots (lock power-on) state
    (with-write-lock (lock)
      (setf power-on new-value))))

(defsetf power-on (&optional (state '*state*)) (new-value)
  `(set-power-on ,new-value ,state))

(defun username% (&optional (state *state*))
  "Get the cached bot's username, you should probably use `ukkoclot/src/tg:bot-username' instead."
  (with-slots (lock username%) state
    (with-read-lock (lock)
      username%)))

(defun set-username% (new-value &optional (state *state*))
  (with-slots (lock username%) state
    (with-write-lock (lock)
      (setf username% new-value))))

(defsetf username% (&optional (state '*state*)) (new-value)
  `(set-username% ,new-value ,state))

(defun id% (&optional (state *state*))
  "Get the cached bot's ID, you should probably use `ukkoclot/src/tg:bot-id' instead."
  (with-slots (lock id%) state
    (with-read-lock (lock)
      id%)))

(defun set-id% (new-value &optional (state *state*))
  (with-slots (lock id%) state
    (with-write-lock (lock)
      (setf id% new-value))))

(defsetf id% (&optional (state '*state*)) (new-value)
  `(set-id% ,new-value ,state))