[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ Programming ➜ STL ➜ Columned Displays?

Columned Displays?

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Davion   Canada  (10 posts)  Bio
Date Sun 23 Apr 2006 07:15 PM (UTC)
Message
Just wondering if you have a good way to column a list? Ie.

[ look] [ find] [ jog] [ jump]
[ scan] [ run] [ dash] [dance]


I've been trying to toy with for_each, but I can't quite figure it out.

Davion
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #1 on Sun 23 Apr 2006 07:31 PM (UTC)
Message
What you need to do is first figure out how many columns you will need/have. Then, for each column, you'd figure out what the widest element of that column is. Once you have that maximum width, you can print out each element to fit into that width. I'm not sure if for_each would actually work in this case, since you're not doing the same thing to each element.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Davion   Canada  (10 posts)  Bio
Date Reply #2 on Sun 23 Apr 2006 07:52 PM (UTC)
Message
*nodnod* Thanks! Actually kept toying with it after I posted and just finished :) Here's what I go


class cmdDisplay
{	int iLength;
	String str;
	public:
	cmdDisplay() : iLength(0) { str.Empty(); };
	void operator()(CmdType *cmmd )
	{	iLength++;
		cmmd->Display(str, iLength);
	}
	void SendCmds(Entity *en)
	{	en->Send("%s", *str);
	}
};

void Interpreter::doCmdList(Entity *en, String &arguments)
{	for_each(en->interp->cmdList.begin(),
		 en->interp->cmdList.end(),
		 cmdDisplay() ).SendCmds(en);
	return;
}
void CmdType::Display(String &rhs, int length)
{	char buf[10000];
	sprintf(buf, "[%-10s]", &(*name));
	rhs << buf;
	if( !(length % 4 ) ) rhs << "\n\r";
}




Excuse the horrible hacking of Display :) I haven't quite finished my string lib, so it's a bit... strange atm :). Seems to work very nicely though!

Davion
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #3 on Sun 23 Apr 2006 08:05 PM (UTC)
Message
Oh yeah. I forgot about function objects and how they let you do the "same" operation every time. *bonk self* I'm curious; have you tested it and is it working? Looks good to me... Of course, you're giving the same width to every column, which makes things easier.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Davion   Canada  (10 posts)  Bio
Date Reply #4 on Sun 23 Apr 2006 08:21 PM (UTC)
Message
Looks like it! The most any of my interpreters have is 4 commands, so I dropped columning down to two, and it worked fine!


command
[create ][setpasswd ]
[login ][command ]
>


The MudObject stuff in one of the prior threads helped a lot!

Davion
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #5 on Sun 23 Apr 2006 08:28 PM (UTC)
Message
Very good. The STL is really quite amazing when you look at it like this. Look at what you were able to do in so relatively few lines of code. Then think how much it would have been in straight C, and how less elegant it would have been. Bah! :-)

And yes, Nick's guides are excellent; very useful material. Some of them are for the intermediate-level coder, but if you know enough to understand the guides the potential for useful learning is immense.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Davion   Canada  (10 posts)  Bio
Date Reply #6 on Sun 23 Apr 2006 09:19 PM (UTC)

Amended on Sun 23 Apr 2006 09:37 PM (UTC) by Davion

Message
Look at what you were able to do in so relatively few lines of code.

This statement really nudged me. Soo! I went for it

void doDisplay(CHAR_DATA *ch, char *argument)
{    std::list<CmdType *>::iterator i;
     char buf[MSL];
     for(int n = 0, i = ch->interp->begin(); i != ch->interp->end() ; ++i, ++n)
     { sprintf(buf, "[%-10s]", (*i)->name);
       send_to_char(buf,ch);
       if(!(n % 4) )
            send_to_char("\n\r", ch);
     }
}


Just typed that out dunno if it compiles, but that does the same thing in like 1/4 the lines of code. So. I figured, if I'm going to use this, I might as well make it worth while. I switched up my display function to->

template <class T>
class DisplayList
{	int iLength;
	String str;
	public:
	DisplayList() : iLength(0) { str.Empty(); };
	void operator()(T *node )
	{	iLength++;
		node->Display(str, iLength);
	}
	void Send(Entity *en)
	{	en->Send("%s", *str);
	}
};


Now, as long as the type class has a Display() method, it will display it. I understand it's dangerous to assume Display exists, but I don't think I'll be using this on classes where it lacks a Display method. This now seems a bit more practical, rather than writing a new one for each different kind of node.

Davion
Top

Posted by Nick Gammon   Australia  (23,046 posts)  Bio   Forum Administrator
Date Reply #7 on Sun 23 Apr 2006 10:11 PM (UTC)
Message
Very nice!

Strictly speaking, in this line:


cmdDisplay() : iLength(0) { str.Empty(); };


You don't need to do "str.Empty();", because when you define:


String str;


... the constructor is called which I assume initialises it to an empty string (it does for the string class, but you are using String).

However you are correct in initializing iLength because that is a "raw integer" (not a class) and hence is not initialized.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #8 on Mon 24 Apr 2006 01:44 AM (UTC)
Message
I think I read somewhere that some implementations actually will initialize all member variables, including primitives like integers, when you call the new operator. After all, by definition, when you 'new' something, it will initialize all objects in there; I think somebody took that a step further and had it initialize the primitives as well. Since the default constructor for integers is zero, you'd end up with zeroes.

But that's probably non-standard behavior, so don't rely on it... :)
Quote:
I understand it's dangerous to assume Display exists, but I don't think I'll be using this on classes where it lacks a Display method
Oh, don't worry about that... the compiler will happily barf at you if you try to. :P

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Davion   Canada  (10 posts)  Bio
Date Reply #9 on Mon 24 Apr 2006 01:36 PM (UTC)
Message
I think I read somewhere that some implementations actually will initialize all member variables, including primitives like integers, when you call the new operator. After all, by definition, when you 'new' something, it will initialize all objects in there; I think somebody took that a step further and had it initialize the primitives as well.

Never thought of that.


#include <iostream>

class Foo
{       public:
                int bar;
                Foo(){}
};


int main()
{       int i;
        Foo boo;
        std::cout << boo.bar << std::endl << i << std::endl;
        return -1;
}


Output


0
1073831104


Seems all those initializers are redundant! Thanks!

Davion
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


26,784 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]