473,770 Members | 2,028 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

[Possibly OT] How to handle text parsing functions?

In my program I am accepting messages over the network and parsing them. I
find that the function that does this has gotten quite big, and so want to
break the if else code into functions. I started thinking of how to do
this, but came up with a number of ways and don't know what would be best,
and fit into the C++ idoism.

This is what I have now:

if ( ThisPlayer.Char acter.GMLevel == 100 && ( StrMessage == "/debugserver"
|| StrMessage == "/DEBUGSERVER" ) )
DebugMode = ! DebugMode;

else if ( StrMessage == "/list" || StrMessage == "/LIST" )
{
// lots of cod here
}

else if ( ThisPlayer.Char acter.GMLevel >= 50 && ( StrMessage.comp are( 0, 8,
"/summon " ) == 0 || StrMessage.comp are( 0, 8, "/SUMMON " ) == 0 ) )
{
// lots of code here
}

else if ( ThisPlayer.Char acter.GMLevel >= 50 && ( StrMessage.comp are( 0, 8,
"/jumpto " ) == 0 || StrMessage.comp are( 0, 8, "/JUMPTO " ) == 0 ) )
{
// lots of code here
}

etc.. There are actually 30 different else if's. As you can imagine, the
code is quite huge. The simplest thing would to take each // lots of code
here and make them functions and call them. But then I was thinking I could
just pass the GMLevel and StrMessage to the functions themselves. Then I
started thinking about maybe having some type of custom map type container
with the criteria (keyword and GMLevel) and a pointer to the function,
etc...

Over time this is just going to grow. This is the main text processing for
my online game and commands will only get added, not removed over time.

I can think of having a structure/class with Minimim GMLevel, keyword,
pointer to function call. There shouldn't be too much of a problem with
having to pass parameters to the class because of the game system constrains
I have a global structure that I can access what I need anyway.

