Пример #1
0
/**
 * processItem
 *    - If this is a TclCommand - flush all the consolidations and output.
 *    - If there's already a consolidation for  this type if the message is the
 *      same just count it, otherwise flush and set a new consolidation.
 *    - If there's not an existing consolidation, make one.
 *    - free storage associated with the action item's payload.
 *
 *    @param action - action message.
 */
void
Actions::COutputThread::processItem(Actions::ActionItem item)
{
    Actions::ActionType type = item.s_type;
    std::string        msg  = item.s_pMessage;
    free(item.s_pMessage);                 // Free storage!'
    
    if (type == Actions::TclCommand) {
        flushMessages();                // Flush All messages before commanding.
        outputItem(type, msg);
    } else {
        //  Message, not an actual 'action'.
        
        std::map<Actions::ActionType, ActionInfo>::iterator p =
            m_ConsolidatedActions.find(type);
        if (p == m_ConsolidatedActions.end()) {     // No prior message.
            createConsolidation(type, msg);
        } else {
            if(msg == p->second.s_message) {          // If repetition
                p->second.s_messageCount++; // count.
            } else {
                flushItem(type);                     // otherwise flush  that item.
                createConsolidation(type, msg);    // start a new one.
            }
        }
    }
}
Пример #2
0
/**
 * operator()
 *    This is the entry point of the code.
 *    - Save the current time in s_lastAdded
 *    - Process action items aggregating and flushing as time advances.
 *
 *    For now we'll just flush as time changes (each second).
 */
void
Actions::COutputThread::operator()()
{
    time_t lastTime = time(NULL);
    while(1) {
        // Try to get data from the queue...if not available, wait
        // for up to a second for data:
        
        Actions::ActionItem item;
        while (!m_pActionQueue->getnow(item)) {
            // See if we should flush all
            
            time_t now = time(NULL);
            if (now != lastTime) {
                flushMessages();              // Flush all consolidations.
                lastTime = now;
            }
            m_pActionQueue->wait(1000);
        }
        // We have an action item now.
        
        processItem(item);
        

    }
}
Пример #3
0
CarlaBridgeUI::~CarlaBridgeUI() /*noexcept*/
{
    carla_debug("CarlaBridgeUI::~CarlaBridgeUI()");

    if (fLib != nullptr)
    {
        lib_close(fLib);
        fLib = nullptr;
    }

    if (isPipeRunning() && ! fQuitReceived)
    {
        const CarlaMutexLocker cml(getPipeLock());
        writeMessage("exiting\n", 8);
        flushMessages();
    }

    if (fToolkit != nullptr)
    {
        fToolkit->quit();
        delete fToolkit;
        fToolkit = nullptr;
    }

    closePipeClient();
}
Пример #4
0
    ~ZynPipeClient() noexcept override
    {
        if (fQuitReceived)
            return;

        const CarlaMutexLocker cml(getPipeLock());

        writeMessage("exiting\n");
        flushMessages();
    }
Пример #5
0
    void uiNameChanged(const char* const uiName) override
    {
        CARLA_SAFE_ASSERT_RETURN(uiName != nullptr && uiName[0] != '\0',);

        const CarlaMutexLocker cml(getPipeLock());

        if (! writeMessage("uiTitle\n", 8))
            return;
        if (! writeAndFixMessage(uiName))
            return;

        flushMessages();
    }
