Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
csammis
Aug 26, 2003

Mental Institution

Avenging Dentist posted:

Manually fix the IDs once, never worry about it again (for a while anyway)? If it's anything like resource IDs, it's sequential. For example:

code:
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        108
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1026
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

That solves it for the single developer case (provided we go through each of the project and normalize the resource IDs so that they are sequentially increasing from 1 with no gaps), but let's say we have the following scenario:

1) One developer sets the next resource ID to start at 40000 and checks the change into TFS.
2) The next morning, all developers get that update.
3) Five developers add one string to the same project's string table. Each of those strings has ID 40000.
4) Check-in time! The first developer checks in their change, then the second has to resolve a conflict. The new string is added to #2's table, he compiles again to make sure everything works because he is a good developer, and there is a conflicting ID. Repeat for #3, 4 and 5 :suicide:

This is why I'm thinking about solutions that fix the resource IDs at compile time...that way it really doesn't matter what IDs are used at design time.

Resource lookup by integer is weak as hell, resource lookups by string fo' lyfe

Adbot
ADBOT LOVES YOU

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

csammis posted:

That solves it for the single developer case (provided we go through each of the project and normalize the resource IDs so that they are sequentially increasing from 1 with no gaps), but let's say we have the following scenario:

Ok so you have to resolve conflicts when merging, that's pretty much par for the course with development.

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.
Why can't each developer have his own starting ID?

TSDK
Nov 24, 2003

I got a wooden uploading this one

Sagacity posted:

Why can't each developer have his own starting ID?
Close, but no cigar: per-person code rules are generally a bad idea. Each of the individual projects should have its own unique prefix for string IDs.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

TSDK posted:

Close, but no cigar: per-person code rules are generally a bad idea. Each of the individual projects should have its own unique prefix for string IDs.

I didn't explicitly say anything about per-project stuff since resource files are nothing but per project. String IDs don't exist in the VS resource thing-a-ma-bobber though.

csammis
Aug 26, 2003

Mental Institution

Avenging Dentist posted:

Ok so you have to resolve conflicts when merging, that's pretty much par for the course with development.

Conflict resolution is a fact of development life...that doesn't mean effort shouldn't be taken to reduce the incidence of conflicts.

Avenging Dentist posted:

String IDs don't exist in the VS resource thing-a-ma-bobber though.

Not for C++ anyway. The C# resource editor exposes the string table using string IDs, though it may use integers under the hood.

Lexical Unit
Sep 16, 2003

csammis posted:

Conflict resolution is a fact of development life
Yeah like today when a coworker attempted to remove a symlink that had been checked in and instead removed all the source files in the directory the symlink linked to. He then proceeded to checkin the deletion and push it up to dev w/o bothering to test anything. And when he was made aware of his mistake, he simply copied the files from an old backup into the same path as they were previously located and checked them in as new files.

Sometimes conflicts escalate to physicality...

Bhaal
Jul 13, 2001
I ain't going down alone
Dr. Infant, MD
Could you have developers create a GUID for each resource they add? The downsides of course are 1) if they're stored internally as integers it won't work very well, and 2) it's a bit of an overengineered (and cluttered) solution

huge sesh
Jun 9, 2008

Is there any way to easily implement a simple job queue with callbacks using some combination of boost function libraries? It seems relatively simple to implement one with identical function signatures e.g.

code:
void job(void*) { }
std::queue<boost::function<void(void*)> > job_queue;
boost::function<void(void*)> > func = boost::bind(&job);
queue.push(func);
However, what I'd like to be doing is storing function objects with arbitrary signatures in the queue so that I don't have to serialize & deserialize arguments into structs. Is this possible with boost::bind?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

huge sesh posted:

Is this possible with boost::bind?

Yes.

Lexical Unit
Sep 16, 2003

/\/\ Please elaborate, I could certainly stand to learn more about boost::bind. (Edit: Oh wait I get it, duh. Feel free to burn me with your explanation tho :3:)

huge sesh posted:

code:
void job(void*) { }
std::queue<boost::function<void(void*)> > job_queue;
boost::function<void(void*)> > func = boost::bind(&job);
queue.push(func);
Your code there doesn't compile and I don't believe you're using boost::bind correctly here.

std::queue can't store boost::functions of different signatures because those are different types and std::queue holds just one type. But consider that boost::function allows arbitrary compatible function objects to be targets. How does this strike your fancy?
code:
#include <queue>
#include <iostream>
#include <boost/function.hpp>

using namespace std;

