Author: egon
Date: 2004-10-11 09:38:35 -0400 (Mon, 11 Oct 2004)
New Revision: 377

Added:
   trunk/clients/wxhaver/wxHaverParser.cpp
   trunk/clients/wxhaver/wxHaverParser.h
Modified:
   trunk/clients/wxhaver/wxHaver.cpp
   trunk/clients/wxhaver/wxHaver.h
   trunk/clients/wxhaver/wxHaverFrame.cpp
   trunk/clients/wxhaver/wxHaverFrame.h
Log:
wxHaver command handler written. (Yay!)

Modified: trunk/clients/wxhaver/wxHaver.cpp
===================================================================
--- trunk/clients/wxhaver/wxHaver.cpp   2004-10-11 11:42:01 UTC (rev 376)
+++ trunk/clients/wxhaver/wxHaver.cpp   2004-10-11 13:38:35 UTC (rev 377)
@@ -3,6 +3,8 @@
  */
 
 #include "wxHaver.h"
+#include "wxHaverFrame.h"
+#include "wxHaverParser.h"
 
 #include "wx/splitter.h"
 

Modified: trunk/clients/wxhaver/wxHaver.h
===================================================================
--- trunk/clients/wxhaver/wxHaver.h     2004-10-11 11:42:01 UTC (rev 376)
+++ trunk/clients/wxhaver/wxHaver.h     2004-10-11 13:38:35 UTC (rev 377)
@@ -14,8 +14,6 @@
 #include "wx/wx.h"
 #endif
 
