Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DasherModel.cpp

Go to the documentation of this file.
00001 // DasherModel.h
00002 //
00004 //
00005 // Copyright (c) 2001-2002 David Ward
00006 //
00008 
00009 #include <iostream>
00010 #include "DasherModel.h"
00011 
00012 using namespace Dasher;
00013 using namespace std;
00014 
00016 // CDasherModel
00018 
00019 CDasherModel::CDasherModel(CDashEditbox* Editbox, CLanguageModel* LanguageModel, bool Dimensions)
00020   : m_Dimensions(Dimensions), m_editbox(Editbox), m_languagemodel(LanguageModel), m_Root(0)
00021 {
00022         LearnContext = m_languagemodel->GetRootNodeContext();
00023         
00024         // various settings
00025         int iShift = 12;
00026         m_DasherY = 1<<iShift;
00027         m_DasherOY = m_DasherY/2;
00028         m_DasherOX = m_DasherY/2;
00029         m_dAddProb = 0.003;
00030 }
00031 
00032 
00033 CDasherModel::~CDasherModel()
00034 {
00035         m_languagemodel->ReleaseNodeContext(LearnContext);
00036         delete m_Root;  // which will also delete all the whole structure
00037 }
00038 
00039 
00040 void CDasherModel::Make_root(int whichchild)
00041  // find a new root node 
00042 {
00043         symbol t=m_Root->Symbol();
00044         if (t) {
00045                 m_editbox->output(t);
00046                 m_languagemodel->LearnNodeSymbol(LearnContext, t);
00047         }
00048 
00049         CDasherNode * oldroot=m_Root;
00050         
00051         CDasherNode **children=m_Root->Children();
00052         m_Root=children[whichchild];
00053         //      oldroot->Children()[whichchild]=0;  // null the pointer so we don't delete the whole tree
00054         //      delete oldroot;
00055         
00056         oldroots.push_back(oldroot);
00057 
00058         myint range=m_Rootmax-m_Rootmin;
00059         m_Rootmax=m_Rootmin+(range*m_Root->Hbnd())/Normalization();
00060         m_Rootmin+=(range*m_Root->Lbnd())/Normalization();
00061 }
00062 
00063 void CDasherModel::Reparent_root(int lower, int upper)
00064 {
00065   /* Change the root node to the parent of the existing node
00066      We need to recalculate the coordinates for the "new" root as the 
00067      user may have moved around within the current root */
00068 
00069   /* Determine how zoomed in we are */
00070         float scalefactor=(m_Rootmax-m_Rootmin)/(upper-lower);
00071 
00072         m_Rootmax=int(m_Rootmax+((1024-upper)*scalefactor));
00073         m_Rootmin=int(m_Rootmin-(lower*scalefactor));
00074 
00075         m_editbox->deletetext();
00076 
00077         m_Root=oldroots.back();
00078         oldroots.pop_back();
00079 }
00080 
00082 
00083 CDasherNode * CDasherModel::Get_node_under_crosshair()
00084 {
00085         return m_Root->Get_node_under(Normalization(),m_Rootmin,m_Rootmax,m_DasherOX,m_DasherOY);
00086 }
00087 
00089 
00090 
00091 CDasherNode * CDasherModel::Get_node_under_mouse(myint Mousex,myint Mousey)
00092 {
00093         return m_Root->Get_node_under(Normalization(),m_Rootmin,m_Rootmax,Mousex,Mousey);
00094 }
00095 
00097 
00098 
00099 void CDasherModel::Get_string_under_mouse(const myint Mousex,const myint Mousey, vector<symbol> &str)
00100 {
00101         m_Root->Get_string_under(Normalization(),m_Rootmin,m_Rootmax,Mousex,Mousey,str);
00102         return;
00103 }
00104 
00106 
00107 
00108 void CDasherModel::Flush(const myint ,const myint )
00109 {
00110         vector<symbol> vtUnder;
00111         Get_string_under_mouse(m_DasherOX,m_DasherOY,vtUnder);
00112         unsigned int i;
00113         for (i=0;i<vtUnder.size();i++) {
00114           if (vtUnder[i]==0)
00115             continue;
00116           m_editbox->flush(vtUnder[i]);
00117         }
00118 }
00119 
00121 
00122 void CDasherModel::Update(CDasherNode *node,CDasherNode *under_mouse,int iSafe)
00123 // go through the Dasher nodes, delete ones who have expired
00124 // decrease the time left for nodes which arent safe
00125 // safe nodes are those which are under the mouse or offspring of this node
00126 {
00127 //      if (node->pushme )
00128 //              node->push_node();
00129         if (node==under_mouse)
00130                 iSafe=1;
00131         if (!iSafe)
00132                 node->Age();
00133 //      dchar debug[256];
00134 //      wsprintf(debug,TEXT("node->Age %d %f\n"),node->Age, fr.framerate());
00135 //      OutputDebugString(debug);
00136         
00137         
00138         if (node->Age() > Framerate())
00139                 node->Kill();
00140         
00141         
00142         if (node->Alive()) {
00143                 CDasherNode **children=node->Children();
00144                 if (children) {
00145                         unsigned int i;
00146                         for (i=1;i<node->Chars();i++)
00147                                 Update(children[i],under_mouse,iSafe);
00148                 }
00149         }
00150         return;
00151 }
00152 
00154 
00155 void CDasherModel::Start()
00156 {
00157         m_Rootmin=0;
00158         m_Rootmax=m_DasherY;
00159         
00160         delete m_Root;
00161         CLanguageModel::CNodeContext* therootcontext=m_languagemodel->GetRootNodeContext();
00162         
00163         //Rootparent=new DasherNode(0,0,0,therootcontext,0,0,0,Normalization(),languagemodel);  
00164         if (m_editbox) {
00165                 m_editbox->set_flushed(0);
00166                 string ContextString;
00167                 m_editbox->get_new_context(ContextString,5);
00168                 if (ContextString.size() != 0) {
00169                   m_languagemodel->EnterText(therootcontext, ContextString);
00170                 }
00171                 m_languagemodel->ReleaseNodeContext(LearnContext);
00172                 LearnContext = m_languagemodel->CloneNodeContext(therootcontext);
00173         }
00174         m_Root=new CDasherNode(0,0,0,0,Opts::Nodes1,0,Normalization(),m_languagemodel);
00175         m_Root->Push_Node(therootcontext);
00176         
00177         m_languagemodel->ReleaseNodeContext(therootcontext);
00178 //      ppmmodel->dump();
00179 //      dump();
00180         
00181 }
00182 
00184 
00185 void CDasherModel::Get_new_root_coords(myint Mousex,myint Mousey)
00186 {
00187         // int cappedrate=0;
00188         double dRx=1.0,dRxnew=1.0;
00189         double dRxnew2;
00190 
00191         int iSteps=m_fr.Steps();
00192 
00193         if (Mousex<m_DasherOX) {
00194         //      rx=1.0001*Ixmap[mx]/Ixmap[cx];
00195                 if (Mousex<=0)
00196                         Mousex=1;
00197                 dRx=1.0*m_DasherOX/Mousex;
00198                 dRxnew=pow(dRx,1.0/iSteps);  // or exp(log(rx)/steps) - i think the replacement is faster   
00199         
00200                 dRxnew2=1+(dRx-1)/iSteps;
00201                 //+(rx-1)*(rx-1)*(1.0/fr.steps()-1.0)/2/fr.steps();
00202                 
00203 
00204                 const double dRxmax=m_fr.Rxmax();
00205                 if (dRxnew>dRxmax)
00206                  dRxnew=dRxmax;
00207                 //              cappedrate=1;
00208         } else {
00209                 if (Mousex==m_DasherOX)
00210                         Mousex++;
00211         //              OutputDebugString(TEXT("zoom out\n"));
00212                 dRx=1.0001*m_DasherOX/Mousex;
00213                 dRxnew=exp(log(dRx)/iSteps);
00214         //      get_coords(root->lbnd,root->hbnd,&x1,&y1,&y2);
00215                 //if (x1>0 || y1>0 || y2<CanvasY)
00216                 //go_back_a_char();
00217                 if (m_Rootmax<m_DasherY && m_Rootmin>0)
00218                         return;
00219         } 
00220 //      dchar debug[256];
00221 //      _stprintf(debug,TEXT("rx %f rxnew %f approx %f\n"),rx,rxnew,rxnew2);
00222 //      OutputDebugString(debug);
00223         //wsprintf(debug,TEXT("rx %f rxnew %f\n"),rx,rxnew);
00224         //OutputDebugString(debug);
00225         myint above=(Mousey-m_Rootmin);//*(1-rxnew)/(1-rx);
00226         myint below=(m_Rootmax-Mousey);//*(1-rxnew)/(1-rx);
00227 
00228 //      wsprintf(debug,TEXT("above %I64d below %I64d \n"),above,below);
00229 //      OutputDebugString(debug);
00230 
00231         myint miDistance=m_DasherY/2-Mousey;
00232         miDistance=myint(miDistance*(dRxnew-1)/(dRx-1));
00233         myint miNewrootzoom=Mousey+miDistance;
00234 
00235         myint newRootmax=miNewrootzoom+myint(below*dRxnew);
00236         myint newRootmin=miNewrootzoom-myint(above*dRxnew);
00237         if (newRootmin<m_DasherY/2 && newRootmax>m_DasherY/2 && newRootmax<LLONG_MAX && newRootmin>LLONG_MIN) {
00238                 m_Rootmax=newRootmax;
00239                 m_Rootmin=newRootmin;   
00240         }
00241 
00242 }
00243 
00245 
00246 void CDasherModel::Tap_on_display(myint miMousex,myint miMousey, unsigned long ) 
00247         // work out the next viewpoint, opens some new nodes
00248 {
00249         // works out next viewpoint
00250         Get_new_root_coords(miMousex,miMousey);
00251 
00252         // opens up new nodes
00253 
00254         // push node under mouse
00255         CDasherNode *under_mouse=Get_node_under_mouse(miMousex,miMousey);
00256         under_mouse->Push_Node();
00257 
00258 
00259         if (Framerate() > 4) {
00260                 // push node under mouse but with x coord on RHS
00261                 CDasherNode *right=Get_node_under_mouse(50,miMousey);
00262                 right->Push_Node();
00263         }
00264 
00265         if (Framerate() > 8) {
00266                 // push node under the crosshair
00267                 CDasherNode *under_cross=Get_node_under_crosshair();
00268                 under_cross->Push_Node();
00269         }
00270 
00271         unsigned int iRandom;
00272 #if defined(_WIN32_WCE)
00273         iRandom=Random();
00274 #else
00275         iRandom=rand();
00276 #endif
00277         if (Framerate() > 8) {
00278                 // add some noise and push another node
00279                 CDasherNode *right=Get_node_under_mouse(50,miMousey+iRandom%500-250);
00280                 right->Push_Node();
00281         }
00282 #if defined(_WIN32_WCE)
00283         iRandom=Random();
00284 #else
00285         iRandom=rand();
00286 #endif
00287         if (Framerate() > 15) {
00288                 // add some noise and push another node
00289                 CDasherNode *right=Get_node_under_mouse(50,miMousey+iRandom%500-250);
00290                 right->Push_Node();
00291         }
00292 
00293         // only do this is Dasher is flying
00294         if (Framerate() > 30) {
00295                 for (int i=1;i<int(Framerate()-30)/3;i++) {
00296 #if defined(_WIN32_WCE) 
00297                 iRandom=Random();
00298 #else
00299                 iRandom=rand();
00300 #endif
00301                 // push at a random node on the RHS
00302                 CDasherNode *right=Get_node_under_mouse(50,miMousey+iRandom%1000-500);
00303                 right->Push_Node();
00304         
00305                 }
00306         }
00307         Update(m_Root,under_mouse,0);
00308 
00309 
00310 }
00311 
00313 
00314 void CDasherModel::Dump() const 
00315         // diagnostic dump
00316 {
00317                 // OutputDebugString(TEXT(" ptr   symbol   context Next  Child    pushme pushed cscheme   lbnd  hbnd \n"));
00318                 m_Root->Dump_node();
00319 }
00320 
00321 
00322 

Generated on Sat Nov 5 16:16:00 2005 for OPIE by  doxygen 1.4.2