mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
P3D_instance_start_stream()
This commit is contained in:
parent
c2be49507f
commit
fbb5c7ce0d
@ -40,6 +40,7 @@ P3D_set_plugin_version_func *P3D_set_plugin_version;
|
||||
P3D_set_super_mirror_func *P3D_set_super_mirror;
|
||||
P3D_new_instance_func *P3D_new_instance;
|
||||
P3D_instance_start_func *P3D_instance_start;
|
||||
P3D_instance_start_stream_func *P3D_instance_start_stream;
|
||||
P3D_instance_finish_func *P3D_instance_finish;
|
||||
P3D_instance_setup_window_func *P3D_instance_setup_window;
|
||||
|
||||
@ -193,6 +194,7 @@ load_plugin(const string &p3d_plugin_filename,
|
||||
P3D_set_super_mirror = (P3D_set_super_mirror_func *)get_func(module, "P3D_set_super_mirror");
|
||||
P3D_new_instance = (P3D_new_instance_func *)get_func(module, "P3D_new_instance");
|
||||
P3D_instance_start = (P3D_instance_start_func *)get_func(module, "P3D_instance_start");
|
||||
P3D_instance_start_stream = (P3D_instance_start_stream_func *)get_func(module, "P3D_instance_start_stream");
|
||||
P3D_instance_finish = (P3D_instance_finish_func *)get_func(module, "P3D_instance_finish");
|
||||
P3D_instance_setup_window = (P3D_instance_setup_window_func *)get_func(module, "P3D_instance_setup_window");
|
||||
|
||||
@ -234,6 +236,7 @@ load_plugin(const string &p3d_plugin_filename,
|
||||
P3D_set_super_mirror == NULL ||
|
||||
P3D_new_instance == NULL ||
|
||||
P3D_instance_start == NULL ||
|
||||
P3D_instance_start_stream == NULL ||
|
||||
P3D_instance_finish == NULL ||
|
||||
P3D_instance_setup_window == NULL ||
|
||||
|
||||
@ -275,6 +278,7 @@ load_plugin(const string &p3d_plugin_filename,
|
||||
<< "\nP3D_set_super_mirror = " << P3D_set_super_mirror
|
||||
<< "\nP3D_new_instance = " << P3D_new_instance
|
||||
<< "\nP3D_instance_start = " << P3D_instance_start
|
||||
<< "\nP3D_instance_start_stream = " << P3D_instance_start_stream
|
||||
<< "\nP3D_instance_finish = " << P3D_instance_finish
|
||||
<< "\nP3D_instance_setup_window = " << P3D_instance_setup_window
|
||||
|
||||
@ -371,6 +375,7 @@ unload_dso() {
|
||||
P3D_set_super_mirror = NULL;
|
||||
P3D_new_instance = NULL;
|
||||
P3D_instance_start = NULL;
|
||||
P3D_instance_start_stream = NULL;
|
||||
P3D_instance_finish = NULL;
|
||||
P3D_instance_setup_window = NULL;
|
||||
|
||||
|
@ -26,6 +26,7 @@ extern P3D_set_plugin_version_func *P3D_set_plugin_version;
|
||||
extern P3D_set_super_mirror_func *P3D_set_super_mirror;
|
||||
extern P3D_new_instance_func *P3D_new_instance;
|
||||
extern P3D_instance_start_func *P3D_instance_start;
|
||||
extern P3D_instance_start_stream_func *P3D_instance_start_stream;
|
||||
extern P3D_instance_finish_func *P3D_instance_finish;
|
||||
extern P3D_instance_setup_window_func *P3D_instance_setup_window;
|
||||
|
||||
|
@ -279,7 +279,8 @@ P3DInstance::
|
||||
// Access: Public
|
||||
// Description: Specifies a URL that should be contacted to download
|
||||
// the instance data. Normally this, or
|
||||
// set_p3d_filename(), is only called once.
|
||||
// set_p3d_filename() or make_p3d_stream(), is only
|
||||
// called once.
|
||||
//
|
||||
// The instance data at the other end of this URL is
|
||||
// key. We can't start the instance until we have
|
||||
@ -315,6 +316,41 @@ set_p3d_url(const string &p3d_url) {
|
||||
start_download(download);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::make_p3d_stream
|
||||
// Access: Public
|
||||
// Description: Indicates an intention to transmit the p3d data as a
|
||||
// stream. Should return a new unique stream ID to
|
||||
// receive it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DInstance::
|
||||
make_p3d_stream(const string &p3d_url) {
|
||||
// Make a temporary file to receive the instance data.
|
||||
assert(_temp_p3d_filename == NULL);
|
||||
_temp_p3d_filename = new P3DTemporaryFile(".p3d");
|
||||
_stuff_to_download = true;
|
||||
|
||||
// Maybe it's time to open a splash window now.
|
||||
make_splash_window();
|
||||
|
||||
// Mark the time we started downloading, so we'll know when to reveal
|
||||
// the progress bar.
|
||||
#ifdef _WIN32
|
||||
_start_dl_instance_tick = GetTickCount();
|
||||
#else
|
||||
gettimeofday(&_start_dl_instance_timeval, NULL);
|
||||
#endif
|
||||
_show_dl_instance_progress = false;
|
||||
|
||||
// Start downloading the data.
|
||||
InstanceDownload *download = new InstanceDownload(this);
|
||||
download->set_url(p3d_url);
|
||||
download->set_filename(_temp_p3d_filename->get_filename());
|
||||
|
||||
_panda_script_object->set_string_property("status", "downloading_instance");
|
||||
return start_download(download, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::set_p3d_filename
|
||||
// Access: Public
|
||||
@ -908,9 +944,18 @@ get_packages_failed() const {
|
||||
// This increments the P3DDownload object's reference
|
||||
// count, and will decrement it (and possibly delete the
|
||||
// object) after download_finished() has been called.
|
||||
//
|
||||
// add_request should be true to actually request the
|
||||
// URL from the plugin, or false not to. Normally, this
|
||||
// should always be set true, except in the one special
|
||||
// case of make_p3d_stream(), in which case the plugin
|
||||
// is already prepared to send the stream and doesn't
|
||||
// need to have it requested.
|
||||
//
|
||||
// Returns the unique ID of this stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
start_download(P3DDownload *download) {
|
||||
int P3DInstance::
|
||||
start_download(P3DDownload *download, bool add_request) {
|
||||
assert(download->get_download_id() == 0);
|
||||
assert(!download->get_url().empty());
|
||||
|
||||
@ -923,12 +968,16 @@ start_download(P3DDownload *download) {
|
||||
bool inserted = _downloads.insert(Downloads::value_type(download_id, download)).second;
|
||||
assert(inserted);
|
||||
|
||||
P3D_request *request = new P3D_request;
|
||||
request->_request_type = P3D_RT_get_url;
|
||||
request->_request._get_url._url = strdup(download->get_url().c_str());
|
||||
request->_request._get_url._unique_id = download_id;
|
||||
if (add_request) {
|
||||
P3D_request *request = new P3D_request;
|
||||
request->_request_type = P3D_RT_get_url;
|
||||
request->_request._get_url._url = strdup(download->get_url().c_str());
|
||||
request->_request._get_url._unique_id = download_id;
|
||||
|
||||
add_baked_request(request);
|
||||
}
|
||||
|
||||
add_baked_request(request);
|
||||
return download_id;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
|
||||
void set_p3d_url(const string &p3d_url);
|
||||
void set_p3d_filename(const string &p3d_filename);
|
||||
int make_p3d_stream(const string &p3d_url);
|
||||
inline const P3DFileParams &get_fparams() const;
|
||||
|
||||
void set_wparams(const P3DWindowParams &wparams);
|
||||
@ -97,7 +98,7 @@ public:
|
||||
bool get_packages_failed() const;
|
||||
|
||||
inline bool is_trusted() const;
|
||||
void start_download(P3DDownload *download);
|
||||
int start_download(P3DDownload *download, bool add_request = true);
|
||||
inline bool is_started() const;
|
||||
inline bool is_failed() const;
|
||||
void request_stop_sub_thread();
|
||||
|
@ -425,6 +425,22 @@ set_p3d_filename(P3DInstance *inst, bool is_local,
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::make_p3d_stream
|
||||
// Access: Public
|
||||
// Description: Indicates an intention to transmit the p3d data as a
|
||||
// stream. Should return a new unique stream ID to
|
||||
// receive it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DInstanceManager::
|
||||
make_p3d_stream(P3DInstance *inst, const string &p3d_url) {
|
||||
if (inst->is_started()) {
|
||||
nout << "Instance started twice: " << inst << "\n";
|
||||
return -1;
|
||||
}
|
||||
return inst->make_p3d_stream(p3d_url);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::start_instance
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
|
||||
bool set_p3d_filename(P3DInstance *inst, bool is_local,
|
||||
const string &p3d_filename);
|
||||
int make_p3d_stream(P3DInstance *inst, const string &p3d_url);
|
||||
bool start_instance(P3DInstance *inst);
|
||||
void finish_instance(P3DInstance *inst);
|
||||
P3DAuthSession *authorize_instance(P3DInstance *inst);
|
||||
|
@ -151,6 +151,23 @@ P3D_instance_start(P3D_instance *instance, bool is_local,
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
P3D_instance_start_stream(P3D_instance *instance, const char *p3d_url) {
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
if (p3d_url == NULL) {
|
||||
p3d_url = "";
|
||||
}
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
P3DInstance *inst = inst_mgr->validate_instance(instance);
|
||||
int result = -1;
|
||||
if (inst != NULL) {
|
||||
result = inst_mgr->make_p3d_stream(inst, p3d_url);
|
||||
}
|
||||
RELEASE_LOCK(_api_lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
P3D_instance_finish(P3D_instance *instance) {
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
|
@ -313,13 +313,28 @@ P3D_new_instance_func(P3D_request_ready_func *func,
|
||||
|
||||
If is_local is true, then p3d_filename contains the name of a local
|
||||
p3d file on disk. If false, then p3d_filename contains a URL that
|
||||
should be downloaded to retrieve the p3d file.
|
||||
should be downloaded to retrieve the p3d file. Also see
|
||||
P3D_instance_start_stream(), below.
|
||||
|
||||
The return value is true on success, false on failure. */
|
||||
typedef bool
|
||||
P3D_instance_start_func(P3D_instance *instance, bool is_local,
|
||||
const char *p3d_filename);
|
||||
|
||||
/* This function is an alternative to P3D_instance_start(); it
|
||||
indicates an intention to feed the p3d file data to the instance as
|
||||
a stream. The instance should return a unique integer ID for this
|
||||
stream, as if the instance had requested the stream via a get_url
|
||||
request (below). The plugin will then send the p3d file data to
|
||||
the instance via a series of calls to
|
||||
P3D_instance_feed_url_stream(), using the unique ID returned by
|
||||
this function. When the stream has been transmitted successfully,
|
||||
the instance will automatically start.
|
||||
|
||||
The p3d_url string passed to this function is informational only.
|
||||
The instance will not explicitly request this URL. */
|
||||
typedef int
|
||||
P3D_instance_start_stream_func(P3D_instance *instance, const char *p3d_url);
|
||||
|
||||
/* Call this function to interrupt a particular instance and stop it
|
||||
from rendering, for instance when the user navigates away from the
|
||||
@ -890,6 +905,7 @@ EXPCL_P3D_PLUGIN P3D_set_super_mirror_func P3D_set_super_mirror;
|
||||
|
||||
EXPCL_P3D_PLUGIN P3D_new_instance_func P3D_new_instance;
|
||||
EXPCL_P3D_PLUGIN P3D_instance_start_func P3D_instance_start;
|
||||
EXPCL_P3D_PLUGIN P3D_instance_start_stream_func P3D_instance_start_stream;
|
||||
EXPCL_P3D_PLUGIN P3D_instance_finish_func P3D_instance_finish;
|
||||
EXPCL_P3D_PLUGIN P3D_instance_setup_window_func P3D_instance_setup_window;
|
||||
|
||||
|
@ -28,8 +28,7 @@ public:
|
||||
enum RequestType {
|
||||
RT_contents_file,
|
||||
RT_core_dll,
|
||||
RT_user,
|
||||
RT_instance_data
|
||||
RT_user
|
||||
};
|
||||
|
||||
inline PPDownloadRequest(RequestType rtype, int user_id = 0);
|
||||
|
@ -192,19 +192,12 @@ new_stream(NPMIMEType type, NPStream *stream, bool seekable, uint16 *stype) {
|
||||
// stream we receive is the instance data; any other unsolicited
|
||||
// stream is an error.
|
||||
|
||||
// We don't let Mozilla finish downloading the instance data, but
|
||||
// we do extract its URL to pass to the instance.
|
||||
if (!_got_instance_url && stream->url != NULL) {
|
||||
if (!_got_instance_url && stream->url != NULL && _p3d_inst != NULL) {
|
||||
_got_instance_url = true;
|
||||
_instance_url = stream->url;
|
||||
if (_p3d_inst != NULL) {
|
||||
P3D_instance_start(_p3d_inst, false, _instance_url.c_str());
|
||||
}
|
||||
int user_id = P3D_instance_start_stream(_p3d_inst, _instance_url.c_str());
|
||||
|
||||
// We don't want the rest of this stream any more, but we can't
|
||||
// just return NPERR_GENERIC_ERROR, though--that seems to freak
|
||||
// out Firefox.
|
||||
stream->notifyData = new PPDownloadRequest(PPDownloadRequest::RT_instance_data);
|
||||
stream->notifyData = new PPDownloadRequest(PPDownloadRequest::RT_user, user_id);
|
||||
|
||||
*stype = NP_NORMAL;
|
||||
return NPERR_NO_ERROR;
|
||||
@ -263,13 +256,6 @@ write_stream(NPStream *stream, int offset, int len, void *buffer) {
|
||||
P3D_RC_in_progress, 0,
|
||||
stream->end, buffer, len);
|
||||
return len;
|
||||
|
||||
case PPDownloadRequest::RT_instance_data:
|
||||
// Here's a stream we don't really want. But stopping it here
|
||||
// seems to freak out Safari. (And stopping it before it starts
|
||||
// freaks out Firefox.) Whatever. We'll just quietly ignore the
|
||||
// data.
|
||||
return len;
|
||||
|
||||
default:
|
||||
nout << "Unexpected write_stream on " << stream->url << "\n";
|
||||
@ -309,9 +295,6 @@ destroy_stream(NPStream *stream, NPReason reason) {
|
||||
}
|
||||
break;
|
||||
|
||||
case PPDownloadRequest::RT_instance_data:
|
||||
break;
|
||||
|
||||
default:
|
||||
nout << "Unexpected destroy_stream on " << stream->url << "\n";
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user