Game Development Community

Script - Shell to .exe and return?

by Mark Brown · in Torque Game Engine · 10/26/2006 (6:58 am) · 18 replies

Is there a way to shell to a program called maze_maker.exe and then return to the script? Maze_maker.exe creates a file called maze.mis. The size of the maze (3x3x3, 4x4x4,...7x7x7), is based on the players choice from a .gui screen, and the size argument could passed to maze_maker.exe or output to a file that can be read by maze_maker.exe.

#1
10/26/2006 (7:23 am)
Just place the .mis file in your game directory?
#2
10/27/2006 (1:43 pm)
I can't create the maze.mis ( which is created by maze_maker.exe ) until the player selects a size from the .gui screen.
#3
10/27/2006 (1:56 pm)
Some solutions:
- create a batch file that creates a number of maze sizes (5 of each for example), copies them to game directory, and then runs the game. Player then selects maze size from gui.

- create the maze in script (there's a resource for creating mazes, IIRC)
#4
10/27/2006 (4:35 pm)
So basicly your saying there is no way to shell out to an .exe and return in a .cs script.
#5
10/27/2006 (4:47 pm)
No existing method as far as I know.
#6
10/28/2006 (12:46 pm)
First, the caveats:
1) This is a bad way to do whatever it is you want to do.
2) This blocks. And that's a Good Thing(TM), but it will do even less of what you want it to do. The only way to make it not block would leave you with a nondeterministic "the map may have been produced, or it may not, or it may be produced soon" situation
3) System() sucks. It's a terrible command to use, ever, but I don't know how to do windows popen /et al/
4) You're presumably using windows since you want a .exe. I don't have a windows reference for system() here, so I'm assuming it's the same as the C90 version.

#include <stdlib.h>

ConsoleFunction( system, S32, 3, 3, "(\"program [args]\") Shell out to an external program")
{
   argc;argv;
   return system(argv[2]);
}

Gary (-;

PS Really, convert your mapmaking code to .cs, or write it in C/C++ and add it to your main torque codebase. Using an external .exe is asking for trouble in so many ways.
#7
10/29/2006 (4:53 am)
Thanks Gary. I have come to the same conclusions as you set forth above.
The .exe file is a compiled perl script file. It is massive and would be a bitch to convert to c++ of .cs but it will have to be done, when it is finally shaken down. For now, I call it first and then launch Torque.
#8
10/30/2006 (12:32 pm)
Quote:It is massive and would be a bitch to convert to c++ of .cs but it will have to be done, when it is finally shaken down. For now, I call it first and then launch Torque.

At a guess, I'd say that the mapmaking code is a very minor subset of your overall code. Rewriting it would take a smaller amount of time than messing about and getting the external program working, and would take a miniscule amount of time compared to writing the rest of your game.

Seriously, shelling out to other executables sucks. And you're probably better off rewriting it without using perl anyways?

Gary (-;
#9
10/30/2006 (12:42 pm)
Yeah. There have been a million "map making" or "random map" algorithms and snippets of source out for decades now. Look at the routines used for the generation and figure out how to do it with your geometry.
#10
10/30/2006 (7:24 pm)
I have started down the "long road" of coverting to Torque script.
As a clue to what lies ahead, we are talking about converting a 113k, 5,337 lines of perl script.

This code pulls from a library of over 300 rotatable rooms ( and growing daily ).
If a room can not be found, then it is created from a large library of spair parts, floors ceilings doorways stairs ...

The code is four months bullet proof!!!

Oh well ... off to work.
#11
10/30/2006 (7:52 pm)
Quote:5,337 lines of perl script.

Well, that's pretty much just replaced my worst ever nightmare of someone repeatedly closing a hot waffle iron over my... hand.

Gary (-;
#12
11/02/2006 (1:57 pm)
The translation from perl to torque script is going more smoothly than I expected.
Examples:
"index" convert directly to "strstr"
"eq" to "$=" for string compare

Here is a random integer maker ( with tests ):
//####################
//#
//# If argument == N then return random int between 1 and N
//#
//####################
function random_int ( %many )
{

%ja = %many;
%many = mFloor ( %many );
if ( %many != %ja )
echo ( "** Function random_int: Submit was not integer: " @ %ja );


if ( %many < 1 )
{
echo ( "** Function random_int: Submit was less than one: " @ %many SPC "Reset to one!" );
%many = 1;
}

if ( %many == 1 )
return ( 1 );

%rando = getRandom ( %many );
if ( %rando < 1 )
{
%rando = 1;
}

if ( %rando > %many )
{
%rando = %many;
}
return ( %rando );
}

I may be over protective but it keeps me out of many troubles!
#13
11/02/2006 (2:06 pm)
Wow, that's a lot of heartache to call getRandom, which does most of that stuff for you...

ConsoleFunction(getRandom, F32, 1, 3, "(int a=1, int b=0)"
                "Get a random number between a and b.")
{
   if (argc == 2)
      return F32(gRandGen.randI(0,dAtoi(argv[1])));
   else
   {
      if (argc == 3) {
         S32 min = dAtoi(argv[1]);
         S32 max = dAtoi(argv[2]);
         if (min > max) {
            S32 t = min;
            min = max;
            max = t;
         }
         return F32(gRandGen.randI(min,max));
      }
   }
   return gRandGen.randF();
}

In other words, does the same as you want, if you just call getRandom() with your %many argument.

Gary (-;
#14
11/03/2006 (3:07 pm)
Heartache is 3 hours of tracking down "someone" calling:
%rando = getRandom ( -1 );

%rando = getRandom ( "" );

%rando = getRandom ( "Happy" );

%rando = getRandom ( 13.563224 );
#15
11/13/2006 (3:24 pm)
I finished the conversion and all is working well. The above random_int ( ) function helped track down a coding error of a call with an argument of ( 0 ). I coded a local "%" where a "$" was called for. I placed an echo before each call to random_int and tracked it down quickly. I would not even have know the nature of the problem without the "Function random_int: Submit was less than one" echo. Still shaking it down, but it looks solid so far! I had used a number of GOTO which had to be converted to WHILE. It was nice to have the SWITCH statement back.
#16
11/13/2006 (3:45 pm)
Quote:GOTO

ew

Congratulations on getting everything working, though :-)

Gary (-;

PS I hate the torque switch/case arrangement because it doesn't fall through, taking away the one real benefit of it over if/elseif/elseif/end operators :-(
#17
11/29/2006 (11:21 am)
Is there a way to call the EXE without blocking? I am thinking to use this to call a C# web services client as I can not find anyone to add a web services client to the C++ source code. I would need the response from the web service call for use in TorqueScript.
#18
11/29/2006 (11:49 am)
Quote: Is there a way to call the EXE without blocking?

First, your disclaimers:
1) Shelling out to executables still sucks.
2) Nonblocking means you don't know when data is returned without an appropriate eventual callback
3) Basically, if you don't block, then there's no good way to write your UI, unless what you want is a progress bar or something.

So some answers:
1) Don't you want an HTTPObject or a TCPObject? Why shell out to an executable when all you want is a TCP Stream?
2) tdn.garagegames.com/wiki/Torque/RSSTicker
3) If what you still really desire is a nonblocking way to shell out to an executable and find out something useful when it returns, reference this page and write a run function that calls Con::execute with useful answers once it has them.

Gary (-;