Пример #6
0
bool CarlaBridgeUI::init(const int argc, const char* argv[])
{
    CARLA_SAFE_ASSERT_RETURN(fToolkit != nullptr, false);

    if (argc == 7)
    {
        if (! initPipeClient(argv))
            return false;

        fLastMsgTimer = 0;

        // wait for ui options
        for (; ++fLastMsgTimer < 50 && ! fGotOptions;)
        {
            idlePipe(true);
            carla_msleep(20);
        }

        if (! fGotOptions)
        {
            carla_stderr2("CarlaBridgeUI::init() - did not get options on time, quitting...");
            {
                const CarlaMutexLocker cml(getPipeLock());
                writeMessage("exiting\n", 8);
                flushMessages();
            }
            closePipeClient();
            return false;
        }
    }

    if (! fToolkit->init(argc, argv))
    {
        if (argc == 7)
            closePipeClient();
        return false;
    }

    return true;
}
/* virtual */
void LLPluginProcessChild::receivePluginMessage(const std::string &message)
{
	LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL;
	
	if(mBlockingRequest)
	{
		// 
		LL_ERRS("Plugin") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL;
	}
	
	// Incoming message from the plugin instance
	bool passMessage = true;

	// FIXME: how should we handle queueing here?
	
	// Intercept certain base messages (responses to ones sent by this class)
	{
		// Decode this message
		LLPluginMessage parsed;
		parsed.parse(message);
		
		if(parsed.hasValue("blocking_request"))
		{
			mBlockingRequest = true;
		}

		std::string message_class = parsed.getClass();
		if(message_class == "base")
		{
			std::string message_name = parsed.getName();
			if(message_name == "init_response")
			{
				// The plugin has finished initializing.
				setState(STATE_RUNNING);

				// Don't pass this message up to the parent
				passMessage = false;
				
				LLPluginMessage new_message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin_response");
				LLSD versions = parsed.getValueLLSD("versions");
				new_message.setValueLLSD("versions", versions);
				
				if(parsed.hasValue("plugin_version"))
				{
					std::string plugin_version = parsed.getValue("plugin_version");
					new_message.setValueLLSD("plugin_version", plugin_version);
				}

				// Let the parent know it's loaded and initialized.
				sendMessageToParent(new_message);
			}
			else if(message_name == "shm_remove_response")
			{
				// Don't pass this message up to the parent
				passMessage = false;

				std::string name = parsed.getValue("name");
				sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);				
				if(iter != mSharedMemoryRegions.end())
				{
					// detach the shared memory region
					iter->second->detach();
					
					// and remove it from our map
					mSharedMemoryRegions.erase(iter);
					
					// Finally, send the response to the parent.
					LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove_response");
					message.setValue("name", name);
					sendMessageToParent(message);
				}
				else
				{
					LL_WARNS("Plugin") << "shm_remove_response for unknown memory segment!" << LL_ENDL;
				}
			}
		}
		else if (message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
		{
			bool flush = false;
			std::string message_name = parsed.getName();
			if(message_name == "shutdown")
			{
				// The plugin is finished.
				setState(STATE_UNLOADING);
				flush = true;
			}
			else if (message_name == "flush")
			{
				flush = true;
				passMessage = false;
			}
			if (flush)
			{
				flushMessages();
			}
		}
	}
	
	if(passMessage)
	{
		LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
		writeMessageRaw(message);
	}
	
	while(mBlockingRequest)
	{
		// The plugin wants to block and wait for a response to this message.
		sleep(mSleepTime);	// this will pump the message pipe and process messages

		if(mBlockingResponseReceived || mSocketError != APR_SUCCESS || (mMessagePipe == NULL))
		{
			// Response has been received, or we've hit an error state.  Stop waiting.
			mBlockingRequest = false;
			mBlockingResponseReceived = false;
		}
	}
}
// This is the SLPlugin process.
// This is part of the loaded DSO.
//
// This function is called from LLPluginInstance::sendMessage
// for messages received from the viewer (that are not 'internal').
void FilepickerPlugin::receiveMessage(char const* message_string)
{
	LLPluginMessage message_in;

	if (message_in.parse(message_string) >= 0)
	{
		std::string message_class = message_in.getClass();
		std::string message_name = message_in.getName();

		if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
		{
			if (message_name == "init")
			{
				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_BASE, "init_response");
				LLSD versions = LLSD::emptyMap();
				versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
				versions[LLPLUGIN_MESSAGE_CLASS_BASIC] = LLPLUGIN_MESSAGE_CLASS_BASIC_VERSION;
				message.setValueLLSD("versions", versions);

				std::string plugin_version = "Filepicker Plugin, version 1.0.0.0";
				message.setValue("plugin_version", plugin_version);
				sendMessage(message);
			}
			else if (message_name == "cleanup")
			{
				// We have no resources that need care. Just do nothing.
			}
			else if (message_name == "idle")
			{
				// This whole message should not have existed imho -- Aleric
			}
			else
			{
				std::cerr << "FilepickerPlugin::receiveMessage: unknown base message: " << message_name << std::endl;
			}
		}
		else if (message_class == LLPLUGIN_MESSAGE_CLASS_BASIC)
		{
			// This message should be sent at most once per SLPlugin invokation.
			if (message_name == "initialization")
			{
				LLSD dictionary = message_in.getValueLLSD("dictionary");
				for (LLSD::map_iterator iter = dictionary.beginMap(); iter != dictionary.endMap(); ++iter)
				{
					translation::add(iter->first, iter->second.asString());
				}
				if (message_in.hasValue("window_id"))
				{
					unsigned long window_id = strtoul(message_in.getValue("window_id").c_str(), NULL, 16);
					LLFilePicker::instance().setWindowID(window_id);
				}
			}
			// This message may theoretically be repeated (though currently the plugin is terminated after returning).
			else if (message_name == "open")
			{
				std::string type = message_in.getValue("type");
				std::string filter = message_in.getValue("filter");
				std::string folder = message_in.getValue("folder");
				bool get_directory = (filter == "directory");

				// We about to completely block on running the modal File/Dir picker window, so flush any pending messages to the viewer.
				flushMessages();

				bool canceled;
				if (get_directory)
				{
					canceled = !LLDirPicker::instance().getDir(folder);
				}
				else if (type == "save")
				{
					canceled = !LLFilePicker::instance().getSaveFile(str2savefilter(filter), message_in.getValue("default"), folder);
				}
				else if (type == "load")
				{
					canceled = !LLFilePicker::instance().getLoadFile(str2loadfilter(filter), folder);
				}
				else // type == "load_multiple"
				{
					canceled = !LLFilePicker::instance().getMultipleLoadFiles(str2loadfilter(filter), folder);
				}
				if (canceled)
				{
					LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_BASIC, "canceled");
					message.setValue("perseus", "unblock");
					sendMessage(message);
				}
				else
				{
					LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_BASIC, "done");
					message.setValue("perseus", "unblock");
					LLSD filenames;
					if (get_directory)
					{
						filenames.append(LLDirPicker::instance().getDirName());
					}
					else
					{
						for (std::string filename = LLFilePicker::instance().getFirstFile(); !filename.empty(); filename = LLFilePicker::instance().getNextFile())
						{
							filenames.append(filename);
						}
					}
					message.setValueLLSD("filenames", filenames);
					sendMessage(message);
				}
				// We're done. Exit the whole application.
				// This first flushes any messages before terminating the plugin.
				sendShutdownMessage();
			}
			else
			{
				std::cerr << "FilepickerPlugin::receiveMessage: unknown basic message: " << message_name << std::endl;
			}
		}
		else
		{
			std::cerr << "FilepickerPlugin::receiveMessage: unknown message class: " << message_class << std::endl;
		}
	}
}