Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Ivko

Member Since 07 Mar 2001
Offline Last Active Nov 27 2014 03:07 AM

Topics I've Started

boost::function with class member functions?

22 February 2006 - 11:19 PM

I've spent the last few hours trying to figure out how to make a sort of routing table to functions through a std::map. It didn't take long to find out how to use boost::function to make it work for non-member functions - that part works good. Now I'm trying to make it work with class member functions. I realize that it's going to involve some sort of mix of boost function, bind, and mem_fn. It's late now though and I just can't figure out how to put it together to make it work. I realize there's lots of threads on this sort of thing, but usually they start with just plain function pointers and end with "look into boost". Here's some short code that shows what I'm doing right now:
typedef boost::function<void (const std::string &)> CommandFn;
std::map<const std::string, CommandFn > commands;

void test(const string &param) { /* code */ }

void CConsole::RegisterKeys() {
	RegCommand("test_cmd", &test);
}

void CConsole::RegCommand(const string &cmd, CommandFn funct) {
	if(!CommandExists(cmd))
		commands[cmd] = funct;
}

void CConsole::Command(const string &cmd, const string &param) {
	if(CommandExists(cmd))
		commands[cmd](param);
}

That works well, and all it takes to add new commands is
RegCommand("command", &function);
How can I change what I have so far to make it work like this:
RegCommand("command", &CClass::function);
I have a feeling there's not a lot involved to make this work. I'd like to maintain a simple, one-line calling style to RegCommand. Thanks.

Intellisense doesn't work at all with one class

22 February 2006 - 08:52 PM

I'm using MSVS 2005 Professional and intellisense is working for everything but one class. It won't list the members or show any information at all about it. It also won't recognize any member variables that the class possesses (ie, typing "vars." in the source file won't list any std:map methods). I don't know when it stopped working so I'm not sure what I might have done to cause it to break. I tried playing around with it a bit, and I deleted the .ncb file in the project folder and let it rebuild itself. The program compiles fine. Here's the class declaration in the header file:
#ifndef INC_CONSOLE
#define INC_CONSOLE

#include <map>
#include <string>
#include <vector>
#include <algorithm>

class CConsole {
private:
	std::vector<std::string> command_list;
	std::map<const std::string, std::string> vars;

	// Mutators
	void RegisterKeys(); // handles registering of system commands and variables
	void RegCommand(const std::string &cmd); // register command
	void RegVar(const std::string &var, const std::string &def_value = "0");

	// Accessors
	std::string GetParam(const std::string &var, size_t index) const; // gets specific parameter of a variable in string form
	bool CommandExists(const std::string &cmd) const;
	bool VarExists(const std::string &var) const;

public:
	CConsole() { RegisterKeys(); }
	bool Load(const char *filename); // load script and execute lines within it

	bool Exec(const std::string &line); // execute a string line as a command
	void Command(const std::string &cmd, const std::string &param); // command call manager

	// Variable readers and writers
	template<typename T> T Var(const std::string &var, size_t index = 0) const; // get specific parameter of a console variable (defaults to first)
	template<> std::string Var(const std::string &var, size_t index) const; // get full string value of a console variable (no specific parameters)
	std::string &Var(const std::string &var); // return reference to variable value for changing
};


Intellisense doesn't work for this class in any source file. If I declare a dummy class in the same header file, it will recognize the dummy fine everywhere. This is really annoying me. Does anyone know what might fix it?

Logger class: how to perform something once at end of line?

31 December 2005 - 12:29 AM

I'm trying to write a simple but effective logger class. I got most of it working how I want so far, but I have a feeling adding the last step will require either heavily rewriting how it's done right now, or some strange way of doing it. First, here's some of the relevant code (not in final state, but the way it's written and used will be the same). This is in the logger class:
enum log_type { info, warn, error }; // this enum is outside the class (global)
	ofstream &operator <<(log_type obj) { // enumerated log-type is passed
		switch(obj) {
			case info:
				flog << "   <info> ";
				break;
			case warn:
				flog << "<warning> ";
				break;
			case error:
				quit = true;
				flog << "  <error> ";
				break;
		}
		return flog;
	}
	template<class T>
	ofstream &operator <<(T obj) { // something else is passed (not preceded by info, warn, etc)
		flog << "    <log> " << obj;
		return flog;
	}



And it's used like this:
	App << info << "an info " << 1 << 2 << endl;
	App << warn << "a warning " << 3 << 4 << endl;
	App << error << "an error " << 5 << 6 << endl;
	App << "alone" << endl;
	App << 7 << " - preceded by int" << endl;



All of this works exactly how I want it. Now, the problem is, I want a MessageBox to show up with the logged message once endl is reached for the error case. That is, the line [ App << error << "an error " << 5 << 6 << endl; ] should show a MessageBox that will say "an error 56". I can't think of a way to do it other than put everything being logged into a buffer, and then have a macro that will do the normal App << ... thing followed by calling something to MessageBox the stuff in the buffer and clear the buffer. Is there a way to do it while keeping the same usage format as I wrote above? It seems like I'm looking for a way to have the endl trigger a call to the MessageBox buffer thing I described. I guess if I knew how to implement something like the stream formatting system that iostreams uses instead of the enumerating way I'm doing, I'd know how to solve my problem. [Edited by - Ivko on January 1, 2006 4:56:48 AM]

PARTNERS