mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
command-line arguments
This commit is contained in:
parent
8f96fa71f5
commit
1dda2cfb99
@ -82,6 +82,25 @@ set_tokens(const P3D_token tokens[], size_t num_tokens) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DFileParams::set_args
|
||||
// Access: Public
|
||||
// Description: Specifies the command-line arguments associated with
|
||||
// the instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DFileParams::
|
||||
set_args(int argc, const char *argv[]) {
|
||||
_args.clear();
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
const char *arg = argv[i];
|
||||
if (arg == NULL) {
|
||||
arg = "";
|
||||
}
|
||||
_args.push_back(arg);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DFileParams::lookup_token
|
||||
// Access: Public
|
||||
@ -136,10 +155,17 @@ make_xml() {
|
||||
for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) {
|
||||
const Token &token = (*ti);
|
||||
TiXmlElement *xtoken = new TiXmlElement("token");
|
||||
xtoken->SetAttribute("keyword", token._keyword.c_str());
|
||||
xtoken->SetAttribute("value", token._value.c_str());
|
||||
xtoken->SetAttribute("keyword", token._keyword);
|
||||
xtoken->SetAttribute("value", token._value);
|
||||
xfparams->LinkEndChild(xtoken);
|
||||
}
|
||||
|
||||
Args::const_iterator ai;
|
||||
for (ai = _args.begin(); ai != _args.end(); ++ai) {
|
||||
TiXmlElement *xarg = new TiXmlElement("arg");
|
||||
xarg->SetAttribute("value", (*ai));
|
||||
xfparams->LinkEndChild(xarg);
|
||||
}
|
||||
|
||||
return xfparams;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
|
||||
void set_p3d_filename(const string &p3d_filename);
|
||||
void set_tokens(const P3D_token tokens[], size_t num_tokens);
|
||||
void set_args(int argc, const char *argv[]);
|
||||
|
||||
inline const string &get_p3d_filename() const;
|
||||
string lookup_token(const string &keyword) const;
|
||||
@ -46,9 +47,11 @@ private:
|
||||
string _value;
|
||||
};
|
||||
typedef vector<Token> Tokens;
|
||||
typedef vector<string> Args;
|
||||
|
||||
string _p3d_filename;
|
||||
Tokens _tokens;
|
||||
Args _args;
|
||||
};
|
||||
|
||||
#include "p3dFileParams.I"
|
||||
|
@ -51,7 +51,8 @@ typedef P3DSplashWindow SplashWindowType;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3DInstance::
|
||||
P3DInstance(P3D_request_ready_func *func,
|
||||
const P3D_token tokens[], size_t num_tokens, void *user_data) :
|
||||
const P3D_token tokens[], size_t num_tokens,
|
||||
int argc, const char *argv[], void *user_data) :
|
||||
_func(func)
|
||||
{
|
||||
_browser_script_object = NULL;
|
||||
|
@ -49,7 +49,8 @@ class P3DToplevelObject;
|
||||
class P3DInstance : public P3D_instance, public P3DReferenceCount {
|
||||
public:
|
||||
P3DInstance(P3D_request_ready_func *func,
|
||||
const P3D_token tokens[], size_t num_tokens, void *user_data);
|
||||
const P3D_token tokens[], size_t num_tokens,
|
||||
int argc, const char *argv[], void *user_data);
|
||||
~P3DInstance();
|
||||
|
||||
void set_p3d_url(const string &p3d_url);
|
||||
|
@ -207,8 +207,9 @@ read_contents_file(const string &contents_filename) {
|
||||
P3DInstance *P3DInstanceManager::
|
||||
create_instance(P3D_request_ready_func *func,
|
||||
const P3D_token tokens[], size_t num_tokens,
|
||||
void *user_data) {
|
||||
P3DInstance *inst = new P3DInstance(func, tokens, num_tokens, user_data);
|
||||
int argc, const char *argv[], void *user_data) {
|
||||
P3DInstance *inst = new P3DInstance(func, tokens, num_tokens, argc, argv,
|
||||
user_data);
|
||||
inst->ref();
|
||||
_instances.insert(inst);
|
||||
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
P3DInstance *
|
||||
create_instance(P3D_request_ready_func *func,
|
||||
const P3D_token tokens[], size_t num_tokens,
|
||||
void *user_data);
|
||||
int argc, const char *argv[], void *user_data);
|
||||
|
||||
bool set_p3d_filename(P3DInstance *inst, bool is_local,
|
||||
const string &p3d_filename);
|
||||
|
@ -942,7 +942,6 @@ set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams) {
|
||||
}
|
||||
|
||||
PyObject *token_list = PyList_New(0);
|
||||
|
||||
TiXmlElement *xtoken = xfparams->FirstChildElement("token");
|
||||
while (xtoken != NULL) {
|
||||
string keyword, value;
|
||||
@ -963,11 +962,28 @@ set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams) {
|
||||
|
||||
xtoken = xtoken->NextSiblingElement("token");
|
||||
}
|
||||
|
||||
PyObject *arg_list = PyList_New(0);
|
||||
TiXmlElement *xarg = xfparams->FirstChildElement("arg");
|
||||
while (xarg != NULL) {
|
||||
string value;
|
||||
const char *value_c = xarg->Attribute("value");
|
||||
if (value_c != NULL) {
|
||||
value = value_c;
|
||||
}
|
||||
|
||||
PyObject *str = Py_BuildValue("s", value.c_str());
|
||||
PyList_Append(arg_list, str);
|
||||
Py_DECREF(str);
|
||||
|
||||
xarg = xarg->NextSiblingElement("arg");
|
||||
}
|
||||
|
||||
PyObject *result = PyObject_CallMethod
|
||||
(_runner, (char *)"setP3DFilename", (char *)"sOi", p3d_filename.c_str(),
|
||||
token_list, inst->get_instance_id());
|
||||
(_runner, (char *)"setP3DFilename", (char *)"sOOi", p3d_filename.c_str(),
|
||||
token_list, arg_list, inst->get_instance_id());
|
||||
Py_DECREF(token_list);
|
||||
Py_DECREF(arg_list);
|
||||
|
||||
if (result == NULL) {
|
||||
PyErr_Print();
|
||||
|
@ -105,12 +105,13 @@ P3D_finalize() {
|
||||
P3D_instance *
|
||||
P3D_new_instance(P3D_request_ready_func *func,
|
||||
const P3D_token tokens[], size_t num_tokens,
|
||||
void *user_data) {
|
||||
int argc, const char *argv[], void *user_data) {
|
||||
nout << "new_instance\n";
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
P3DInstance *result = inst_mgr->create_instance(func, tokens, num_tokens, user_data);
|
||||
P3DInstance *result = inst_mgr->create_instance(func, tokens, num_tokens,
|
||||
argc, argv, user_data);
|
||||
RELEASE_LOCK(_api_lock);
|
||||
return result;
|
||||
}
|
||||
|
@ -224,6 +224,14 @@ typedef struct {
|
||||
passed to the application, who is free to decide how to interpret
|
||||
them; they have no meaning at the system level.
|
||||
|
||||
The argc/argv parameters are intended for when the plugin is
|
||||
invoked from the command line; they should be filled a standard
|
||||
C-style argc/argv parameter list, corresponding to the command-line
|
||||
parameters passed to the application. They may be 0 and NULL when
|
||||
the plugin is invoked from the web. As above, this array and its
|
||||
string data will be copied into the core API's own internal
|
||||
storage, and need not persist after this call.
|
||||
|
||||
The user_data pointer is any arbitrary pointer value; it will be
|
||||
copied into the _user_data member of the new P3D_instance object.
|
||||
This pointer is intended for the host to use to store private data
|
||||
@ -234,6 +242,7 @@ typedef struct {
|
||||
typedef P3D_instance *
|
||||
P3D_new_instance_func(P3D_request_ready_func *func,
|
||||
const P3D_token tokens[], size_t num_tokens,
|
||||
int argc, const char *argv[],
|
||||
void *user_data);
|
||||
|
||||
/* This function should be called at some point after
|
||||
|
@ -957,7 +957,8 @@ create_instance() {
|
||||
if (!_tokens.empty()) {
|
||||
tokens = &_tokens[0];
|
||||
}
|
||||
_p3d_inst = P3D_new_instance(request_ready, tokens, _tokens.size(), this);
|
||||
_p3d_inst = P3D_new_instance(request_ready, tokens, _tokens.size(),
|
||||
0, NULL, this);
|
||||
|
||||
if (_p3d_inst != NULL) {
|
||||
// Now get the browser's window object, to pass to the plugin.
|
||||
|
@ -609,30 +609,35 @@ make_parent_window(P3D_window_handle &parent_window,
|
||||
// play a particular .p3d file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_instance *Panda3D::
|
||||
create_instance(const string &arg, P3D_window_type window_type,
|
||||
create_instance(const string &p3d, P3D_window_type window_type,
|
||||
int win_x, int win_y, int win_width, int win_height,
|
||||
P3D_window_handle parent_window, char **args, int num_args) {
|
||||
P3D_token tokens[] = {
|
||||
{ "src", arg.c_str() },
|
||||
};
|
||||
int num_tokens = sizeof(tokens) / sizeof(P3D_token);
|
||||
|
||||
// If the supplied parameter name is a real file, pass it in on the
|
||||
// parameter list. Otherwise, assume it's a URL and let the plugin
|
||||
// download it.
|
||||
Filename p3d_filename = Filename::from_os_specific(arg);
|
||||
string os_p3d_filename;
|
||||
Filename p3d_filename = Filename::from_os_specific(p3d);
|
||||
string os_p3d_filename = p3d;
|
||||
bool is_local = false;
|
||||
if (p3d_filename.exists()) {
|
||||
p3d_filename.make_absolute();
|
||||
os_p3d_filename = p3d_filename.to_os_specific();
|
||||
is_local = true;
|
||||
}
|
||||
|
||||
P3D_instance *inst = P3D_new_instance(NULL, tokens, num_tokens, NULL);
|
||||
// Build up the argument list, beginning with the p3d_filename.
|
||||
pvector<const char *> argv;
|
||||
argv.push_back(os_p3d_filename.c_str());
|
||||
for (int i = 0; i < num_args; ++i) {
|
||||
argv.push_back(args[i]);
|
||||
}
|
||||
|
||||
P3D_instance *inst = P3D_new_instance(NULL, NULL, 0,
|
||||
argv.size(), &argv[0], NULL);
|
||||
|
||||
if (inst != NULL) {
|
||||
P3D_instance_setup_window
|
||||
(inst, window_type, win_x, win_y, win_width, win_height, parent_window);
|
||||
P3D_instance_start(inst, true, os_p3d_filename.c_str());
|
||||
P3D_instance_start(inst, is_local, os_p3d_filename.c_str());
|
||||
}
|
||||
|
||||
return inst;
|
||||
|
@ -55,11 +55,11 @@ private:
|
||||
void make_parent_window(P3D_window_handle &parent_window,
|
||||
int win_width, int win_height);
|
||||
|
||||
P3D_instance *create_instance(const string &arg, P3D_window_type window_type,
|
||||
int win_x, int win_y, int win_width,
|
||||
int win_height,
|
||||
P3D_window_handle parent_window,
|
||||
char **args, int num_args);
|
||||
P3D_instance *
|
||||
create_instance(const string &p3d, P3D_window_type window_type,
|
||||
int win_x, int win_y, int win_width, int win_height,
|
||||
P3D_window_handle parent_window,
|
||||
char **args, int num_args);
|
||||
void delete_instance(P3D_instance *instance);
|
||||
|
||||
void usage();
|
||||
|
@ -371,6 +371,9 @@ class Freezer:
|
||||
self.moduleName = moduleName
|
||||
self.filename = filename
|
||||
|
||||
def __repr__(self):
|
||||
return 'ModuleDef(%s, %s, %s)' % (repr(self.token), repr(self.moduleName), repr(self.filename))
|
||||
|
||||
def __init__(self, previous = None, debugLevel = 0):
|
||||
# Normally, we are freezing for our own platform. Change this
|
||||
# if untrue.
|
||||
@ -646,7 +649,6 @@ class Freezer:
|
||||
parentName, baseName = newName.rsplit('.', 1)
|
||||
if parentName in excludeDict:
|
||||
token = excludeDict[parentName]
|
||||
|
||||
if token == self.MTInclude:
|
||||
includes.append(mdef)
|
||||
elif token == self.MTAuto or token == self.MTGuess:
|
||||
@ -772,10 +774,12 @@ class Freezer:
|
||||
# Previously exported.
|
||||
pass
|
||||
else:
|
||||
if newName in self.mf.modules or \
|
||||
newName in startupModules or \
|
||||
if mdef.moduleName in self.mf.modules or \
|
||||
mdef.moduleName in startupModules or \
|
||||
mdef.filename:
|
||||
moduleDefs.append((newName, mdef))
|
||||
else:
|
||||
print "Unknown module %s" % (mdef.moduleName)
|
||||
elif token == self.MTForbid:
|
||||
if not prev or prev.token != self.MTForbid:
|
||||
moduleDefs.append((newName, mdef))
|
||||
|
@ -194,8 +194,9 @@ class Packager:
|
||||
message = 'No main_module specified for application %s' % (self.packageName)
|
||||
raise PackagerError, message
|
||||
if self.mainModule:
|
||||
if self.mainModule not in self.freezer.modules:
|
||||
self.freezer.addModule(self.mainModule)
|
||||
moduleName, newName = self.mainModule
|
||||
if newName not in self.freezer.modules:
|
||||
self.freezer.addModule(moduleName, newName = newName)
|
||||
|
||||
# Pick up any unfrozen Python files.
|
||||
self.freezer.done()
|
||||
@ -601,7 +602,7 @@ class Packager:
|
||||
if self.version:
|
||||
xpackage.SetAttribute('version', self.version)
|
||||
|
||||
xpackage.SetAttribute('main_module', self.mainModule)
|
||||
xpackage.SetAttribute('main_module', self.mainModule[1])
|
||||
|
||||
for variable, value in self.configs.items():
|
||||
if isinstance(value, types.UnicodeType):
|
||||
@ -1463,15 +1464,19 @@ class Packager:
|
||||
|
||||
def parse_main_module(self, words):
|
||||
"""
|
||||
main_module moduleName
|
||||
main_module moduleName [newName]
|
||||
"""
|
||||
newName = None
|
||||
|
||||
try:
|
||||
command, moduleName = words
|
||||
if len(words) == 2:
|
||||
command, moduleName = words
|
||||
else:
|
||||
command, moduleName, newName = words
|
||||
except ValueError:
|
||||
raise ArgumentError
|
||||
|
||||
self.mainModule(moduleName)
|
||||
self.mainModule(moduleName, newName = newName)
|
||||
|
||||
def parse_freeze_exe(self, words):
|
||||
"""
|
||||
@ -1879,11 +1884,13 @@ class Packager:
|
||||
if not self.currentPackage:
|
||||
raise OutsideOfPackageError
|
||||
|
||||
if self.currentPackage.mainModule and self.currentPackage.mainModule != moduleName:
|
||||
if self.currentPackage.mainModule and self.currentPackage.mainModule[0] != moduleName:
|
||||
self.notify.warning("Replacing main_module %s with %s" % (
|
||||
self.currentPackage.mainModule, moduleName))
|
||||
self.currentPackage.mainModule[0], moduleName))
|
||||
|
||||
self.currentPackage.mainModule = moduleName
|
||||
if not newName:
|
||||
newName = moduleName
|
||||
self.currentPackage.mainModule = (moduleName, newName)
|
||||
|
||||
def freeze(self, filename, compileToExe = False):
|
||||
""" Freezes all of the current Python code into either an
|
||||
@ -1906,10 +1913,17 @@ class Packager:
|
||||
raise PackagerError, message
|
||||
|
||||
if package.mainModule:
|
||||
if package.mainModule not in freezer.modules:
|
||||
freezer.addModule(package.mainModule, newName = '__main__')
|
||||
moduleName, newName = package.mainModule
|
||||
if compileToExe:
|
||||
# If we're producing an exe, the main module must
|
||||
# be called "__main__".
|
||||
newName = '__main__'
|
||||
package.mainModule = (moduleName, newName)
|
||||
|
||||
if newName not in freezer.modules:
|
||||
freezer.addModule(moduleName, newName = newName)
|
||||
else:
|
||||
freezer.modules['__main__'] = freezer.modules[package.mainModule]
|
||||
freezer.modules[newName] = freezer.modules[moduleName]
|
||||
freezer.done(compileToExe = compileToExe)
|
||||
|
||||
if not package.dryRun:
|
||||
|
@ -128,6 +128,12 @@ def makePackedApp(args):
|
||||
|
||||
packager.endPackage(appBase, p3dApplication = True)
|
||||
|
||||
def main(appRunner):
|
||||
""" This function is called when this module is invoked as
|
||||
packp3d.p3d. """
|
||||
|
||||
makePackedApp(appRunner.argv[1:])
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
makePackedApp(sys.argv[1:])
|
||||
|
@ -223,12 +223,12 @@ class AppRunner(DirectObject):
|
||||
v = VFSImporter.VFSImporter(MultifileRoot)
|
||||
loader = v.find_module(moduleName)
|
||||
if not loader:
|
||||
message = "No %s.py found in application." % (mainName)
|
||||
message = "No %s found in application." % (moduleName)
|
||||
raise StandardError, message
|
||||
|
||||
main = loader.load_module(moduleName)
|
||||
if hasattr(main, 'main') and callable(main.main):
|
||||
main.main()
|
||||
main.main(self)
|
||||
|
||||
def getPandaScriptObject(self):
|
||||
""" Called by the browser to query the Panda instance's
|
||||
@ -251,7 +251,7 @@ class AppRunner(DirectObject):
|
||||
needsResponse = False)
|
||||
self.deferredEvals = []
|
||||
|
||||
def setP3DFilename(self, p3dFilename, tokens = [],
|
||||
def setP3DFilename(self, p3dFilename, tokens = [], argv = [],
|
||||
instanceId = None):
|
||||
# One day we will have support for multiple instances within a
|
||||
# Python session. Against that day, we save the instance ID
|
||||
@ -260,6 +260,7 @@ class AppRunner(DirectObject):
|
||||
|
||||
self.tokens = tokens
|
||||
self.tokenDict = dict(tokens)
|
||||
self.argv = argv
|
||||
|
||||
# Tell the browser that Python is up and running, and ready to
|
||||
# respond to queries.
|
||||
|
Loading…
x
Reference in New Issue
Block a user