void job(void*) { cout << "boring job" << endl; }

struct special_job
{
	explicit special_job(int x) : x(x) { }
	int x;
	void operator()(void*) { cout << "special job " << x << endl; }
};

int main()
{
	typedef boost::function<void(void*)> callback;
	queue<callback> job_queue;
	job_queue.push (job);
	job_queue.push (special_job (2));
	job_queue.push (special_job (10));
	
	while (!job_queue.empty ())
	{
		job_queue.front () (NULL);
		job_queue.pop ();
	}
}
So if whatever additional parameters your special jobs need are known at queue time, you could workaround this by using functors.


Edit: Or you could just use boost::bind, here's the above code re-worked:
code:
#include <queue>
#include <iostream>

#include <boost/function.hpp>
#include <boost/bind.hpp>

using namespace std;

void job(void*) { cout << "boring job" << endl; }

void special_job(int x, void*) { cout << "special job " << x << endl; }

int main()
{
	typedef boost::function<void(void*)> callback;
	queue<callback> job_queue;
	job_queue.push (job);
	job_queue.push (boost::bind (special_job, 2, _1));
	job_queue.push (boost::bind (special_job, 10, _1));
	
	while (!job_queue.empty ())
	{
		job_queue.front () (NULL);
		job_queue.pop ();
	}
}

Lexical Unit fucked around with this message at 21:37 on Jun 30, 2009

huge sesh
Jun 9, 2008

Thanks, that nailed it.

Foran
Apr 19, 2008

Garry's Mod is an Art
I recently got into C++, and I've been using the PDcurses library to make a small roguelike game.

so far, I've been able to get the player to walk around, hit walls, and such.
I'm trying to have more than 1 room in the window at once. I init two rooms from the room class, draw them, and etc. Unfortunately, the second room does not fill in with floor tiles.

Here is the room class:

code:
class AreaRoom
{
      public:
      //int X;
      //int Y;
      int Width;
      int Breadth;
      
       void        Init(int newX, int newY, int newWidth, int newBreadth)
    {
        X = newX;
        Y = newY;
        Width = newWidth;
        Breadth = newBreadth;
    }
    bool AreaRoom::isWalkable(char newASCIIChar)
{
    int tile = newASCIIChar;
   
    if (tile == FloorTileASCII ||
        tile == PlayerSym || tile == FloorTileASCII2)
    {
        return true;
    }
    else
    {
        return false;
    }
}
    
    
      //int rows;
      //int cols;
      
      /*void ARstart(int Arows, int Acols)
      {
           Arows--;
           Acols--;
           
           mvaddch(0,0,'*');
           refresh();
           
           mvaddch(0,Acols,'*');
           refresh();
           
           mvaddch(Arows,0,'*');
           refresh();
           
           mvaddch(Arows,Acols,'*');
           refresh();
      } */
           
           
      void        DrawArea(int Arows, int Acols)
    {
        //Arows=0;
        //Acols=0;
        //Arows--;
        //Acols--;
        char randFtile;
        int randFtile2;
        char randWtile;
        int randWtile2;
        int DrawX = Acols;       
        int DrawY = Arows;

        // While DrawX is less than X + Width
        while(DrawX < Arows + Width)
        {
            while(DrawY < Acols + Breadth)
            {
                // Draw tile DrawX, DrawY
               /* randFtile2 = rand() % 2 + 1;
                if (randFtile2 == 1)
                {
                randFtile = FloorTileASCII;
                }
                else
                {
                randFtile = FloorTileASCII2;
                }
                mvaddch(DrawX, DrawY, randFtile);
                randFtile2 = rand() % 2 + 1;
                */
                mvaddch(DrawX, DrawY, FloorTileASCII);
                // Add 1 to DrawY
                DrawY = DrawY + 1;
                //testwalls
                //mvaddch(4,DrawY,HorizontalWallASCII);
                //mvaddch(4,5,FloorTileASCII);
            }
            // Add 1 to DrawX
            DrawX = DrawX + 1;
            // Reset DrawY for next line...
            DrawY = Acols;
        }

        DrawX = Arows;       

        // While DrawX is less than X + Width
        while(DrawX < Arows + Width)
        {
            mvaddch(DrawX, Acols, HorizontalWallASCII);
            mvaddch(DrawX, Acols+Breadth, HorizontalWallASCII);
            DrawX = DrawX + 1;
        }

        DrawY = Acols;       

        while(DrawY < Y + Breadth)
        {
            mvaddch(Arows, DrawY, VerticalWallASCII);
            mvaddch(X+Width, DrawY, VerticalWallASCII);
            DrawY = DrawY + 1;
        }
   
        mvaddch(Arows, Acols, TopLeftCornerASCII);
        mvaddch(Arows+Width, Acols, TopRightCornerASCII);
        mvaddch(Arows+Width, Acols+Breadth, BotRightCornerASCII);
        mvaddch(Arows, Acols+Breadth, BotLeftCornerASCII);
        }       
        private:
      int X;
      int Y;  
      
};
And is the drawing function and main loop:

