1 // This may look like C code, but it's really -*- C++ -*-
2 /*
3  * Copyright (C) 2010 Emweb bv, Herent, Belgium.
4  *
5  * See the LICENSE file for terms of use.
6  */
7 #ifndef CODE_SESSION_H_
8 #define CODE_SESSION_H_
9 
10 #include <Wt/WString.h>
11 #include <Wt/WSignal.h>
12 
13 #include <vector>
14 #include <thread>
15 #include <mutex>
16 
17 class CodeSession
18 {
19 public:
20   enum BufferUpdate {
21     Inserted,
22     Deleted,
23     Changed
24   };
25 
26   struct Buffer {
27     Wt::WString name;
28     Wt::WString text;
29   };
30 
31   typedef std::function<void(int, BufferUpdate)> BufferCallback;
32   typedef std::function<void(void)> CoderCallback;
33 
34   CodeSession(const CoderCallback& coderCallback);
35   ~CodeSession();
36 
37   static void addSession(const std::shared_ptr<CodeSession> &session);
38 
id()39   std::string id() const { return id_; }
40 
41   static std::shared_ptr<CodeSession>
42     addObserver(const std::string& id, const BufferCallback& bufferCallback);
43 
44   void removeObserver();
45   void removeCoder();
46 
47   void insertBuffer(int index);
48   void updateBuffer(int buffer, const Wt::WString& name,
49                     const Wt::WString& text);
50 
51   std::vector<Buffer> buffers() const;
52   Buffer buffer(int buffer) const;
observerCount()53   int observerCount() const { return observers_.size(); }
54 
55 private:
56   typedef std::unique_lock<std::recursive_mutex> Lock;
57 
58   struct Coder {
59     std::string sessionId;
60     CoderCallback callback;
61   };
62 
63   struct Observer {
64     std::string sessionId;
65     BufferCallback callback;
66   };
67 
68   std::string id_;
69   std::vector<Buffer> buffers_;
70 
71   std::vector<Observer> observers_;
72   std::unique_ptr<Coder> coder_;
73 
74   static std::vector<std::weak_ptr<CodeSession>> sessions_;
75   static std::recursive_mutex mutex_;
76 
77   void generateId();
78   static void cleanExpiredSessions();
79   void postSessionChanged();
80   void postBufferChanged(int buffer, BufferUpdate update);
81 };
82 
83 #endif // CODE_SESSION_H_
84