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