2
2
#include "../Common/Common.h"
4
4
#include "AlphabetManager.h"
5
#include "DasherModel.h"
5
//#include "DasherModel.h"
6
6
#include "DasherNode.h"
8
8
#include "EventHandler.h"
9
#include "NodeCreationManager.h"
11
12
#include <iostream>
25
CAlphabetManager::CAlphabetManager( CDasherModel *pModel, CLanguageModel *pLanguageModel, bool bGameMode, const std::string &strGameModeText )
26
: CNodeManager(0), m_pLanguageModel(pLanguageModel), m_pModel(pModel) {
26
CAlphabetManager::CAlphabetManager( CNodeCreationManager *pNCManager, CLanguageModel *pLanguageModel, CLanguageModel::Context iLearnContext, bool bGameMode, const std::string &strGameModeText )
27
: CNodeManager(0), m_pLanguageModel(pLanguageModel), m_pNCManager(pNCManager) {
29
m_iLearnContext = iLearnContext;
28
30
m_bGameMode = bGameMode;
29
31
m_strGameString = strGameModeText;
49
iColour = m_pModel->GetColour(iSymbol);
51
iColour = m_pNCManager->GetColour(iSymbol);
51
53
pNewNode = new CDasherNode(pParent, iSymbol, 0, Opts::Nodes1, iLower, iUpper, m_pLanguageModel, iColour);
53
pNewNode->SetContext(m_pLanguageModel->CreateEmptyContext()); // FIXME - handle context properly
55
// pNewNode->SetContext(m_pLanguageModel->CreateEmptyContext()); // FIXME - handle context properly
54
56
pNewNode->m_pNodeManager = this;
55
57
pNewNode->m_bShove = true;
56
pNewNode->m_pBaseGroup = m_pModel->GetAlphabet().m_pBaseGroup;
57
pNewNode->m_strDisplayText = m_pModel->GetAlphabet().GetDisplayText(iSymbol);
58
pNewNode->m_pBaseGroup = m_pNCManager->GetAlphabet()->m_pBaseGroup;
59
pNewNode->m_strDisplayText = m_pNCManager->GetAlphabet()->GetDisplayText(iSymbol);
58
60
pNewNode->Seen(true);
60
62
SAlphabetData *pNodeUserData = new SAlphabetData;
63
65
pNodeUserData->iPhase = 0;
64
66
pNodeUserData->iSymbol = iSymbol;
67
pNodeUserData->pLanguageModel = m_pLanguageModel;
69
// Hopefully this will obsolete any need to handle contexts outside
70
// of the alphabet manager - check this and remove resulting
72
CLanguageModel::Context iContext;
73
iContext = m_pLanguageModel->CreateEmptyContext();
74
pNodeUserData->iContext = iContext;
67
77
pNodeUserData->iGameOffset = -1;
79
89
int iOldPhase(static_cast<SAlphabetData *>(pNode->m_pUserData)->iPhase);
80
90
int iNewPhase((iOldPhase + 1) % 2);
92
SAlphabetData *pParentUserData(static_cast<SAlphabetData *>(pNode->m_pUserData));
83
94
// Actually create the children here
86
97
std::vector < symbol > newchars; // place to put this list of characters
87
98
std::vector < unsigned int >cum; // for the probability list
89
m_pModel->GetProbs(pNode->Context(), newchars, cum, m_pModel->GetLongParameter(LP_NORMALIZATION));
100
// TODO: Need to fix up relation to language model here (use one from node, not global).
101
m_pNCManager->GetProbs(pParentUserData->iContext, newchars, cum, m_pNCManager->GetLongParameter(LP_NORMALIZATION));
90
102
int iChildCount = newchars.size();
92
104
// work out cumulative probs in place
100
112
for(int j = 0; j < iChildCount; j++) {
101
113
CDasherNode *pNewNode;
103
if(newchars[j] == m_pModel->GetControlSymbol())
104
pNewNode = m_pModel->GetRoot(1, pNode, iLbnd, cum[j], NULL);
105
else if(newchars[j] == m_pModel->GetStartConversionSymbol()) {
107
pNewNode = m_pModel->GetRoot(2, pNode, iLbnd, cum[j], NULL);
109
pNewNode = m_pModel->GetRoot(0, pNode, iLbnd, cum[j], NULL);
110
pNewNode->Seen(false);
115
if(newchars[j] == m_pNCManager->GetControlSymbol())
116
pNewNode = m_pNCManager->GetRoot(1, pNode, iLbnd, cum[j], NULL);
117
else if(newchars[j] == m_pNCManager->GetStartConversionSymbol()) {
118
// TODO: Need to consider the case where there is no compile-time support for this
119
pNewNode = m_pNCManager->GetRoot(2, pNode, iLbnd, cum[j], NULL);
113
121
else if( newchars[j] == iExistingSymbol) {
114
122
pNewNode = pExistingChild;
115
123
pNewNode->SetRange(iLbnd, cum[j]);
118
int iColour(m_pModel->GetColour(newchars[j]));
126
int iColour(m_pNCManager->GetColour(newchars[j]));
120
128
// This is provided for backwards compatibility.
121
129
// Colours should always be provided by the alphabet file
122
130
if(iColour == -1) {
123
if(newchars[j] == m_pModel->GetSpaceSymbol()) {
131
if(newchars[j] == m_pNCManager->GetSpaceSymbol()) {
126
else if(newchars[j] == m_pModel->GetControlSymbol()) {
134
else if(newchars[j] == m_pNCManager->GetControlSymbol()) {
135
143
if(iNewPhase == 1 && iColour < 130) // We don't loop on high
138
pNewNode = new CDasherNode(pNode, newchars[j], 0, Nodes1, iLbnd, cum[j], m_pLanguageModel, iColour);
146
pNewNode = new CDasherNode(pNode, newchars[j], 0, Nodes1, iLbnd, cum[j], pParentUserData->pLanguageModel, iColour);
139
147
pNewNode->m_pNodeManager = this;
140
148
pNewNode->m_bShove = true;
141
pNewNode->m_pBaseGroup = m_pModel->GetAlphabet().m_pBaseGroup;
149
pNewNode->m_pBaseGroup = m_pNCManager->GetAlphabet()->m_pBaseGroup;
143
151
SAlphabetData *pNodeUserData = new SAlphabetData;
144
152
pNewNode->m_pUserData = pNodeUserData;
149
157
if(m_bGameMode) {
150
158
int iCurrentGameOffset(static_cast<SAlphabetData *>(pNode->m_pUserData)->iGameOffset);
152
if((iCurrentGameOffset != -2) && ((iCurrentGameOffset + 1) < m_strGameString.size())
153
&& ((m_pModel->GetAlphabet().GetText(newchars[j]))[0] == m_strGameString[iCurrentGameOffset + 1])) {
160
if((iCurrentGameOffset != -2) && ((iCurrentGameOffset + 1) < static_cast<int>(m_strGameString.size()))
161
&& ((m_pNCManager->GetAlphabet()->GetText(newchars[j]))[0] == m_strGameString[iCurrentGameOffset + 1])) {
154
162
static_cast<SAlphabetData *>(pNewNode->m_pUserData)->iGameOffset = iCurrentGameOffset + 1;
155
163
pNewNode->SetGame(true);
158
166
static_cast<SAlphabetData *>(pNewNode->m_pUserData)->iGameOffset = -2;
169
CLanguageModel::Context iContext;
170
iContext = m_pLanguageModel->CloneContext(pParentUserData->iContext);
171
m_pLanguageModel->EnterSymbol(iContext, newchars[j]); // TODO: Don't use symbols?
173
pNodeUserData->pLanguageModel = pParentUserData->pLanguageModel;
174
pNodeUserData->iContext = iContext;
176
// pNewNode->SetContext(iContext); // FIXME - handle context properly
162
pNewNode->m_strDisplayText = m_pModel->GetAlphabet().GetDisplayText(newchars[j]);
179
pNewNode->m_strDisplayText = m_pNCManager->GetAlphabet()->GetDisplayText(newchars[j]);
165
181
pNode->Children()[j] = pNewNode;
172
188
void CAlphabetManager::ClearNode( CDasherNode *pNode ) {
173
delete static_cast<SAlphabetData *>(pNode->m_pUserData);
189
SAlphabetData *pUserData(static_cast<SAlphabetData *>(pNode->m_pUserData));
191
pUserData->pLanguageModel->ReleaseContext(pUserData->iContext);
176
195
void CAlphabetManager::Output( CDasherNode *pNode, Dasher::VECTOR_SYMBOL_PROB* pAdded, int iNormalization) {
177
m_pModel->m_bContextSensitive = true;
196
// m_pNCManager->m_bContextSensitive = true;
178
197
symbol t = static_cast<SAlphabetData *>(pNode->m_pUserData)->iSymbol;
180
199
if(t) { // Ignore symbol 0 (root node)
181
Dasher::CEditEvent oEvent(1, m_pModel->GetAlphabet().GetText(t));
182
m_pModel->InsertEvent(&oEvent);
200
Dasher::CEditEvent oEvent(1, m_pNCManager->GetAlphabet()->GetText(t));
201
m_pNCManager->InsertEvent(&oEvent);
184
203
// Track this symbol and its probability for logging purposes
185
204
if (pAdded != NULL) {
195
214
void CAlphabetManager::Undo( CDasherNode *pNode ) {
196
215
symbol t = static_cast<SAlphabetData *>(pNode->m_pUserData)->iSymbol;
197
216
if(t) { // Ignore symbol 0 (root node)
198
Dasher::CEditEvent oEvent(2, m_pModel->GetAlphabet().GetText(t));
199
m_pModel->InsertEvent(&oEvent);
217
Dasher::CEditEvent oEvent(2, m_pNCManager->GetAlphabet()->GetText(t));
218
m_pNCManager->InsertEvent(&oEvent);
203
222
CDasherNode *CAlphabetManager::RebuildParent(CDasherNode *pNode, int iGeneration) {
224
// TODO: Reimplement -----
205
226
// Ask for context information
206
m_pModel->m_strContextBuffer = "";
207
Dasher::CEditContextEvent oEvent(10);
208
m_pModel->InsertEvent(&oEvent);
227
// m_pNCManager->m_strContextBuffer = "";
228
// Dasher::CEditContextEvent oEvent(10);
229
// m_pNCManager->InsertEvent(&oEvent);
210
std::string strContext(m_pModel->m_strContextBuffer);
231
// std::string strContext(m_pNCManager->m_strContextBuffer);
211
232
std::vector<symbol> vSymbols;
212
m_pLanguageModel->SymbolAlphabet().GetAlphabetPointer()->GetSymbols(&vSymbols, &strContext, false);
233
// m_pLanguageModel->SymbolAlphabet().GetAlphabetPointer()->GetSymbols(&vSymbols, &strContext, false);
215
237
CDasherNode *pNewNode;
220
242
symbol iNewSymbol;
222
if(vSymbols.size() <= iGeneration + 1) {
244
CLanguageModel::Context oContext(m_pLanguageModel->CreateEmptyContext());
246
if(static_cast<int>(vSymbols.size()) <= iGeneration + 1) {
223
247
// Create a root node if there isn't any more context
227
251
pNewNode = new CDasherNode(0, 0, 0, Opts::Nodes1, 0, 0, m_pLanguageModel, 7);
229
253
// TODO: Horrible hard coded default context
230
CLanguageModel::Context oContext(m_pLanguageModel->CreateEmptyContext());
231
m_pModel->EnterText(oContext, ". ");
232
pNewNode->SetContext(oContext);
254
m_pNCManager->EnterText(oContext, ". ");
236
258
iNewPhase = ((iOldPhase + 2 - 1) % 2);
237
259
iNewSymbol = vSymbols[vSymbols.size() - iGeneration - 2];
239
int iColour(m_pModel->GetColour(vSymbols[vSymbols.size() - iGeneration - 2]));
261
int iColour(m_pNCManager->GetColour(vSymbols[vSymbols.size() - iGeneration - 2]));
241
263
// Loop colours if necessary for the colour scheme
242
264
if(iNewPhase == 1)
245
267
pNewNode = new CDasherNode(0, iNewSymbol, 0, Nodes1, 0, 0, m_pLanguageModel, iColour);
246
CLanguageModel::Context oContext(m_pLanguageModel->CreateEmptyContext());
248
for(int i(0); i < vSymbols.size() - iGeneration -1; ++i)
269
for(unsigned int i(0); i < vSymbols.size() - iGeneration -1; ++i)
249
270
m_pLanguageModel->EnterSymbol(oContext, vSymbols[i]);
251
pNewNode->SetContext(oContext);
254
273
pNewNode->m_pNodeManager = this;
255
274
pNewNode->m_bShove = true;
256
275
pNewNode->Seen(true);
257
pNewNode->m_pBaseGroup = m_pModel->GetAlphabet().m_pBaseGroup;
276
pNewNode->m_pBaseGroup = m_pNCManager->GetAlphabet()->m_pBaseGroup;
259
278
SAlphabetData *pNodeUserData = new SAlphabetData;
260
279
pNewNode->m_pUserData = pNodeUserData;
262
281
pNodeUserData->iPhase = iNewPhase;
263
282
pNodeUserData->iSymbol = iNewSymbol;
283
pNodeUserData->pLanguageModel = m_pLanguageModel;
284
pNodeUserData->iContext = oContext;
265
286
PopulateChildrenWithSymbol(pNewNode, static_cast<SAlphabetData *>(pNode->m_pUserData)->iSymbol, pNode);
293
void CAlphabetManager::SetFlag(CDasherNode *pNode, int iFlag, bool bValue) {
297
// TODO: Reimplement (need a learning context, check whether symbol actually corresponds to character)
298
static_cast<SAlphabetData *>(pNode->m_pUserData)->pLanguageModel->LearnSymbol(m_iLearnContext, static_cast<SAlphabetData *>(pNode->m_pUserData)->iSymbol);