code:
//declare class objects
    AreaRoom    hub5;
    AreaRoom    hub6;
    Character   Player;


void draweverything()
{
     clear();
     //getmaxyx(stdscr,rows,cols);
     //hub5.ARstart(rows,cols);
     hub5.DrawArea(0,0);
     //hub5.DrawArea(5,26);
     hub6.DrawArea(5,25);
     mvaddch(7,25,FloorTileASCII);
     //hub5.DrawXwall();
     mvaddch(Player.Y,Player.X,PlayerSym);
     
};
     
    
    
    
    

int main(void)

{
    //init class objects
    Player.Init(5, 5, PlayerSym);
    
    //declare vars/ints
    
    initscr(); //init curses/pdcurses
    noecho();
    //nodelay(stdscr,TRUE);
    hub5.Init(0,0,10,25);
    hub6.Init(5,26,10,35);
   draweverything();
    
    //While loop
    while (1){
          //start output of player pos on screen
          //let's try to make this a function in the future so we cut down on code :P
          move(Player.Y,Player.X);
          addch(PlayerSym);
          refresh();
          
          // ok let's move dat player
          //get the keypress;
         // char nKey = getch();
         keypad(stdscr,TRUE);
         int keyh;
         keyh = getch();
     switch (keyh)    
    {
			// Move down
			case KEY_DOWN:
                 if (hub5.isWalkable(mvinch(Player.Y+1, Player.X)))
                {                    
				Player.Y++;
				Player.LastY--;
                }
				break;
	
			// Move left
			case KEY_LEFT:
                if (hub5.isWalkable(mvinch(Player.Y, Player.X-1)))
                {
				Player.X--;
				Player.LastX++;
                }
				break;

			// Move right
			case KEY_RIGHT:
                 if (hub5.isWalkable(mvinch(Player.Y, Player.X+1)))
                 {
				Player.X++;
				Player.LastX--;
                 }
				break;
	
			// Move up
			case KEY_UP:
                 if (hub5.isWalkable(mvinch(Player.Y-1, Player.X)))
                {     
				Player.Y--;
				Player.LastY++;
                }
				break;
    }
    draweverything();
}
          
          
          
    
    
    
    
    refresh();
    getch();
    
    endwin();
    
    return 0;
      
}
I can't figure out what is going wrong. I'm a newbie at this, so any help I could get would be appreciated.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Rsugar posted:

code:
      int Width;
      int Breadth;
I can't figure out what is going wrong. I'm a newbie at this, so any help I could get would be appreciated.

Well one thing: breadth means exactly the same thing as width. :colbert:

Foran
Apr 19, 2008

Garry's Mod is an Art

Avenging Dentist posted:

Well one thing: breadth means exactly the same thing as width. :colbert:

I know :I . I copied the drawing function from some random tutorial and then built on top of it.

Breadth should be replaced with height, sorry.

Edit: Fixed the problem. I forgot that when I was testing the first room for the first time, I didn't have the init function, and I was passing numbers to the Arows and Acols variables instead. I forgot to replace Arows and Acols with the init vars, and I did that and it worked. Though, now I have a different problem. The lower right corner of the second room does not get drawn...

Foran fucked around with this message at 20:17 on Jul 1, 2009

Zakalwe
May 12, 2002

Wanted For:
  • Terrorism
  • Kidnapping
  • Poor Taste
  • Unlawful Carnal Gopher Knowledge
Don't do this.

