3 // Copyright (c) 2007 David Ward
5 // This file is part of Dasher.
7 // Dasher is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
12 // Dasher is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with Dasher; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "../Common/Common.h"
23 #include "AlphabetManager.h"
25 #include "DasherNode.h"
27 using namespace Dasher
;
31 // Track memory leaks on Windows to the line that new'd the memory
34 #define DEBUG_NEW new( _NORMAL_BLOCK, THIS_FILE, __LINE__ )
37 static char THIS_FILE
[] = __FILE__
;
41 // TODO: put this back to being inlined
42 CDasherNode::~CDasherNode() {
43 // std::cout << "Deleting node: " << this << std::endl;
44 // Release any storage that the node manager has allocated,
45 // unreference ref counted stuff etc.
48 m_pNodeManager
->ClearNode( this );
49 m_pNodeManager
->Unref();
51 // std::cout << "done." << std::endl;
53 delete m_pDisplayInfo
;
57 void CDasherNode::Trace() const {
61 wsprintf(out,TEXT("%7x %3c %7x %5d %7x %5d %8x %8x \n"),this,m_Symbol,m_iGroup,m_context,m_Children,m_Cscheme,m_iLbnd,m_iHbnd);
63 wsprintf(out,TEXT("%7x %7x %5d %7x %5d %8x %8x \n"),this,m_iGroup,m_context,m_Children,m_Cscheme,m_iLbnd,m_iHbnd);
65 OutputDebugString(out);
69 for (i=1;i<m_iChars;i++)
70 m_Children[i]->Dump_node();
75 bool CDasherNode::NodeIsParent(CDasherNode
*oldnode
) const {
76 if(oldnode
== m_pParent
)
83 CDasherNode
*const CDasherNode::Get_node_under(int iNormalization
, myint miY1
, myint miY2
, myint miMousex
, myint miMousey
) {
84 myint miRange
= miY2
- miY1
;
86 // TODO: Manipulating flags in a 'get' method?
87 SetFlag(NF_ALIVE
, true);
89 ChildMap::const_iterator i
;
90 for(i
= GetChildren().begin(); i
!= GetChildren().end(); i
++) {
91 CDasherNode
*pChild
= *i
;
93 myint miNewy1
= miY1
+ (miRange
* pChild
->m_iLbnd
) / iNormalization
;
94 myint miNewy2
= miY1
+ (miRange
* pChild
->m_iHbnd
) / iNormalization
;
95 if(miMousey
< miNewy2
&& miMousey
> miNewy1
&& miMousex
< miNewy2
- miNewy1
)
96 return pChild
->Get_node_under(iNormalization
, miNewy1
, miNewy2
, miMousex
, miMousey
);
101 // kill ourselves and all other children except for the specified
103 // FIXME this probably shouldn't be called after history stuff is working
104 void CDasherNode::OrphanChild(CDasherNode
*pChild
) {
105 DASHER_ASSERT(ChildCount() > 0);
107 ChildMap::const_iterator i
;
108 for(i
= GetChildren().begin(); i
!= GetChildren().end(); i
++) {
110 (*i
)->Delete_children();
115 pChild
->SetParent(NULL
);
118 SetFlag(NF_ALLCHILDREN
, false);
121 // Delete nephews of the child which has the specified symbol
122 // TODO: Need to allow for subnode
123 void CDasherNode::DeleteNephews(CDasherNode
*pChild
) {
124 DASHER_ASSERT(Children().size() > 0);
126 ChildMap::iterator i
;
127 for(i
= Children().begin(); i
!= Children().end(); i
++) {
128 if((*i
)->GetFlag(NF_SUBNODE
))
129 (*i
)->DeleteNephews(pChild
);
132 (*i
)->Delete_children();
138 // TODO: Need to allow for subnodes
139 // TODO: Incorporate into above routine
140 void CDasherNode::Delete_children() {
141 // CAlphabetManager::SAlphabetData *pParentUserData(static_cast<CAlphabetManager::SAlphabetData *>(m_pUserData));
143 // if((GetDisplayInfo()->strDisplayText)[0] == 'e')
144 // std::cout << "ed: " << this << " " << pParentUserData->iContext << " " << pParentUserData->iOffset << std::endl;
146 // std::cout << "Start: " << this << std::endl;
148 ChildMap::iterator i
;
149 for(i
= Children().begin(); i
!= Children().end(); i
++) {
150 // std::cout << "CNM: " << (*i)->m_pNodeManager << " (" << (*i)->m_pNodeManager->GetID() << ") " << (*i) << " " << (*i)->Parent() << std::endl;
154 // std::cout << "NM: " << m_pNodeManager << std::endl;
155 SetFlag(NF_ALLCHILDREN
, false);
158 // Gets the probability of this node, conditioned on the parent
159 double CDasherNode::GetProb(int iNormalization
) {
160 return (double) (m_iHbnd
- m_iLbnd
) / (double) iNormalization
;
163 void CDasherNode::ConvertWithAncestors() {
164 if(GetFlag(NF_CONVERTED
))
167 SetFlag(NF_CONVERTED
, true);
170 m_pParent
->ConvertWithAncestors();
173 void CDasherNode::SetFlag(int iFlag
, bool bValue
) {
175 m_iFlags
= m_iFlags
| iFlag
;
177 m_iFlags
= m_iFlags
& (~iFlag
);
179 m_pNodeManager
->SetFlag(this, iFlag
, bValue
);
182 void CDasherNode::SetParent(CDasherNode
*pNewParent
) {
183 m_pParent
= pNewParent
;
186 int CDasherNode::MostProbableChild() {
190 for(ChildMap::iterator
it(m_mChildren
.begin()); it
!= m_mChildren
.end(); ++it
) {
191 iCurrent
= (*it
)->Range();