-#include "wxHaverFrame.h"
-
 enum {
        WH_ID_Quit = 1,
        WH_ID_Connect,

Modified: trunk/clients/wxhaver/wxHaverFrame.cpp
===================================================================
--- trunk/clients/wxhaver/wxHaverFrame.cpp      2004-10-11 11:42:01 UTC (rev 
376)
+++ trunk/clients/wxhaver/wxHaverFrame.cpp      2004-10-11 13:38:35 UTC (rev 
377)
@@ -6,8 +6,13 @@
 //------------------------------------------------------------------------
 
 #include "wxHaverFrame.h"
+#include "wxHaverParser.h"
 #include "wx/socket.h"
+#include <vector>
+#include <map>
 
+using namespace std;
+
 BEGIN_EVENT_TABLE(wxHaverFrame, wxFrame)
        EVT_MENU(WH_ID_Quit, wxHaverFrame::OnQuit)
        EVT_MENU(WH_ID_Connect, wxHaverFrame::OnConnect)
@@ -53,6 +58,10 @@
 
        SetSizer(topsizer);
 
+       wxHaverCallback<wxHaverFrame> *want = new wxHaverCallback<wxHaverFrame>
+               (this, &wxHaverFrame::OnWant);
+       mParser.AddCommand("WANT", want);
+       
        mSock = new wxSocketClient();
        mSock->SetEventHandler(*this, WH_Socket);
        mSock->SetNotify(wxSOCKET_CONNECTION_FLAG | wxSOCKET_INPUT_FLAG |
@@ -80,27 +89,32 @@
 
 void wxHaverFrame::OnSocketEvent(wxSocketEvent &event)
 {
-       *mTextLines << "\nSocketEvent received.";
+       *mTextLines << "\nSocketEvent received: ";
+       switch (event.GetSocketEvent())
+       {
+               case wxSOCKET_INPUT:
+                       *mTextLines << "wxSOCKET_INPUT"; break;
+               case wxSOCKET_OUTPUT:
+                       *mTextLines << "wxSOCKET_OUTPUT"; break;
+               case wxSOCKET_CONNECTION:
+                       *mTextLines << "wxSOCKET_CONNECTION"; break;
+               case wxSOCKET_LOST:
+                       *mTextLines << "wxSOCKET_LOST"; break;
+       }
        if (event.GetSocketEvent() == wxSOCKET_INPUT) {
                // TODO: Write a better line handler, with buffering.
-               *mTextLines << "\nIt's a SOCKET_INPUT";
-               wxChar buf;
-               wxString str;
-               int gotcrlf = -1;
-               
+               char buf[1024];
+               wxString line;
+               mSock->Read(buf, 1024);
+               mBuf.Append(buf, mSock->LastCount());
                for (;;) {
-                       if (buf == '\r')
-                               gotcrlf++;
-                       mSock->Read(&buf, 1);
-                       str += buf;
-                       if (gotcrlf >= 0 && buf == '\n') {
-                               gotcrlf++;
-                               str += buf;
-                               break;
-                       }
+                       line = mBuf.BeforeFirst('\n');
+                       if (line == mBuf) break;
+                       mTextLines->AppendText(_T("\n(raw) ") + line);
+                       printf("line: %s\n", line.c_str());
+                       mParser.Parse(line);
+                       mBuf = mBuf.AfterFirst('\n');
                }
-               
-               mTextLines->AppendText(_T("\n(raw) ") + str);
        }
 }
 
@@ -131,134 +145,16 @@
        Close(true);
 }
 
-/* Some default text.
- */
-
 //------------------------------------------------------------------------
-//  wxHaverFrame
+//  Haver Command Callbacks
 //------------------------------------------------------------------------
 
-#include "wxHaverFrame.h"
-#include "wx/socket.h"
-
-BEGIN_EVENT_TABLE(wxHaverFrame, wxFrame)
-       EVT_MENU(WH_ID_Quit, wxHaverFrame::OnQuit)
-       EVT_MENU(WH_ID_Connect, wxHaverFrame::OnConnect)
-       EVT_SPLITTER_SASH_POS_CHANGED(WH_CTRL_ServerSplitter,
-                       wxHaverFrame::OnSashPosChanged)
-       EVT_SIZE(wxHaverFrame::OnSize)
-       EVT_SOCKET(WH_Socket, wxHaverFrame::OnSocketEvent)
-END_EVENT_TABLE()
-
-wxHaverFrame::wxHaverFrame(const wxString &title, const wxPoint &pos,
-               const wxSize &size):
-       wxFrame((wxFrame*)NULL, -1, title, pos, size), _splitSize(100)
+void wxHaverFrame::OnWant(vector<wxString> args)
 {
-       wxMenu *File_menu = new wxMenu;
-       File_menu->Append(WH_ID_Quit, "E&xit");
-       File_menu->Append(WH_ID_Connect, "&Connect");
-
-       wxMenuBar *menuBar = new wxMenuBar;
-       menuBar->Append(File_menu, "&File");
-
-       SetMenuBar(menuBar);
-
-       mServerSplit = new wxSplitterWindow(this, WH_CTRL_ServerSplitter,
-               wxDefaultPosition, wxDefaultSize, wxSP_LIVE_UPDATE);
-       mTextLines      = new wxTextCtrl(mServerSplit, -1, "", 
wxDefaultPosition, wxDefaultSize,
-                       wxTE_MULTILINE);
-       mTextEntry      = new wxTextCtrl(this, -1);
-       mUserList       = new  wxListBox(mServerSplit, -1);
-
-       wxSize txtsize(mTextEntry->GetSize());
-       wxSize boxsize(mUserList->GetSize());
-       wxSize clientsize(GetClientSize());
-       mTextEntry->SetSize(0, clientsize.y - txtsize.y, clientsize.x, 
txtsize.y);
-       mUserList->SetSize(clientsize.x - 100, 0, 100, clientsize.y - 
txtsize.y);
-       mTextLines->SetSize(0, 0, clientsize.x - 100, clientsize.y - txtsize.y);
-
-       mTextLines->SetEditable(false);
-       mServerSplit->SplitVertically(mTextLines, mUserList, -_splitSize);
-
-       wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
-       topsizer->Add(mServerSplit, 1, wxGROW);
-       topsizer->Add(mTextEntry, 0, wxGROW);
-
-       SetSizer(topsizer);
-
-       mSock = new wxSocketClient();
-       mSock->SetEventHandler(*this, WH_Socket);
-       mSock->SetNotify(wxSOCKET_CONNECTION_FLAG | wxSOCKET_INPUT_FLAG |
-                       wxSOCKET_LOST_FLAG);
-       mSock->Notify(true);
-}
-
-wxHaverFrame::~wxHaverFrame()
-{
-       mSock->Destroy();
-}
-
-void wxHaverFrame::OnSashPosChanged(wxSplitterEvent &event)
-{
-       _splitSize = GetClientSize().GetWidth() - event.GetSashPosition();
-       event.Skip();
-}
-
-void wxHaverFrame::OnSize(wxSizeEvent& event)
-{
-       if (mServerSplit)
-               mServerSplit->SetSashPosition(GetClientSize().GetWidth() - 
_splitSize);
-       event.Skip();
-}
-
-void wxHaverFrame::OnSocketEvent(wxSocketEvent &event)
-{
-       *mTextLines << "\nSocketEvent received.";
-       if (event.GetSocketEvent() == wxSOCKET_INPUT) {
-               *mTextLines << "\nIt's a SOCKET_INPUT";
-               wxChar buf;
-               wxString str;
-               int gotcrlf = -1;
-               
-               for (;;) {
-                       if (buf == '\r')
-                               gotcrlf++;
-                       mSock->Read(&buf, 1);
-                       str += buf;
-                       if (gotcrlf >= 0 && buf == '\n') {
-                               gotcrlf++;
-                               str += buf;
-                               break;
-                       }
-               }
-               
-               mTextLines->AppendText(_T("\n(raw) ") + str);
+       *mTextLines << "\nReceived WANT...";
+       if (args[0] == "VERSION") {
+               char cmd[] = "VERSION\twxHaver/" WH_VERSION_STRING CRLF;
+               mSock->Write(cmd, sizeof(cmd));
+               *mTextLines << "\nSending version info...";
        }
 }
-
-void wxHaverFrame::OnConnect(wxCommandEvent& WXUNUSED(event))
-{
-       wxIPV4address addr;
-       addr.Hostname("localhost");
-       addr.Service(7071);
-
-       mTextLines->AppendText(_T("\nConnecting to ") + addr.Hostname() + 
_("..."));
-       mSock->Connect(addr, false);
-       mSock->WaitOnConnect(10);
-       
-       if (mSock->IsConnected())
-               mTextLines->AppendText(_T("\nSuccess. Connection 
established."));
-       else {
-               mSock->Close();
-               mTextLines->AppendText(_T("\nFailed. Unable to connect."));
-               wxString errortext;
-               errortext << "Could not connect to " << addr.Hostname() <<
-                       " on port " << addr.Service();
-               wxMessageBox(errortext, "Alert!");
-       }
-}
-
-void wxHaverFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
-{
-       Close(true);
-}

Modified: trunk/clients/wxhaver/wxHaverFrame.h
===================================================================
--- trunk/clients/wxhaver/wxHaverFrame.h        2004-10-11 11:42:01 UTC (rev 
376)
+++ trunk/clients/wxhaver/wxHaverFrame.h        2004-10-11 13:38:35 UTC (rev 
377)
@@ -7,9 +7,11 @@
 #define WH_wxHaverFrame_H
 
 #include "wxHaver.h"
+#include "wxHaverParser.h"
 
 #include "wx/splitter.h"
 #include "wx/socket.h"
+#include <vector>
 
 class wxHaverFrame : public wxFrame
 {
@@ -26,12 +28,16 @@
                void OnSashPosChanged(wxSplitterEvent&);
 
                void OnSocketEvent(wxSocketEvent&);
+
+               void OnWant(std::vector<wxString>);
        private:
                wxSocketClient *mSock;
                wxSplitterWindow *mServerSplit;
                wxTextCtrl      *mTextLines;
                wxTextCtrl      *mTextEntry;
                wxListBox       *mUserList;
+               wxHaverParser mParser;
+               wxString        mBuf;
                int _splitSize;
 
        DECLARE_EVENT_TABLE()

Added: trunk/clients/wxhaver/wxHaverParser.cpp
===================================================================
--- trunk/clients/wxhaver/wxHaverParser.cpp     2004-10-11 11:42:01 UTC (rev 
376)
+++ trunk/clients/wxhaver/wxHaverParser.cpp     2004-10-11 13:38:35 UTC (rev 
377)
@@ -0,0 +1,79 @@
+/* Some default text.
+ *
+ * wxHaverParser class implementation, plus some functions :$ :P
+ */
+
+#include "wxHaver.h"
+#include "wxHaverParser.h"
+#include <vector>
+#include <map>
+#include <string>
+
+using namespace std;
+
+inline void Strip(wxString &line)
+{
+       if (line.find('\r') >= 0)
+               line.Remove(line.find('\r'), 1);
+}
+
+vector<wxString> Split(wxString line, wxString splitby)
+{
+       printf("Splitting \"%s\" by \"%s\"\n", line.c_str(), splitby.c_str());
+       size_t tp;
+       vector<wxString> tokens;
+       while (tp = line.find(splitby)) {
+               if (tp == wxString::npos) break;
+               tokens.push_back(line.substr(0, tp));
+               line.erase(0, tp+1);
+       }
+       // pick up on that last token
+       tokens.push_back(line);
+       return tokens;
+}
+
+wxString Splice(vector<wxString> tokens, wxString splicewith)
+{
+       wxString spliced;
+       for (vector<wxString>::iterator i = tokens.begin();
+                       i < tokens.end() - 1; i++) {
+               spliced += *i + splicewith;
+       }
+       spliced += *(tokens.end() - 1);
+       return spliced;
+}
+
+//------------------------------------------------------------------------
+//  wxHaverParser
+//------------------------------------------------------------------------
+
+wxHaverParser::wxHaverParser()
+{
+       // TODO: Add default commands?
+}
+
+int wxHaverParser::AddCommand(wxString cmdname, wxHaverFunctor *callback)
+{
+       _commands[cmdname] = callback;
+}
+
+int wxHaverParser::DelCommand(wxString cmdname)
+{
+       _commands.erase(cmdname);
+}
+
+void wxHaverParser::Parse(wxString line)
+{
+       Strip(line);
+       printf("Got line \"%s\" to parse\n", line.c_str());
+       vector<wxString> cmd = Split(line, "\t");
+       if (_commands.find(cmd[0]) == _commands.end()) {
+               printf("Command %s doesn't exist\n", cmd[0].c_str());
+               return;
+       }
+       printf("Command exists\n");
+       wxString command = cmd[0];
+       cmd.erase(cmd.begin());
+       (*_commands[command])(cmd);
+}
+

Added: trunk/clients/wxhaver/wxHaverParser.h
===================================================================
--- trunk/clients/wxhaver/wxHaverParser.h       2004-10-11 11:42:01 UTC (rev 
376)
+++ trunk/clients/wxhaver/wxHaverParser.h       2004-10-11 13:38:35 UTC (rev 
377)
@@ -0,0 +1,61 @@
+/* Some default text.
+ *
+ * The wxHaverParser class interface.
+ */
+
+#ifndef WH_wxHaverParser_H
+#define WH_wxHaverParser_H
+
+#include "wxHaver.h"
+#include <vector> // I think wxArray is dumb. :P So unless I (or someone else)
+#include <map>   // can be bothered to learn and implement wxArray instead,
+                                 // I'm sticking with std::vector and std::map.
+
+#define CRLF   "\r\n"
+
+// A command_func is a pointer to a function that takes a
+// std::vector<wxString> as its argument (this contains the command's
+// arguments) and returns void.
+// TODO: Think about prefixes.
+typedef void(*command_func)(std::vector<wxString>);
+
+// Strips the trailing CRLF off a line.
+inline void Strip(wxString &line);
+
+// Split one wxString by another.
+std::vector<wxString> Split(wxString line, wxString splitby = "\t");
+
+// Splice a bunch of wxStrings together with splicewith.
+wxString Splice(std::vector<wxString> tokens, wxString splicewidth = "\t");
+
+class wxHaverFunctor
+{
+       public:
+               virtual void operator()(std::vector<wxString>)=0;
+               virtual void Call(std::vector<wxString>)=0;
+};
+
+template<class T> class wxHaverCallback : public wxHaverFunctor
+{
+       private:
+               void (T::*fpt)(std::vector<wxString>);
+               T* pt2Obj;
+       public:
+               wxHaverCallback(T *_pt2Obj, 
void(T::*_fpt)(std::vector<wxString>)):
+                       pt2Obj(_pt2Obj), fpt(_fpt) {}
+               void operator()(std::vector<wxString> args) { 
(*pt2Obj.*fpt)(args); }
+               void Call(std::vector<wxString> args) { (*pt2Obj.*fpt)(args); }
+};
+
+class wxHaverParser
+{
+       public:
+               wxHaverParser();
+               int AddCommand(wxString cmdname, wxHaverFunctor *callback);
+               int DelCommand(wxString cmdname);
+               void Parse(wxString line);
+       private:
+               std::map<wxString, wxHaverFunctor*> _commands;
+};
+
+#endif // WH_wxHaverParser_H


Reply via email to