mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
p3dpython can be a Panda app
This commit is contained in:
parent
506154a6b6
commit
b660d0f3e5
@ -1,6 +1,6 @@
|
||||
// This directory is still experimental. Define HAVE_P3D_PLUGIN in
|
||||
// your Config.pp to build it.
|
||||
#define BUILD_DIRECTORY $[HAVE_P3D_PLUGIN]
|
||||
#define BUILD_DIRECTORY $[and $[HAVE_P3D_PLUGIN],$[HAVE_PYTHON],$[HAVE_TINYXML]]
|
||||
|
||||
#begin lib_target
|
||||
#define USE_PACKAGES tinyxml
|
||||
@ -30,13 +30,20 @@
|
||||
#end lib_target
|
||||
|
||||
#begin bin_target
|
||||
#define USE_PACKAGES tinyxml
|
||||
#define USE_PACKAGES tinyxml python
|
||||
#define TARGET p3dpython
|
||||
|
||||
#define OTHER_LIBS \
|
||||
dtoolutil:c dtoolbase:c dtool:m \
|
||||
interrogatedb:c dconfig:c dtoolconfig:m \
|
||||
express:c pandaexpress:m \
|
||||
prc:c pstatclient:c pandabase:c linmath:c putil:c \
|
||||
pipeline:c panda:m
|
||||
|
||||
#define SOURCES \
|
||||
handleStream.cxx handleStream.h handleStream.I \
|
||||
handleStreamBuf.cxx handleStreamBuf.h \
|
||||
p3d_lock.h \
|
||||
p3d_lock.h p3d_plugin.h \
|
||||
p3dCInstance.cxx \
|
||||
p3dCInstance.h p3dCInstance.I \
|
||||
p3dPythonRun.cxx p3dPythonRun.h p3dPythonRun.I
|
||||
|
@ -15,9 +15,11 @@
|
||||
#ifndef P3DCINSTANCE_H
|
||||
#define P3DCINSTANCE_H
|
||||
|
||||
#include "p3d_plugin.h"
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "p3d_plugin.h"
|
||||
#include "pvector.h"
|
||||
|
||||
#include <vector>
|
||||
#include <tinyxml.h>
|
||||
|
||||
class P3DSession;
|
||||
@ -41,7 +43,7 @@ private:
|
||||
string _keyword;
|
||||
string _value;
|
||||
};
|
||||
typedef vector<Token> Tokens;
|
||||
typedef pvector<Token> Tokens;
|
||||
|
||||
P3D_request_ready_func *_func;
|
||||
string _p3d_filename;
|
||||
|
@ -13,6 +13,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "p3dPythonRun.h"
|
||||
#include "asyncTaskManager.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPythonRun::Constructor
|
||||
@ -114,41 +115,10 @@ run_python() {
|
||||
}
|
||||
Py_DECREF(appmf);
|
||||
|
||||
// Construct a Python wrapper around our check_comm() method.
|
||||
|
||||
static PyMethodDef p3dpython_methods[] = {
|
||||
{"check_comm", P3DPythonRun::py_check_comm, METH_VARARGS,
|
||||
"Check for communications to and from the plugin host."},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
PyObject *p3dpython = Py_InitModule("p3dpython", p3dpython_methods);
|
||||
if (p3dpython == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
}
|
||||
|
||||
PyObject *check_comm = PyObject_GetAttrString(p3dpython, "check_comm");
|
||||
if (check_comm == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now add check_comm() as a Python task.
|
||||
PyObject *add_check_comm = PyObject_GetAttrString(appmf, "add_check_comm");
|
||||
if (add_check_comm == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
}
|
||||
|
||||
PyObject *task = PyObject_CallFunction
|
||||
(add_check_comm, "Ol", check_comm, (long)this);
|
||||
if (task == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
}
|
||||
Py_DECREF(task);
|
||||
Py_DECREF(add_check_comm);
|
||||
Py_DECREF(check_comm);
|
||||
// Now add check_comm() as a task.
|
||||
_check_comm_task = new GenericAsyncTask("check_comm", st_check_comm, this);
|
||||
AsyncTaskManager *task_mgr = AsyncTaskManager::get_global_ptr();
|
||||
task_mgr->add(_check_comm_task);
|
||||
|
||||
// Finally, get lost in taskMgr.run().
|
||||
|
||||
@ -212,8 +182,8 @@ handle_command(TiXmlDocument *doc) {
|
||||
// from, and requests to be delivered to, the plugin
|
||||
// host in the parent process.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DPythonRun::
|
||||
check_comm() {
|
||||
AsyncTask::DoneStatus P3DPythonRun::
|
||||
check_comm(GenericAsyncTask *task) {
|
||||
ACQUIRE_LOCK(_commands_lock);
|
||||
while (!_commands.empty()) {
|
||||
TiXmlDocument *doc = _commands.front();
|
||||
@ -232,27 +202,21 @@ check_comm() {
|
||||
}
|
||||
|
||||
RELEASE_LOCK(_commands_lock);
|
||||
|
||||
return AsyncTask::DS_cont;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPythonRun::py_check_comm
|
||||
// Function: P3DPythonRun::st_check_comm
|
||||
// Access: Private, Static
|
||||
// Description: This method is added as a Python task function on the
|
||||
// task manager. It is the Python wrapper around the
|
||||
// check_comm method.
|
||||
// Description: This static function wrapper around check_comm is
|
||||
// necessary to add the method function to the
|
||||
// GenericAsyncTask object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *P3DPythonRun::
|
||||
py_check_comm(PyObject *, PyObject *args) {
|
||||
long this_int;
|
||||
PyObject *task;
|
||||
if (!PyArg_ParseTuple(args, "lO:check_comm", &this_int, &task)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
P3DPythonRun *self = (P3DPythonRun *)(void *)this_int;
|
||||
self->check_comm();
|
||||
|
||||
return PyObject_GetAttrString(task, "cont");
|
||||
AsyncTask::DoneStatus P3DPythonRun::
|
||||
st_check_comm(GenericAsyncTask *task, void *user_data) {
|
||||
P3DPythonRun *self = (P3DPythonRun *)user_data;
|
||||
return self->check_comm(task);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -266,6 +230,12 @@ void P3DPythonRun::
|
||||
spawn_read_thread() {
|
||||
assert(!_read_thread_continue);
|
||||
|
||||
// We have to use direct OS calls to create the thread instead of
|
||||
// Panda constructs, because it has to be an actual thread, not
|
||||
// necessarily a Panda thread (we can't use Panda's simple threads
|
||||
// implementation, because we can't get overlapped I/O on an
|
||||
// anonymous pipe in Windows).
|
||||
|
||||
_read_thread_continue = true;
|
||||
#ifdef _WIN32
|
||||
_read_thread = CreateThread(NULL, 0, &win_rt_thread_run, this, 0, NULL);
|
||||
@ -356,8 +326,8 @@ terminate_instance(int id) {
|
||||
delete inst;
|
||||
|
||||
// TODO: we don't currently have any way to stop just one instance
|
||||
// of a multi-instance session. We could maybe close its window or
|
||||
// something.
|
||||
// of a multi-instance session. This will require a different
|
||||
// Python interface than ShowBase.
|
||||
terminate_session();
|
||||
}
|
||||
|
||||
|
@ -15,20 +15,22 @@
|
||||
#ifndef P3DPYTHONRUN_H
|
||||
#define P3DPYTHONRUN_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <assert.h>
|
||||
#include <Python.h>
|
||||
#include <tinyxml.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "p3d_lock.h"
|
||||
#include "handleStream.h"
|
||||
#include "p3dCInstance.h"
|
||||
#include "genericAsyncTask.h"
|
||||
#include "pmap.h"
|
||||
#include "pdeque.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <Python.h>
|
||||
#include <tinyxml.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -56,8 +58,8 @@ public:
|
||||
|
||||
private:
|
||||
void handle_command(TiXmlDocument *doc);
|
||||
void check_comm();
|
||||
static PyObject *py_check_comm(PyObject *, PyObject *args);
|
||||
AsyncTask::DoneStatus check_comm(GenericAsyncTask *task);
|
||||
static AsyncTask::DoneStatus st_check_comm(GenericAsyncTask *task, void *user_data);
|
||||
|
||||
void spawn_read_thread();
|
||||
void join_read_thread();
|
||||
@ -68,13 +70,14 @@ private:
|
||||
|
||||
private:
|
||||
// This method runs only within the read thread.
|
||||
|
||||
void rt_thread_run();
|
||||
#ifdef _WIN32
|
||||
static DWORD WINAPI win_rt_thread_run(LPVOID data);
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef map<int, P3DCInstance *> Instances;
|
||||
typedef pmap<int, P3DCInstance *> Instances;
|
||||
Instances _instances;
|
||||
|
||||
string _program_name;
|
||||
@ -85,9 +88,15 @@ private:
|
||||
PyObject *_exit;
|
||||
PyObject *_setupWindow;
|
||||
|
||||
PT(GenericAsyncTask) _check_comm_task;
|
||||
|
||||
// The remaining members are manipulated by the read thread.
|
||||
typedef deque<TiXmlDocument *> Commands;
|
||||
typedef pdeque<TiXmlDocument *> Commands;
|
||||
Commands _commands;
|
||||
|
||||
// This has to be an actual OS LOCK instead of Panda's Mutex,
|
||||
// because we have to use a true thread here, not one of Panda's
|
||||
// simple threads.
|
||||
LOCK _commands_lock;
|
||||
|
||||
HandleStream _pipe_read;
|
||||
|
Loading…
x
Reference in New Issue
Block a user