1 //
2 // Copyright RIME Developers
3 // Distributed under the BSD License
4 //
5 // 2011-05-02 Wensong He <snowhws@gmail.com>
6 //
7 
8 #ifndef RIME_TRANSLATION_H_
9 #define RIME_TRANSLATION_H_
10 
11 #include <rime_api.h>
12 #include <rime/candidate.h>
13 #include <rime/common.h>
14 
15 namespace rime {
16 
17 class Translation {
18  public:
19   Translation() = default;
20   virtual ~Translation() = default;
21 
22   // A translation may contain multiple results, looks
23   // something like a generator of candidates.
24   virtual bool Next() = 0;
25 
26   virtual an<Candidate> Peek() = 0;
27 
28   // should it provide the next candidate (negative value, zero) or
29   // should it give up the chance for other translations (positive)?
30   RIME_API virtual int Compare(an<Translation> other,
31                                const CandidateList& candidates);
32 
exhausted()33   bool exhausted() const { return exhausted_; }
34 
35  protected:
set_exhausted(bool exhausted)36   void set_exhausted(bool exhausted) { exhausted_ = exhausted; }
37 
38  private:
39   bool exhausted_ = false;
40 };
41 
42 class UniqueTranslation : public Translation {
43  public:
UniqueTranslation(an<Candidate> candidate)44   UniqueTranslation(an<Candidate> candidate)
45       : candidate_(candidate) {
46     set_exhausted(!candidate);
47   }
48 
49   bool Next();
50   an<Candidate> Peek();
51 
52  protected:
53   an<Candidate> candidate_;
54 };
55 
56 class FifoTranslation : public Translation {
57  public:
58   FifoTranslation();
59 
60   bool Next();
61   an<Candidate> Peek();
62 
63   void Append(an<Candidate> candy);
64 
size()65   size_t size() const {
66     return candies_.size() - cursor_;
67   }
68 
69  protected:
70   CandidateList candies_;
71   size_t cursor_ = 0;
72 };
73 
74 class UnionTranslation : public Translation {
75  public:
76   UnionTranslation();
77 
78   bool Next();
79   an<Candidate> Peek();
80 
81   UnionTranslation& operator+= (an<Translation> t);
82 
83  protected:
84   list<of<Translation>> translations_;
85 };
86 
87 an<UnionTranslation> operator+ (an<Translation> x, an<Translation> y);
88 
89 class MergedTranslation : public Translation {
90  public:
91   explicit MergedTranslation(const CandidateList& previous_candidates);
92 
93   bool Next();
94   an<Candidate> Peek();
95 
96   MergedTranslation& operator+= (an<Translation> t);
97 
size()98   size_t size() const { return translations_.size(); }
99 
100  protected:
101   void Elect();
102 
103   const CandidateList& previous_candidates_;
104   vector<of<Translation>> translations_;
105   size_t elected_ = 0;
106 };
107 
108 class CacheTranslation : public Translation {
109  public:
110   CacheTranslation(an<Translation> translation);
111 
112   virtual bool Next();
113   virtual an<Candidate> Peek();
114 
115  protected:
116   an<Translation> translation_;
117   an<Candidate> cache_;
118 };
119 
120 template <class T, class... Args>
Cached(Args &&...args)121 inline an<Translation> Cached(Args&&... args) {
122   return New<CacheTranslation>(New<T>(std::forward<Args>(args)...));
123 }
124 
125 class DistinctTranslation : public CacheTranslation {
126  public:
127   DistinctTranslation(an<Translation> translation);
128   virtual bool Next();
129 
130  protected:
131   bool AlreadyHas(const string& text) const;
132 
133   set<string> candidate_set_;
134 };
135 
136 class PrefetchTranslation : public Translation {
137  public:
138   PrefetchTranslation(an<Translation> translation);
139 
140   virtual bool Next();
141   virtual an<Candidate> Peek();
142 
143  protected:
Replenish()144   virtual bool Replenish() { return false; }
145 
146   an<Translation> translation_;
147   CandidateQueue cache_;
148 };
149 
150 } // namespace rime
151 
152 #endif  // RIME_TRANSLATION_H_
153