FB::SimpleStreamHelperPtr FB::SimpleStreamHelper::AsyncPost( const FB::BrowserHostPtr& host, const FB::URI& uri, const std::string& postdata, const HttpCallback& callback, bool cache /*= true*/, size_t bufferSize /*= 256*1024*/ ) { if (!host->isMainThread()) { // This must be run from the main thread return host->CallOnMainThread(boost::bind(&FB::SimpleStreamHelper::AsyncPost, host, uri, postdata, callback, cache, bufferSize)); } FB::SimpleStreamHelperPtr ptr(boost::make_shared<FB::SimpleStreamHelper>(host, callback, bufferSize)); // This is kinda a weird trick; it's responsible for freeing itself, unless something decides // to hold a reference to it. ptr->keepReference(ptr); FB::BrowserStreamPtr stream(host->createPostStream(uri.toString(), ptr, postdata, true, false, bufferSize)); return ptr; }
void ProcessManagerX11::_open(const FB::BrowserHostPtr& host, const std::string &path) { char *env; std::string launcher; const char *x11Path = path.c_str(); pid_t pid = fork(); env = getenv("SHOTGUN_PLUGIN_LAUNCHER"); launcher = (env == NULL) ? "xdg-open" : std::string(env); switch(pid) { case 0: // child execlp(launcher.c_str(), launcher.c_str(), x11Path, NULL); // should never return from execlp exit(1); default: { // parent host->htmlLog( "[ShotgunIntegration] Launched \"" + launcher + "\" \"" + path + "\" (pid " + boost::lexical_cast<std::string>(pid) + ")" ); } } }
/* * Execute the toolkit command asynchronously */ void ProcessManager::ExecuteToolkitCommandAsync( const FB::BrowserHostPtr& host, const std::string &pipelineConfigPath, const std::string &command, const std::vector<std::string> &args, const ExecuteToolkitCallback &cb) { host->htmlLog("[ShotgunIntegration] ExecuteToolkitCommandAsync"); VerifyArguments(pipelineConfigPath, command); boost::thread cmdThread(&ProcessManager::_ExecuteToolkitCommandAsync, this, pipelineConfigPath, command, args, cb); }
FB::VariantMap ProcessManager::ExecuteTankCommand( const FB::BrowserHostPtr& host, const std::string &pipelineConfigPath, const std::string &command, const std::vector<std::string> &args) { host->htmlLog("[ShotgunIntegration] ExecuteTankCommand"); try { VerifyArguments(pipelineConfigPath, command); fs::path exec = pipelineConfigPath; exec /= TANK_SCRIPT_NAME; std::vector<std::string> arguments = boost::assign::list_of(exec.string())(command); arguments.insert(arguments.end(), args.begin(), args.end()); bp::child child = Launch(exec.string(), arguments); bp::status status = child.wait(); int retcode; if (status.exited()) retcode = status.exit_status(); else retcode = -1; std::string line; std::ostringstream ossStdout; bp::pistream &isStdout = child.get_stdout(); while (std::getline(isStdout, line)) { ossStdout << line << std::endl; } std::ostringstream ossStderr; bp::pistream &isStderr = child.get_stderr(); while (std::getline(isStderr, line)) { ossStderr << line << std::endl; } return FB::variant_map_of<std::string> ("retcode", retcode) ("out", ossStdout.str()) ("err", ossStderr.str()); } catch (std::exception &e) { // May be running in a non-main thread. Avoid propagating exception return FB::variant_map_of<std::string> ("retcode", -1) ("out", std::string("")) ("err", std::string(e.what())); } }
std::string Convert::stringify(const FB::BrowserHostPtr& host, const FB::JSObjectPtr& object) { if(host == NULL) throw DatabaseException("Browser host was null.", DatabaseException::NOT_FOUND_ERR); else if(!host->getDOMWindow()->getProperty<FB::variant>("JSON").is_of_type<FB::JSObjectPtr>()) throw DatabaseException("Could not cast window.JSON to type object.", DatabaseException::UNKNOWN_ERR); FB::JSObjectPtr json = host->getDOMWindow()->getProperty<FB::JSObjectPtr>("JSON"); if(json == NULL) throw DatabaseException("window.JSON support not available.", DatabaseException::NOT_FOUND_ERR); else if(json->HasMethod("stringify")) { FB::VariantList arguments(1, object); FB::variant result = json->Invoke("stringify", arguments); if(result.empty()) throw DatabaseException("JSON Stringification failed.", DatabaseException::RECOVERABLE_ERR); else return result.cast<std::string>(); } else throw DatabaseException("window.JSON missing method stringify().", DatabaseException::NOT_FOUND_ERR); }
FB::HttpStreamResponsePtr FB::SimpleStreamHelper::SynchronousPost( const FB::BrowserHostPtr& host, const FB::URI& uri, const std::string& postdata, const bool cache /*= true*/, const size_t bufferSize /*= 128*1024*/ ) { // Do not call this on the main thread. assert(!host->isMainThread()); SyncHTTPHelper helper; try { FB::HttpCallback cb(boost::bind(&SyncHTTPHelper::getURLCallback, &helper, _1, _2, _3, _4)); FB::SimpleStreamHelperPtr ptr = AsyncPost(host, uri, postdata, cb, cache, bufferSize); helper.setPtr(ptr); helper.waitForDone(); } catch (const std::exception&) { // If anything weird happens, just return NULL (to indicate failure) return FB::HttpStreamResponsePtr(); } return helper.m_response; }
FB::HttpStreamResponsePtr FB::SimpleStreamHelper::SynchronousGet( const FB::BrowserHostPtr& host, const FB::URI& uri, const bool cache /*= true*/, const size_t bufferSize /*= 128*1024*/ ) { // We can't ever block on the main thread, so SynchronousGet can't be called from there. // Also, if you could block the main thread, that still wouldn't work because the request // is processed on the main thread! assert(!host->isMainThread()); SyncGetHelper helper; try { FB::HttpCallback cb(boost::bind(&SyncGetHelper::getURLCallback, &helper, _1, _2, _3, _4)); FB::SimpleStreamHelperPtr ptr = AsyncGet(host, uri, cb, cache, bufferSize); helper.setPtr(ptr); helper.waitForDone(); } catch (const std::exception&) { // If anything weird happens, just return NULL (to indicate failure) return FB::HttpStreamResponsePtr(); } return helper.m_response; }
//libvlc events arrives from separate thread void FBVLC::OnLibVlcEvent_proxy(const libvlc_event_t* e, void *param) { FBVLC* fbvlc = static_cast<FBVLC*>(param); FBVLCAPIPtr api = boost::static_pointer_cast<FBVLCAPI>( fbvlc->getRootJSAPI() ); FB::BrowserHostPtr h = fbvlc->m_host; void (FBVLCAPI::*event_to_fire)(void) = 0; switch ( e->type ) { case libvlc_MediaPlayerMediaChanged: event_to_fire = &FBVLCAPI::fire_MediaPlayerMediaChanged; break; case libvlc_MediaPlayerNothingSpecial: event_to_fire = &FBVLCAPI::fire_MediaPlayerNothingSpecial; break; case libvlc_MediaPlayerOpening: event_to_fire = &FBVLCAPI::fire_MediaPlayerOpening; break; case libvlc_MediaPlayerBuffering: event_to_fire = &FBVLCAPI::fire_MediaPlayerBuffering; break; case libvlc_MediaPlayerPlaying: event_to_fire = &FBVLCAPI::fire_MediaPlayerPlaying; break; case libvlc_MediaPlayerPaused: event_to_fire = &FBVLCAPI::fire_MediaPlayerPaused; break; case libvlc_MediaPlayerStopped: event_to_fire = &FBVLCAPI::fire_MediaPlayerStopped; break; case libvlc_MediaPlayerForward: event_to_fire = &FBVLCAPI::fire_MediaPlayerForward; break; case libvlc_MediaPlayerBackward: event_to_fire = &FBVLCAPI::fire_MediaPlayerBackward; break; case libvlc_MediaPlayerEndReached: event_to_fire = &FBVLCAPI::fire_MediaPlayerEndReached; break; case libvlc_MediaPlayerEncounteredError: event_to_fire = &FBVLCAPI::fire_MediaPlayerEncounteredError; break; case libvlc_MediaPlayerTimeChanged: event_to_fire = &FBVLCAPI::fire_MediaPlayerTimeChanged; break; case libvlc_MediaPlayerPositionChanged: event_to_fire = &FBVLCAPI::fire_MediaPlayerPositionChanged; break; case libvlc_MediaPlayerSeekableChanged: event_to_fire = &FBVLCAPI::fire_MediaPlayerSeekableChanged; break; case libvlc_MediaPlayerPausableChanged: event_to_fire = &FBVLCAPI::fire_MediaPlayerPausableChanged; break; //case libvlc_MediaPlayerTitleChanged: // event_to_fire = &FBVLCAPI::fire_MediaPlayerTitleChanged; // break; //case libvlc_MediaPlayerSnapshotTaken: // event_to_fire = &FBVLCAPI::fire_MediaPlayerSnapshotTaken; // break; //case libvlc_MediaPlayerLengthChanged: // event_to_fire = &FBVLCAPI::fire_MediaPlayerLengthChanged; // break; //case libvlc_MediaPlayerVout: // event_to_fire = &FBVLCAPI::fire_MediaPlayerVout; // break; }; if ( event_to_fire ) { h->ScheduleOnMainThread( api, boost::bind( event_to_fire, api.get() ) ); } }
void ProcessManagerX11::Open(const FB::BrowserHostPtr& host, const std::string &path) { host->ScheduleOnMainThread(boost::shared_ptr<ProcessManagerX11>(), boost::bind(&ProcessManagerX11::_open, this, host, path)); }
//libvlc events arrives from separate thread void Chimera::media_player_event( const libvlc_event_t* e ) { JSRootAPIPtr api = boost::static_pointer_cast<JSRootAPI>( getRootJSAPI() ); FB::BrowserHostPtr h = m_host; void (JSRootAPI::*event_to_fire)(void) = 0; bool fireStateChanged = false; libvlc_state_t newState; bool scheduleNotPlaying = false; switch ( e->type ) { case libvlc_MediaPlayerMediaChanged: event_to_fire = &JSRootAPI::fire_MediaPlayerMediaChanged; break; case libvlc_MediaPlayerNothingSpecial: event_to_fire = &JSRootAPI::fire_MediaPlayerNothingSpecial; fireStateChanged = true; newState = libvlc_NothingSpecial; break; case libvlc_MediaPlayerOpening: event_to_fire = &JSRootAPI::fire_MediaPlayerOpening; fireStateChanged = true; newState = libvlc_Opening; break; case libvlc_MediaPlayerBuffering: h->ScheduleOnMainThread( api, boost::bind( &JSRootAPI::fire_MediaPlayerBuffering, api.get(), e->u.media_player_buffering.new_cache ) ); fireStateChanged = true; newState = libvlc_Buffering; break; case libvlc_MediaPlayerPlaying: { boost::shared_ptr<Chimera> thisPtr = FB::ptr_cast<Chimera>( shared_from_this() ); h->ScheduleOnMainThread( thisPtr, boost::bind( &Chimera::onMediaPlayerPlaying, thisPtr ) ); event_to_fire = &JSRootAPI::fire_MediaPlayerPlaying; fireStateChanged = true; newState = libvlc_Playing; break; } case libvlc_MediaPlayerPaused: event_to_fire = &JSRootAPI::fire_MediaPlayerPaused; scheduleNotPlaying = true; fireStateChanged = true; newState = libvlc_Paused; break; case libvlc_MediaPlayerStopped: event_to_fire = &JSRootAPI::fire_MediaPlayerStopped; scheduleNotPlaying = true; fireStateChanged = true; newState = libvlc_Stopped; break; case libvlc_MediaPlayerForward: event_to_fire = &JSRootAPI::fire_MediaPlayerForward; break; case libvlc_MediaPlayerBackward: event_to_fire = &JSRootAPI::fire_MediaPlayerBackward; break; case libvlc_MediaPlayerEndReached: event_to_fire = &JSRootAPI::fire_MediaPlayerEndReached; scheduleNotPlaying = true; fireStateChanged = true; newState = libvlc_Ended; break; case libvlc_MediaPlayerEncounteredError: event_to_fire = &JSRootAPI::fire_MediaPlayerEncounteredError; scheduleNotPlaying = true; fireStateChanged = true; newState = libvlc_Error; break; case libvlc_MediaPlayerTimeChanged: { double new_time = static_cast<double>( e->u.media_player_time_changed.new_time ); h->ScheduleOnMainThread( api, boost::bind( &JSRootAPI::fire_MediaPlayerTimeChanged, api.get(), new_time ) ); break; } case libvlc_MediaPlayerPositionChanged: h->ScheduleOnMainThread( api, boost::bind( &JSRootAPI::fire_MediaPlayerPositionChanged, api.get(), e->u.media_player_position_changed.new_position ) ); break; case libvlc_MediaPlayerSeekableChanged: h->ScheduleOnMainThread( api, boost::bind( &JSRootAPI::fire_MediaPlayerSeekableChanged, api.get(), e->u.media_player_seekable_changed.new_seekable != 0 ) ); break; case libvlc_MediaPlayerPausableChanged: h->ScheduleOnMainThread( api, boost::bind( &JSRootAPI::fire_MediaPlayerPausableChanged, api.get(), e->u.media_player_pausable_changed.new_pausable != 0 ) ); break; //case libvlc_MediaPlayerTitleChanged: // event_to_fire = &JSRootAPI::fire_MediaPlayerTitleChanged; // break; //case libvlc_MediaPlayerSnapshotTaken: // event_to_fire = &JSRootAPI::fire_MediaPlayerSnapshotTaken; // break; case libvlc_MediaPlayerLengthChanged: { double new_length = static_cast<double>( e->u.media_player_length_changed.new_length ); h->ScheduleOnMainThread( api, boost::bind( &JSRootAPI::fire_MediaPlayerLengthChanged, api.get(), new_length ) ); break; } //case libvlc_MediaPlayerVout: // event_to_fire = &JSRootAPI::fire_MediaPlayerVout; // break; }; if( event_to_fire ) { h->ScheduleOnMainThread( api, boost::bind( event_to_fire, api.get() ) ); } if( fireStateChanged ) { h->ScheduleOnMainThread( api, boost::bind( &JSRootAPI::fire_MediaPlayerStateChanged, api.get(), newState ) ); } if( scheduleNotPlaying ) { boost::shared_ptr<Chimera> thisPtr = FB::ptr_cast<Chimera>( shared_from_this() ); h->ScheduleOnMainThread( thisPtr, boost::bind( &Chimera::onMediaPlayerNotPlaying, thisPtr ) ); } }