P3D_instance_start_stream()

This commit is contained in:
David Rose 2009-10-16 18:07:35 +00:00
parent c2be49507f
commit fbb5c7ce0d
10 changed files with 120 additions and 32 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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());

View File

@ -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;

View File

@ -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);

View File

@ -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;