What would be your suggestion?
Sep 25 '06 #1
4 1910
In a possible solution I am looking at this (something I just took 10
minutes to wrote but haven't tested yet). Any comments?

typedef bool (*CmdFuncPointe r)( CPlayer& ThisPlayer, const std::string&
Message );

class CChatCommand
{
public:
unsigned int GMLevel; // minimum GMLevel
std::string Command; // Command string that calls (I.E. /kick)
CmdFuncPointer CmdFunc; // Command to process

CChatCommand( const unsigned int GMLevel, const std::string& Command,
const CmdFuncPointer CmdFunc ):
GMLevel( GMLevel ), Command( Command ), CmdFunc( CmdFunc ) {}
};

class CProcessChatMes sage
{
public:
void AddCommand( const unsigned int GMLevel, const std::string& Command,
CmdFuncPointer CmdFunc )
{
Commands.push_b ack( CChatCommand( GMLevel, Command, CmdFunc ) );
}
bool ProcessMessage( CPlayer& ThisPlayer, const std::string& Message )
{
for ( std::vector<CCh atCommand>::ite rator it = Commands.begin( ); it
!= Commands.end(); ++it )
{
if ( Message.compare ( 0, (*it).Command.l ength(), (*it).Command )
== 0 &&
( (*it).Command[(*it).Command.l ength() - 1 ] != ' ' ||
Message.length( ) == (*it).Command.l ength() ) &&
ThisPlayer.Char acter.GMLevel >= (*it).GMLevel )
{
(*(*it).CmdFunc )( ThisPlayer, Message );
return true;
}
}
return false;
}
private:
std::vector<CCh atCommandComman ds;
};
Sep 25 '06 #2
Jim Langston <ta*******@rock etmail.comwrote :
In my program I am accepting messages over the network and parsing them. I
find that the function that does this has gotten quite big, and so want to
break the if else code into functions. I started thinking of how to do
this, but came up with a number of ways and don't know what would be best,
and fit into the C++ idoism.
This may not work for you since you are receiving the messages over the
network and they appear to be plain strings, but IMO the "idiomatic" way
to do it would be to have a "Command" base class with a virtual
"execute()" method or somesuch, and each specific command would be
derived from the Command base class. I believe there is a design
pattern for this.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Sep 25 '06 #3

"Marcus Kwok" <ri******@gehen nom.invalidwrot e in message
news:ef******** **@news-int2.gatech.edu ...
Jim Langston <ta*******@rock etmail.comwrote :
In my program I am accepting messages over the network and parsing them.
I
find that the function that does this has gotten quite big, and so want
to
break the if else code into functions. I started thinking of how to do
this, but came up with a number of ways and don't know what would be
best,
and fit into the C++ idoism.

This may not work for you since you are receiving the messages over the
network and they appear to be plain strings, but IMO the "idiomatic" way
to do it would be to have a "Command" base class with a virtual
"execute()" method or somesuch, and each specific command would be
derived from the Command base class. I believe there is a design
pattern for this.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
You might want to look at the chain of command design pattern.

Each of you possibilities would be modelled as a separate subclass of a
common base class. You would register instances of these
classes to handle the messages. When a message arrives, you would iterate
through each of the instances
calling a virual function such as "execute()" . If the object handles that
message, it would process the message, then
return true, otherwise false, and you'd try the next object in the sequence.
You should check that you need to
continue processing after each "execute()" call .

The benefit of this approach is each object is simple and self contained.
Adding new messages is also very easy,
and the behavior can be dynamic, ie, messages handlers can be added or
removed as the situation requires.


Sep 26 '06 #4
In article <le************ **@newsfe02.lga >, ta*******@rocke tmail.com
says...
In my program I am accepting messages over the network and parsing them. I
find that the function that does this has gotten quite big, and so want to
break the if else code into functions. I started thinking of how to do
this, but came up with a number of ways and don't know what would be best,
and fit into the C++ idoism.
[ ... ]
Over time this is just going to grow. This is the main text processing for
my online game and commands will only get added, not removed over time.

I can think of having a structure/class with Minimim GMLevel, keyword,
pointer to function call. There shouldn't be too much of a problem with
having to pass parameters to the class because of the game system constrains
I have a global structure that I can access what I need anyway.

What would be your suggestion?
A couple of minor suggestions: first of all, instead of making the block
of code functions, I'd probably make them class objects. They give you
more flexibility in the long run. You might not need it now, but the
penalty is low (a couple extra lines of code for each) and in the long
run the flexibility is likely to pay off. For simplicity, I'd probably
derive them all from a fairly simple base class.

Second, instead of making the framework directly aware of the GMLevel,
I'd probably have each of those functors include a "check" function or
something like that, that could look at a player object to determine
whether the player can carry out that action. Make it a virtual
function, and have the base class version simply check whether the
player's GMLevel is high enough -- but someday, when you decide an
action requires GMLevel X _and_ the player to be carrying object Y (or
whatever) it'll be easy to handle. Again, the penalty now is minimal,
and the long-term payoff is potentially fairly high.

You also mentioned using a custom map type -- nothing you've said
convinces me that you need anything std::map doesn't provide. The
keyword is the key for your map, and the value type will be a pointer to
the "action" object. From what you've said so far, the base class would
look something like this:

class player;

class action {
int req_GMLevel;
public:
virtual bool check(player const &p) {
return p->GMLevel>= req_GMLevel;
}
virtual void exec() = 0;
}

From there your framework looks something like this:

// Do a case-insensitive comparison to avoid repeating comparisons,
// as well as allowing, e.g., "/List" along with "/list" and "/LIST"
//
struct cmp {
// Q&D case-insensitive comparison: convert a copy of each
// string to upper case, and compare those copies:
//
bool operator()(std: :string a, std::string b) {
std::transform( a.begin(), a.end(), a.begin(), std::toupper);
std::transform( b.begin(), b.end(), a.begin(), std::toupper);
std::string::si ze_type len = b.size();
return a.compare(0, len, b) == 1;
}
};

// We'll be using this a couple of times and don't want to re-type it:
typedef std::map<std::s tring, action *, cmpactions_map;

// The actual map from command names to actions:
actions_map actions;

// Create our actual actions. Each must override execute().
// Each can override check() if more complex criteria ever arise
// for qualifying a player to carry out a particular action:
class lister : public action { /* ... */ } list;
class summoner: public action { /* ... */ } summon;
class jumper : public action { /* .. .*/ } jump;
// 27 more action classes here...

// Set up the map from commands to actions:
actions["/list"] = &list;
actions["/summon"] = &summon;
actions["/jumpto"] = &jump;
// 27 more command/action pairs here...

// Execute a command from the user:
//
// look the command up in the map
actions_map::it erator it = actions.find(st rMessage);

// if it wasn't found, tell the user:
if (actions.end() == it)
std::cerr<<"Sor ry, I don't understand: \""<< strMessage<<"\" \n";
// it was found; check whether the player can do that
else if (it->second.check(p layer)))
// and if so, do it.
it->second.execute ();
else
// otherwise, tell them they can't.
std::cerr << "Sorry, you can't do that\n";

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 27 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
3643
by: Rohit | last post by:
Hi, Threads in the .NET Framework 1.1 (and possibly in 1.0 also) leak "Event" handles, by Event handles I mean Win32 Event handles which can be monitored using the ProcessExplorer from www.sysinternals.com, or even simply look at the Handle count in the good old windows TaskManager. To demonstrate the problem, all I did was created a basic Win Forms application and with Main implemented as:
2
3055
by: Indiana Epilepsy and Child Neurology | last post by:
Before asking this questions I've spent literally _years_ reading (Meyer, Stroustrup, Holub), googling, asking more general design questions, and just plain thinking about it. I am truly unable to figure out what would be a "proper" OO design (in C++) for this. There may be alternatives to writing my own ODBC handle classes, and I may be interested in them, but I'd like to pursue this particular problem, if for no other reason than to...
9
5399
by: bobo | last post by:
Hi, I have table wich looks like that id detail 1 value1=15,value2=345,value3=2 2 value1=1523,value2=32,value3=2322 3 value1=2,value2=45,value3=34 How can I change it to this: id value1 value2 value3
4
2474
by: atv | last post by:
Whatis the proper way to handle errors from function calls? For example, i normally have a main function, with calls to mine or c functions. Should i check for errors in the functions called themselves, or should i return a code to main and handle the error there? If i don't return them to main, except for the structure, what use is the main function except for calling functions?
4
1727
by: Hugh | last post by:
Hello, I am having some problems understanding (most likely), parsing a text file. I would like to parse a file like: block1 { stuff; ... stuffN; };
3
4266
by: Richard | last post by:
I have a requirement to put a GDI style circle or rectangle border around the selected row of a datagrid/ It will overlap into the row above and below the selected row. Doing this in a the OnPaint of a subclassed DataGridTextBoxColum dos not seem like a practical way to do it. I have subclassed a DataGrid and overridden the OnPaint as such:
6
2685
by: Jacob Rael | last post by:
Hello, I have a simple script to parse a text file (a visual basic program) and convert key parts to tcl. Since I am only working on specific sections and I need it quick, I decided not to learn/try a full blown parsing module. My simple script works well until it runs into functions that straddle multiple lines. For example: Call mass_write(&H0, &HF, &H4, &H0, &H5, &H0, &H6, &H0, &H7, &H0, &H8, &H0, _
3
4386
by: toton | last post by:
Hi, I have some ascii files, which are having some formatted text. I want to read some section only from the total file. For that what I am doing is indexing the sections (denoted by .START in the file) with the location. And for a particular section I parse only that section. The file is something like, .... DATAS
13
2835
by: charliefortune | last post by:
I am fetching some product feeds with PHP like this $merch = substr($key,1); $feed = file_get_contents($_POST); $fp = fopen("./feeds/feed".$merch.".txt","w+"); fwrite ($fp,$feed); fclose ($fp); and then parsing them with PHP's native parsing functions. This is succesful for most of the feeds, but a couple of them claim to be
0
9618
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9454
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
10038
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9906
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8933
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6712
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5354
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5482
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2850
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.