code:
    bool AreaRoom::isWalkable(char newASCIIChar)
{
    int tile = newASCIIChar;
   
    if (tile == FloorTileASCII ||
        tile == PlayerSym || tile == FloorTileASCII2)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Do this instead.

code:
inline bool AreaRoom::isWalkable(const char& newASCIIChar) const
{
     return (newASCIIChar == FloorTileASCII || newASCIIChar == PlayerSym || newASCIIChar == FloorTileASCII2);
}
Edit: Your Init() could probably be dumped. Instead write a constructor with an initializer list. The initilizer list is not really important here, but it's a good habit to get into.

Zakalwe fucked around with this message at 02:48 on Jul 2, 2009

opie
Nov 28, 2000
Check out my TFLC Excuse Log!
So here's another one I probably won't get an answer on, but I'm out of ideas. I have a multi-threaded dll written in unmanaged c++ that displays a simple dialog box with an activex control. When it tries to create the control, I get an assertion failed error on line 410 in occmgr.cpp, here is part of the code:
code:
COleControlSiteOrWnd *pTemp =
new COleControlSiteOrWnd(
::GetDlgItem(pWndParent->GetSafeHwnd(), pOccDlgInfo->m_pItemInfo[i].nId),
pOccDlgInfo->m_pItemInfo[i].bAutoRadioButton);

ASSERT(pTemp->m_hWnd); //Line 410
I'm using visual studio 2002 to compile, and might try 2003 to see if that helps. I've checked that the registry is correct and the ocx file is in the right place, and I have the correct mfc dll installed. I didn't see any other helpful tips in my research. I can't change it to single threaded, so that's out. Anyone else have any ideas?

Edit - looks like the dialog box works in another application, so it's an issue of it not finding the parent window for this one. That's what I thought the problem was until I researched it and there seemed to be several other causes.

opie fucked around with this message at 21:21 on Jul 2, 2009

raminasi
Jan 25, 2005

a last drink with no ice
I'm going to be starting a new project for which I have to use a library with C++ interfaces. It's targeted for Windows. Should I consider C++/CLI? I've read up some, but I don't know anything about it in practice. I've never done any .NET programming of any kind before, so this will be my first foray.

fankey
Aug 31, 2001

GrumpyDoctor posted:

I'm going to be starting a new project for which I have to use a library with C++ interfaces. It's targeted for Windows. Should I consider C++/CLI? I've read up some, but I don't know anything about it in practice. I've never done any .NET programming of any kind before, so this will be my first foray.
The only reason to use C++/CLI is to call C++ code from C#. So if you want to use C# to write your new project and you need to call into a C++ library, you'll need to wrap the C++ library with C++/CLI.

In theory you can write .NET apps directly in C++/CLI but I wouldn't recommend that. I'd either write a thin C++/CLI wrapper around the C++ DLL using .NET or write the app in C++ without .NET.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

The last time I looked at C++/CLI it was kind of a clusterfuck. If you're set on using .NET for the rest of the application, using a proper .NET language like C# with P/Invoke is the way I would go.

raminasi
Jan 25, 2005

a last drink with no ice
Thanks, those were exactly the kind of answers I was looking for. Guess I don't need to bother with it.

Foran
Apr 19, 2008

Garry's Mod is an Art

Zakalwe posted:

Don't do this.

Actually, while I was working on the thing yesterday, I re-wrote the entire map generation function, so that it loads a hard-coded map. Next up is parsing config files so that I can load up monsters/items/etc. After that I'm going to work on a larger map than what I have now that takes up more than the entire screen, and then work on a way to scroll through it.

Adhemar
Jan 21, 2004

Kellner, da ist ein scheussliches Biest in meiner Suppe.

Rsugar posted:

code:
    ...
    //While loop
    while (1){
    ...  
    }

A while loop you say? I never would have guessed.

baquerd
Jul 2, 2007

by FactsAreUseless

Adhemar posted:

A while loop you say? I never would have guessed.

He forgot the "//end while" at the end though, makes it a bit confusing.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Adhemar posted:

A while loop you say? I never would have guessed.
I find "#define FOREVER while(1)" makes commenting the loop unnecessary! :downs:

(I've seen this in code more times than I really should)

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
Blame K&R.

Foran
Apr 19, 2008

Garry's Mod is an Art

Adhemar posted:

A while loop you say? I never would have guessed.

What, you don't use pseudo-code and forget to erase it every so often?

baquerd
Jul 2, 2007

by FactsAreUseless

Rsugar posted:

What, you don't use pseudo-code and forget to erase it every so often?

code:
//while loop
////if statement
//////if true
////else statement
//////not true
////end if statement
//end while loop
Oh baby

Adhemar
Jan 21, 2004

Kellner, da ist ein scheussliches Biest in meiner Suppe.

Rsugar posted:

What, you don't use pseudo-code and forget to erase it every so often?

No, I write real code from the start. :smug:

HauntedRobot
Jun 22, 2002

an excellent mod
a simple map to my heart
now give me tilt shift
I write all my code like that ^^ starting with just the control structures, no details. Just to see what it ends up being. Like writing a song and deciding "verse, verse, chorus, verse, chorus, chorus"

Vinterstum
Jul 30, 2003

HauntedRobot posted:

I write all my code like that ^^ starting with just the control structures, no details. Just to see what it ends up being. Like writing a song and deciding "verse, verse, chorus, verse, chorus, chorus"

This is a whole new level of waterfall.

Bhaal
Jul 13, 2001
I ain't going down alone
Dr. Infant, MD

Dijkstracula posted:

I find "#define FOREVER while(1)" makes commenting the loop unnecessary! :downs:

(I've seen this in code more times than I really should)
http://doc.trolltech.com/4.5/qtglobal.html#forever

(Though their foreach is useful I'll admit)

The Red Baron
Jan 10, 2005

Since C++0x will (eventually) come with user-defined literals that allow you to convert a constexpr input string into a variadic template argument list, I figured I'd try to create something that lets you actually do something with it. So for the last few days I've been working on a highly experimental prototype of a Boost.Spirit2-inspired attribute-based, recursive descent parser.. with the parsing all being done at compile time!

Example:
code:
// Compile-time parser for pseudo-EBNF '{' int (space char)* '}'
typedef seq<
    ch<'{'>
  , int_
  , kleene< 
      seq<space, char_>
    >
  , ch<'}'>
> grammar;

// No compilers support user-defined literals yet, so use MPL.String
// Here corresponding to the string "{32 A B C}"
typedef mpl::string<'{32 ','A B ','C}'> teststr;

// Create compile-time parser. Skip-parsers also supported as a 4th argument
typedef phrase_parse<mpl::begin<teststr>::type, mpl::end<teststr>::type, grammar> testparse;
Since it's attribute-based, the end result depends on the associated attributes of the (sub)parsers (e.g. int_ -> mpl::int_, space -> no attribute etc.) and the way they are composed.
In this case, we have testparse::type -> mpl::vector<mpl::int_<32>, mpl::char_<'A'>, mpl::char_<'B'>, mpl::char_<'C'>>

So far I haven't done any benchmarking, but I kinda expect compilers to begin melting down with more complex grammars or longer input strings. For what it's worth, the above example compiles in only a couple of seconds on VC++2008. I'll probably write something up about this soon and maybe send off an RFC to the boost list at some point.

Comments? To be honest, I wasn't sure whether to post this here or in the coding horrors thread :toot:

User0015
Nov 24, 2007

Please don't talk about your sexuality unless it serves the ~narrative~!
I'm writing a small program in C/C++ and had a question regarding a compiler error.

I wanted to create a separate file that handled the task of setting up parameters, flags, definitions and variables for my program, as well as performing one-time tasks. I wrote a .cpp file and included the Setup() method call, and then simply called it in main. The error reports: "multiple definition of Setup()", "main.cpp: first defined here."

I simply changed the entire function to an inline function to avoid the error, which works. However, is this a proper way to handle things? It feels like there should be a better or more common way of doing this without having to inline a rather large function, especially since it feels like I'm avoiding the compiler when it's trying to warn me. Of course, it's only ran once during the programs lifetime, and it's not HUGE, so I'm not worried about performance impact, but it still feels like a rather poor method of getting it to work. Is there a better/smarter/easier way of doing this?

ehnus
Apr 16, 2003

Now you're thinking with portals!
That's a linker error which is caused, well, by the function being defined more than once. Don't put the function definition in a file you #include from others unless you want to inline it but rather put its definition in its own translation unit and include its declaration/prototype from all the files that need to call it.

User0015
Nov 24, 2007

Please don't talk about your sexuality unless it serves the ~narrative~!
It's good to know that some days I'm an idiot. This problem was bothering me because it seemed simple enough, but I thought I was missing something. What I was missing was coffee. Problem resolved.

newsomnuke
Feb 25, 2007

If I've got this:

code:
template <class T>
class Foo
{
public:
	static const int Bar = 10;
};
Is it possible to access Bar from outside the class without specifying a type for Foo?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
No because Foo isn't a class.

newsomnuke
Feb 25, 2007

I thought that considering Bar will be the same for whatever type Foo is instantiated with that an exception might have been made for it or something.

Adbot
ADBOT LOVES YOU

chips
Dec 25, 2004
Mein Führer! I can walk!
You'd start to get inconsistant behaviour (or atleast inconsistant with the behaviour of C++ template class specializations as being different classes) if two different specializations of Foo both try to use Bar separately.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply