Пример #1
0
static void DeserializeMetadata(const std::string& document, CAddonBuilder& builder)
{
  CVariant variant = CJSONVariantParser::Parse(document);

  builder.SetAuthor(variant["author"].asString());
  builder.SetDisclaimer(variant["disclaimer"].asString());
  builder.SetBroken(variant["broken"].asString());
  builder.SetPackageSize(variant["size"].asUnsignedInteger());

  builder.SetPath(variant["path"].asString());
  builder.SetFanart(variant["fanart"].asString());
  builder.SetIcon(variant["icon"].asString());

  std::vector<std::string> screenshots;
  for (auto it = variant["screenshots"].begin_array(); it != variant["screenshots"].end_array(); ++it)
    screenshots.push_back(it->asString());
  builder.SetScreenshots(std::move(screenshots));

  builder.SetType(TranslateType(variant["extensions"][0].asString()));

  ADDONDEPS deps;
  for (auto it = variant["dependencies"].begin_array(); it != variant["dependencies"].end_array(); ++it)
  {
    AddonVersion version((*it)["version"].asString());
    deps.emplace((*it)["addonId"].asString(), std::make_pair(std::move(version), (*it)["optional"].asBoolean()));
  }
  builder.SetDependencies(std::move(deps));

  InfoMap extraInfo;
  for (auto it = variant["extrainfo"].begin_array(); it != variant["extrainfo"].end_array(); ++it)
    extraInfo.emplace((*it)["key"].asString(), (*it)["value"].asString());
  builder.SetExtrainfo(std::move(extraInfo));
}
Пример #2
0
inline static QString toString(const InfoMap &infoMap, const QString sep="\n")
{
    QString str("");
    InfoMap::const_iterator it = infoMap.begin();
    for (; it != infoMap.end() ; ++it)
        str += QString("[%1]:%2%3").arg(it.key()).arg(*it).arg(sep);
    return str;
}
Пример #3
0
void MythGenericTree::SetTextFromMap(const InfoMap &infoMap,
                                     const QString &state)
{
    InfoMap::const_iterator map_it = infoMap.begin();
    while (map_it != infoMap.end())
    {
        TextProperties textprop;
        textprop.text = (*map_it);
        textprop.state = state;
        m_strings[map_it.key()] = textprop;
        ++map_it;
    }
}
Пример #4
0
mitk::PropertyPersistence::InfoMap mitk::PropertyPersistence::SelectInfo(const InfoMap &infoMap,
                                                                         const SelectFunctionType &selectFunction)
{
  InfoMap result;

  for (auto pos : infoMap)
  {
    if (selectFunction(pos))
    {
      result.insert(pos);
    }
  }

  return result;
};
Пример #5
0
mitk::PropertyPersistence::InfoResultType mitk::PropertyPersistence::GetInfo(const std::string &propertyName,
                                                                             const MimeTypeNameType &mime,
                                                                             bool allowMimeWildCard,
                                                                             bool allowNameRegEx) const
{
  SelectFunctionType select = [propertyName, mime](const InfoMap::value_type &x) {
    return infoPredicate(x, propertyName, mime);
  };

  InfoMap selection = SelectInfo(m_InfoMap, select);

  if (allowNameRegEx)
  {
    select = [propertyName, mime](const InfoMap::value_type &x) { return infoPredicateRegEx(x, propertyName, mime); };

    InfoMap regExSelection = SelectInfo(m_InfoMap, select);

    selection.insert(regExSelection.begin(), regExSelection.end());
  }

  if (selection.empty() && allowMimeWildCard)
  { // no perfect match => second run through with "any mime type"
    select = [propertyName](const InfoMap::value_type &x) {
      return infoPredicate(x, propertyName, PropertyPersistenceInfo::ANY_MIMETYPE_NAME());
    };

    selection = SelectInfo(m_InfoMap, select);

    if (allowNameRegEx)
    {
      select = [propertyName](const InfoMap::value_type &x) {
        return infoPredicateRegEx(x, propertyName, PropertyPersistenceInfo::ANY_MIMETYPE_NAME());
      };

      InfoMap regExSelection = SelectInfo(m_InfoMap, select);

      selection.insert(regExSelection.begin(), regExSelection.end());
    }
  }

  InfoResultType result;
  for (const auto &pos : selection)
  {
    result.push_back(pos.second->UnRegExByName(propertyName).GetPointer());
  }

  return result;
}
Пример #6
0
Distribution combine(Distribution const& c, InfoMap const& info)
{
    std::map<Cell, Value> tmp;

    for (size_t i = 0; i < c.size(); ++i)
    {
        Distribution const& w = info.at(c.at(i).first)->weights;
        Value const f = c.at(i).second;

        for (size_t j = 0; j < w.size(); ++j)
        {
            Cell const v = w.at(j).first;
            if (tmp.count(v) == 0)
                tmp[v] = 0;
            tmp[v] += f * w.at(j).second;
        }
    }

    Distribution result(tmp.size());

    std::map<Cell, Value>::const_iterator iter = tmp.begin();
    for (size_t i = 0; i < tmp.size(); ++i, ++iter)
        result[i] = std::make_pair(iter->first, iter->second);

    return result;
}
Пример #7
0
 inline
 void UserInfoCache::removeUser(int userId)
 {
     d_lock.lockWrite();
     d_infoMap.erase(userId);
     d_lock.unlock();
 }
Пример #8
0
bool PlayerContext::GetPlayingInfoMap(InfoMap &infoMap) const
{
    bool loaded = false;
    LockPlayingInfo(__FILE__, __LINE__);
    if (playingInfo)
    {
        playingInfo->ToMap(infoMap);
        infoMap["tvstate"]  = StateToString(playingState);
        infoMap["iconpath"] = ChannelUtil::GetIcon(playingInfo->GetChanID());
        if ((playingInfo->IsVideoFile() || playingInfo->IsVideoDVD() ||
            playingInfo->IsVideoBD()) && playingInfo->GetPathname() !=
            playingInfo->GetBasename())
        {
            infoMap["coverartpath"] = VideoMetaDataUtil::GetArtPath(
                playingInfo->GetPathname(), "Coverart");
            infoMap["fanartpath"] = VideoMetaDataUtil::GetArtPath(
                playingInfo->GetPathname(), "Fanart");
            infoMap["bannerpath"] = VideoMetaDataUtil::GetArtPath(
                playingInfo->GetPathname(), "Banners");
            infoMap["screenshotpath"] = VideoMetaDataUtil::GetArtPath(
                playingInfo->GetPathname(), "Screenshots");
        }
        if (player)
            player->GetCodecDescription(infoMap);

        infoMap.detach();
        loaded = true;
    }
    UnlockPlayingInfo(__FILE__, __LINE__);
    return loaded;
}
Пример #9
0
bool
MediaAddonServer::QuitRequested()
{
	CALLED();

	InfoMap::iterator iterator = fInfoMap.begin();
	for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++)
		_DestroyInstantiatedFlavors(iterator->second);

	BMediaRoster::CurrentRoster()->Lock();
	BMediaRoster::CurrentRoster()->Quit();
				
	for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++)
		_PutAddonIfPossible(iterator->second);

	return true;
}
Пример #10
0
void ChannelEditor::SetText(const InfoMap &map)
{
    if (map.contains("callsign"))
        m_callsignEdit->SetText(map.value("callsign"));
    if (map.contains("channum"))
        m_channumEdit->SetText(map.value("channum"));
    if (map.contains("channame"))
        m_channameEdit->SetText(map.value("channame"));
    if (map.contains("XMLTV"))
        m_xmltvidEdit->SetText(map.value("XMLTV"));
}
Пример #11
0
 /**
 * \brief Show and update the edit mode On Screen Display. The cut regions
 *        are only refreshed if the deleteMap has been updated.
 */
void DeleteMap::UpdateOSD(uint64_t frame, double frame_rate, OSD *osd)
{
    if (!osd || !m_ctx)
        return;
    CleanMap();

    InfoMap infoMap;
    m_ctx->LockPlayingInfo(__FILE__, __LINE__);
    if (m_ctx->playingInfo)
        m_ctx->playingInfo->ToMap(infoMap);
    infoMap.detach();
    m_ctx->UnlockPlayingInfo(__FILE__, __LINE__);

    QString cutmarker = " ";
    if (IsInDelete(frame))
        cutmarker = tr("cut");

    uint64_t total = m_ctx->player->GetTotalFrameCount();
    QString timestr = CreateTimeString(frame, false, frame_rate, true);
    QString relTimeDisplay;
    relTimeDisplay = CreateTimeString(frame, true, frame_rate, false);
    QString relLengthDisplay;
    relLengthDisplay = CreateTimeString(total, true, frame_rate, false);
    infoMap["timedisplay"]  = timestr;
    infoMap["framedisplay"] = QString::number(frame);
    infoMap["cutindicator"] = cutmarker;
    infoMap["title"]        = tr("Edit");
    infoMap["seekamount"]   = m_seekText;;
    infoMap["reltimedisplay"] = relTimeDisplay;
    infoMap["rellengthdisplay"] = relLengthDisplay;
    //: example: "13:24 (10:23 of 24:37)"
    infoMap["fulltimedisplay"] = tr("%3 (%1 of %2)").arg(relTimeDisplay)
        .arg(relLengthDisplay).arg(timestr);

    QHash<QString,float> posMap;
    posMap.insert("position", (float)((double)frame/(double)total));
    osd->SetValues("osd_program_editor", posMap, kOSDTimeout_None);
    osd->SetText("osd_program_editor", infoMap,  kOSDTimeout_None);
    if (m_changed || total != m_cachedTotalForOSD)
        osd->SetRegions("osd_program_editor", m_deleteMap, total);
    m_changed = false;
    m_cachedTotalForOSD = total;
}
Пример #12
0
    inline
    int UserInfoCache::updateUserInfo(int userId, UserInfo *userInfo)
    {
        int ret = 1;
//..
// Although we intend to update the information, we first acquire a *read*
// *lock* to locate the item.  This allows other threads to read the list while
// we find the item.  If we do not locate the item we can simply release the
// *read* *lock* and return an error without causing any other *reading* thread
// to block.  (Again, other writers *will* block until this *read* *lock* is
// released.)
//..
        d_lock.lockRead();
        InfoMap::iterator it = d_infoMap.find(userId);
        if (d_infoMap.end() != it) {
//..
// Since 'it != end()', we found the item.  Now we need to upgrade to a *write*
// *lock*.  If we can't do this atomically, then we need to locate the item
// again.  This is because another thread may have changed 'd_infoMap' during
// the time between our *read* and *write* locks.
//..
            if (d_lock.upgradeToWriteLock()) {
                it = d_infoMap.find(userId);
            }
//..
// This is a little more costly, but since we don't expect many concurrent
// writes, it should not happen often.  In the (likely) event that we do
// upgrade to a *write* *lock* atomically, then the second lookup above is not
// performed.  In any case, we can now update the information and release the
// lock, since we already have a pointer to the item and we know that the list
// could not have been changed by anyone else.
//..
            if (d_infoMap.end() != it) {
                it->second = *userInfo;
                ret = 0;
            }
            d_lock.unlock();
        }
        else {
            d_lock.unlock();
        }
        return ret;
    }
Пример #13
0
static void DeserializeMetadata(const std::string& document, CAddonBuilder& builder)
{
  CVariant variant;
  if (!CJSONVariantParser::Parse(document, variant))
    return;

  builder.SetAuthor(variant["author"].asString());
  builder.SetDisclaimer(variant["disclaimer"].asString());
  builder.SetBroken(variant["broken"].asString());
  builder.SetPackageSize(variant["size"].asUnsignedInteger());

  builder.SetPath(variant["path"].asString());
  builder.SetIcon(variant["icon"].asString());

  std::map<std::string, std::string> art;
  for (auto it = variant["art"].begin_map(); it != variant["art"].end_map(); ++it)
    art.emplace(it->first, it->second.asString());
  builder.SetArt(std::move(art));

  std::vector<std::string> screenshots;
  for (auto it = variant["screenshots"].begin_array(); it != variant["screenshots"].end_array(); ++it)
    screenshots.push_back(it->asString());
  builder.SetScreenshots(std::move(screenshots));

  builder.SetType(CAddonInfo::TranslateType(variant["extensions"][0].asString()));

  {
    std::vector<DependencyInfo> deps;
    for (auto it = variant["dependencies"].begin_array(); it != variant["dependencies"].end_array(); ++it)
    {
      deps.emplace_back(
          (*it)["addonId"].asString(),
          AddonVersion((*it)["version"].asString()),
          (*it)["optional"].asBoolean());
    }
    builder.SetDependencies(std::move(deps));
  }

  InfoMap extraInfo;
  for (auto it = variant["extrainfo"].begin_array(); it != variant["extrainfo"].end_array(); ++it)
    extraInfo.emplace((*it)["key"].asString(), (*it)["value"].asString());
  builder.SetExtrainfo(std::move(extraInfo));
}
Пример #14
0
 inline
 int UserInfoCache::addUserInfo(int userId, UserInfo *userInfo)
 {
     d_lock.lockRead();
     bool found = !! d_infoMap.count(userId);
     if (! found) {
         if (d_lock.upgradeToWriteLock()) {
             found = !! d_infoMap.count(userId);
         }
         if (! found) {
             d_infoMap[userId] = *userInfo;
         }
         d_lock.unlock();
     }
     else {
         d_lock.unlock();
     }
     return found ? 1 : 0;
 }
Пример #15
0
    inline
    int UserInfoCache::getUserInfo(int userId, UserInfo *userInfo)
    {
        int ret = 1;
//..
// Getting the user info does not require any write access.  We do, however,
// need read access to 'd_infoMap', which is controlled by 'd_lock'.  (Note
// that writers *will* block until this *read* *lock* is released, but
// concurrent reads are allowed.)  The user info is copied into the
// caller-owned location 'userInfo'.
//..
        d_lock.lockRead();
        InfoMap::iterator it = d_infoMap.find(userId);
        if (d_infoMap.end() != it) {
            *userInfo = it->second;
            ret = 0;
        }
        d_lock.unlock();
        return ret;
    }
Пример #16
0
void
MediaAddonServer::_AddOnRemoved(ino_t fileNode)
{
	// TODO: locking?

	FileMap::iterator foundFile = fFileMap.find(fileNode);
	if (foundFile == fFileMap.end()) {
		ERROR("MediaAddonServer::_AddOnRemoved: inode %Ld removed, but no "
			"media add-on found\n", fileNode);
		return;
	}

	media_addon_id id = foundFile->second;
	fFileMap.erase(foundFile);

	int32 oldFlavorCount;
	InfoMap::iterator foundInfo = fInfoMap.find(id);

	if (foundInfo == fInfoMap.end()) {
		ERROR("MediaAddonServer::_AddOnRemoved: couldn't get addon info for "
			"add-on %ld\n", id);
		oldFlavorCount = 1000;
	} else {
		AddOnInfo& info = foundInfo->second;
		oldFlavorCount = info.flavor_count;

		_DestroyInstantiatedFlavors(info);
		_PutAddonIfPossible(info);

		if (info.addon) {
			ERROR("MediaAddonServer::_AddOnRemoved: couldn't unload addon "
				"%ld since flavors are in use\n", id);
		}

		fInfoMap.erase(foundInfo);
	}

	gDormantNodeManager->UnregisterAddOn(id);

	BPrivate::media::notifications::FlavorsChanged(id, 0, oldFlavorCount);
}
Пример #17
0
void MythUIText::ResetMap(const InfoMap &map)
{
    QString newText = GetTemplateText();

    if (newText.isEmpty())
        newText = GetDefaultText();

    QRegExp regexp("%(([^\\|%]+)?\\||\\|(.))?([\\w#]+)(\\|(.+))?%");
    regexp.setMinimal(true);

    bool replaced = map.contains(objectName());

    if (!replaced && !newText.isEmpty() && newText.contains(regexp))
    {
        int pos = 0;

        QString translatedTemplate = qApp->translate("ThemeUI",
                                                     newText.toUtf8());

        while ((pos = regexp.indexIn(translatedTemplate, pos)) != -1)
        {
            QString key = regexp.cap(4).toLower().trimmed();

            if (map.contains(key))
            {
                replaced = true;
                break;
            }
            pos += regexp.matchedLength();
        }
    }

    if (replaced)
    {
        Reset();
    }
}
Пример #18
0
void MythUIText::SetTextFromMap(const InfoMap &map)
{
    QString newText = GetTemplateText();

    if (newText.isEmpty())
        newText = GetDefaultText();

    QRegExp regexp("%(([^\\|%]+)?\\||\\|(.))?([\\w#]+)(\\|(.+))?%");
    regexp.setMinimal(true);

    if (!newText.isEmpty() && newText.contains(regexp))
    {
        int pos = 0;

        QString translatedTemplate = qApp->translate("ThemeUI",
                                                     newText.toUtf8());

        QString tempString = translatedTemplate;
        bool replaced = map.contains(objectName());

        while ((pos = regexp.indexIn(translatedTemplate, pos)) != -1)
        {
            QString key = regexp.cap(4).toLower().trimmed();
            QString replacement;

            if (map.contains(key))
            {
                replaced = true;
            }
            if (!map.value(key).isEmpty())
            {
                replacement = QString("%1%2%3%4")
                .arg(regexp.cap(2))
                .arg(regexp.cap(3))
                .arg(map.value(key))
                .arg(regexp.cap(6));
            }

            tempString.replace(regexp.cap(0), replacement);
            pos += regexp.matchedLength();
        }
        if (replaced)
        {
            SetText(tempString);
        }
    }
    else if (map.contains(objectName()))
    {
        SetText(map.value(objectName()));
    }
}
Пример #19
0
void
MediaAddonServer::_AddOnAdded(const char* path, ino_t fileNode)
{
	TRACE("\n\nMediaAddonServer::_AddOnAdded: path %s\n", path);

	media_addon_id id = gDormantNodeManager->RegisterAddOn(path);
	if (id <= 0) {
		ERROR("MediaAddonServer::_AddOnAdded: failed to register add-on %s\n",
			path);
		return;
	}

	TRACE("MediaAddonServer::_AddOnAdded: loading addon %ld now...\n", id);

	BMediaAddOn* addon = gDormantNodeManager->GetAddOn(id);
	if (addon == NULL) {
		ERROR("MediaAddonServer::_AddOnAdded: failed to get add-on %s\n", path);
		gDormantNodeManager->UnregisterAddOn(id);
		return;
	}

	TRACE("MediaAddonServer::_AddOnAdded: loading finished, id %ld\n", id);

	try {
		// put file's inode and addon's id into map
		fFileMap.insert(std::make_pair(fileNode, id));

		AddOnInfo info;
		fInfoMap.insert(std::make_pair(id, info));
	} catch (std::bad_alloc& exception) {
		fFileMap.erase(fileNode);
		return;
	}

	InfoMap::iterator found = fInfoMap.find(id);
	AddOnInfo& info = found->second;

	info.id = id;
	info.wants_autostart = false; // temporary default
	info.flavor_count = 0;
	info.addon = addon;

	// scan the flavors
	_ScanAddOnFlavors(addon);

	// need to call BMediaNode::WantsAutoStart()
	// after the flavors have been scanned
	info.wants_autostart = addon->WantsAutoStart();

	if (info.wants_autostart)
		TRACE("add-on %ld WantsAutoStart!\n", id);

	// During startup, first all add-ons are loaded, then all
	// nodes (flavors) representing physical inputs and outputs
	// are instantiated. Next, all add-ons that need autostart
	// will be autostarted. Finally, add-ons that don't have
	// any active nodes (flavors) will be unloaded.

	// After startup is done, we simply do it for each new
	// loaded add-on, too.
	if (!fStartup) {
		_InstantiatePhysicalInputsAndOutputs(info);
		_InstantiateAutostartFlavors(info);
		_PutAddonIfPossible(info);

		// since something might have changed
		server_rescan_defaults_command cmd;
		SendToServer(SERVER_RESCAN_DEFAULTS, &cmd, sizeof(cmd));
	}

	// we do not call gDormantNodeManager->PutAddOn(id)
	// since it is done by _PutAddonIfPossible()
}
Пример #20
0
void
MediaAddonServer::_ScanAddOnFlavors(BMediaAddOn* addon)
{
	ASSERT(addon->AddonID() > 0);

	TRACE("MediaAddonServer::_ScanAddOnFlavors: id %ld\n", addon->AddonID());

	// cache the media_addon_id in a local variable to avoid
	// calling BMediaAddOn::AddonID() too often
	media_addon_id addonID = addon->AddonID();

	// update the cached flavor count, get oldflavorcount and newflavorcount

	InfoMap::iterator found = fInfoMap.find(addonID);
	ASSERT(found != fInfoMap.end());

	AddOnInfo& info = found->second;
	int32 oldFlavorCount = info.flavor_count;
	int32 newFlavorCount = addon->CountFlavors();
	info.flavor_count = newFlavorCount;

	TRACE("%ld old flavors, %ld new flavors\n", oldflavorcount, newFlavorCount);

	// during the first update (i == 0), the server removes old dormant_flavor_infos
	for (int i = 0; i < newFlavorCount; i++) {
		const flavor_info* flavorInfo;
		TRACE("flavor %d:\n", i);
		if (addon->GetFlavorAt(i, &flavorInfo) != B_OK) {
			ERROR("MediaAddonServer::_ScanAddOnFlavors GetFlavorAt failed for "
				"index %d!\n", i);
			continue;
		}

#if DEBUG >= 2
		DumpFlavorInfo(flavorInfo);
#endif

		dormant_flavor_info dormantFlavorInfo;
		dormantFlavorInfo = *flavorInfo;
		dormantFlavorInfo.node_info.addon = addonID;
		dormantFlavorInfo.node_info.flavor_id = flavorInfo->internal_id;
		strlcpy(dormantFlavorInfo.node_info.name, flavorInfo->name,
			B_MEDIA_NAME_LENGTH);

		size_t flattenedSize = dormantFlavorInfo.FlattenedSize();
		size_t messageSize = flattenedSize
			+ sizeof(server_register_dormant_node_command);
		server_register_dormant_node_command* message
			= (server_register_dormant_node_command*)malloc(messageSize);
		if (message == NULL)
			break;

		// The server should remove previously registered "dormant_flavor_info"s
		// during the first update, but after  the first iteration, we don't
		// want the server to anymore remove old dormant_flavor_infos
		message->purge_id = i == 0 ? addonID : 0;

		message->type = dormantFlavorInfo.TypeCode();
		message->flattened_size = flattenedSize;
		dormantFlavorInfo.Flatten(message->flattened_data, flattenedSize);

		status_t status = SendToServer(SERVER_REGISTER_DORMANT_NODE,
			message, messageSize);
		if (status != B_OK) {
			ERROR("MediaAddonServer::_ScanAddOnFlavors: couldn't register "
				"dormant node: %s\n", strerror(status));
		}

		free(message);
	}

	// TODO: we currently pretend that all old flavors have been removed, this
	// could probably be done in a smarter way
	BPrivate::media::notifications::FlavorsChanged(addonID, newFlavorCount,
		oldFlavorCount);
}
Пример #21
0
/** \fn     GalleryWidget::ShowFileDetails()
 *  \brief  Shows the available details of the current image file.
            The details will only be shown if the file is an image.
 *  \return void
 */
void GalleryWidget::ShowFileDetails()
{
    ImageMetadata *im = m_fileDataList->at(m_index);
    if (!im)
    {
        delete im;
        return;
    }

    if (im->m_type != kImageFile)
    {
        delete im;
        return;
    }

    // First remove all entries
    m_infoList->Reset();

    // This map holds all the exif tag values
    QMap<QString, QString> infoList;

    // Get all the available exif header information from the file
    // and create a data structure that can be displayed nicely
    QByteArray ba = m_fh->GetExifValues(im);
    if (ba.count() > 0)
    {
        bool readTagValues = false;
        QString key, value;

        QXmlStreamReader xml(ba);
        while (!xml.atEnd())
        {
            xml.readNext();

            // Read the general information
            if (xml.isStartElement() &&
                    (xml.name() == "Count"  ||
                     xml.name() == "File"   ||
                     xml.name() == "Path"   ||
                     xml.name() == "Size"   ||
                     xml.name() == "Extension"))
                infoList.insert(xml.name().toString(), xml.readElementText());

            if (xml.isStartElement() && xml.name() == "ImageMetadataInfo")
                readTagValues = true;

            if (readTagValues)
            {
                if (xml.isStartElement() && xml.name() == "Label")
                    key = xml.readElementText();

                if (xml.isStartElement() && xml.name() == "Value")
                    value = xml.readElementText();
            }

            if (xml.isEndElement() && xml.name() == "ImageMetadataInfo")
            {
                readTagValues = false;
                infoList.insert(key, value);
            }
        }
    }

    // Now go through the info list and create a map for the mythui buttonlist
    QMap<QString, QString>::const_iterator i = infoList.constBegin();
    while (i != infoList.constEnd())
    {
        MythUIButtonListItem *item = new MythUIButtonListItem(m_infoList, "");
        InfoMap infoMap;
        infoMap.insert("name", i.key());

        QString value = tr("Not defined");
        if (!i.value().isEmpty())
            value = i.value();

        infoMap.insert("value", value);

        item->SetTextFromMap(infoMap);

        ++i;
    }

    m_infoList->SetVisible(true);

    // All widgets are visible, remember this
    m_infoVisible = true;
    SetFocusWidget(m_infoList);

    delete im;
}
Пример #22
0
void
MediaAddonServer::ReadyToRun()
{
	if (!be_roster->IsRunning("application/x-vnd.Be.media-server")) {
		// the media server is not running, let's quit
		fprintf(stderr, "The media_server is not running!\n");
		Quit();
		return;
	}

	// the control thread is already running at this point,
	// so we can talk to the media server and also receive
	// commands for instantiation

	ASSERT(fStartup == true);

	// The very first thing to do is to create the system time source,
	// register it with the server, and make it the default SYSTEM_TIME_SOURCE
	BMediaNode *timeSource = new SystemTimeSource;
	status_t result = fMediaRoster->RegisterNode(timeSource);
	if (result != B_OK) {
		fprintf(stderr, "Can't register system time source : %s\n",
			strerror(result));
		debugger("Can't register system time source");
	}

	if (timeSource->ID() != NODE_SYSTEM_TIMESOURCE_ID)
		debugger("System time source got wrong node ID");
	media_node node = timeSource->Node();
	result = MediaRosterEx(fMediaRoster)->SetNode(SYSTEM_TIME_SOURCE, &node);
	if (result != B_OK)
		debugger("Can't setup system time source as default");

	// During startup, first all add-ons are loaded, then all
	// nodes (flavors) representing physical inputs and outputs
	// are instantiated. Next, all add-ons that need autostart
	// will be autostarted. Finally, add-ons that don't have
	// any active nodes (flavors) will be unloaded.

	char parameter[32];
	size_t parameterLength = sizeof(parameter);
	bool safeMode = false;
	if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, parameter,
			&parameterLength) == B_OK) {
		if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on")
			|| !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes")
			|| !strcasecmp(parameter, "enable") || !strcmp(parameter, "1"))
			safeMode = true;
	}

	fMonitorHandler = new MonitorHandler(this);
	AddHandler(fMonitorHandler);

	BMessage pulse(B_PULSE);
	fPulseRunner = new BMessageRunner(fMonitorHandler, &pulse, 1000000LL);
		// the monitor handler needs a pulse to check if add-ons are ready

	// load dormant media nodes
	const directory_which directories[] = {
		B_USER_ADDONS_DIRECTORY,
		B_COMMON_ADDONS_DIRECTORY,
		B_SYSTEM_ADDONS_DIRECTORY
	};

	// when safemode, only B_SYSTEM_ADDONS_DIRECTORY is used
	for (uint32 i = safeMode ? 2 : 0;
			i < sizeof(directories) / sizeof(directory_which); i++) {
		BDirectory directory;
		node_ref nodeRef;
		BPath path;
		if (find_directory(directories[i], &path) == B_OK
			&& path.Append("media") == B_OK
			&& directory.SetTo(path.Path()) == B_OK
			&& directory.GetNodeRef(&nodeRef) == B_OK)
			fMonitorHandler->AddDirectory(&nodeRef);
	}

#ifdef USER_ADDON_PATH
	node_ref nodeRef;
	if (entry.SetTo(USER_ADDON_PATH) == B_OK
		&& entry.GetNodeRef(&nodeRef) == B_OK)
		fMonitorHandler->AddDirectory(&nodeRef);
#endif

	fStartup = false;

	InfoMap::iterator iterator = fInfoMap.begin();
	for (; iterator != fInfoMap.end(); iterator++)
		_InstantiatePhysicalInputsAndOutputs(iterator->second);

	for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++)
		_InstantiateAutostartFlavors(iterator->second);

	for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++)
		_PutAddonIfPossible(iterator->second);

	server_rescan_defaults_command cmd;
	SendToServer(SERVER_RESCAN_DEFAULTS, &cmd, sizeof(cmd));
}
Пример #23
0
bool UPNPSubscription::ProcessRequest(HTTPRequest *pRequest)
{
    if (!pRequest)
        return false;

    if (pRequest->m_sBaseUrl != "/Subscriptions")
        return false;
    if (pRequest->m_sMethod != "event")
        return false;

    LOG(VB_UPNP, LOG_DEBUG, LOC + QString("%1\n%2")
        .arg(pRequest->m_sRawRequest).arg(pRequest->m_sPayload));

    if (pRequest->m_sPayload.isEmpty())
        return true;

    pRequest->m_eResponseType = ResponseTypeHTML;

    QString nt  = pRequest->m_mapHeaders["nt"];
    QString nts = pRequest->m_mapHeaders["nts"];
    bool    no  = (pRequest->m_eType == RequestTypeNotify);

    if (nt.isEmpty() || nts.isEmpty() || !no)
    {
        pRequest->m_nResponseStatus = 400;
        return true;
    }

    pRequest->m_nResponseStatus = 412;
    if (nt != "upnp:event" || nts != "upnp:propchange")
        return true;

    QString usn = pRequest->m_mapParams["usn"];
    QString sid = pRequest->m_mapHeaders["sid"];
    if (usn.isEmpty() || sid.isEmpty())
        return true;

    // N.B. Validating the usn and uuid here might mean blocking for some time
    // while waiting for a subscription to complete. While this operates in a
    // worker thread, worker threads are a limited resource which we could
    // rapidly overload if a number of events arrive. Instead let the
    // subscribing objects validate the usn - the uuid should be superfluous.

    QString seq = pRequest->m_mapHeaders["seq"];

    // mediatomb sends some extra character(s) at the end of the payload
    // which throw Qt, so try and trim them off
    int loc = pRequest->m_sPayload.lastIndexOf("propertyset>");
    QString payload = (loc > -1) ? pRequest->m_sPayload.left(loc + 12) :
                                   pRequest->m_sPayload;

    LOG(VB_UPNP, LOG_DEBUG, LOC + QString("Payload:\n%1").arg(payload));

    pRequest->m_nResponseStatus = 400;
    QDomDocument body;
    QString error;
    int errorCol = 0;
    int errorLine = 0;
    if (!body.setContent(payload, true, &error, &errorLine, &errorCol))
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + 
            QString("Failed to parse event: Line: %1 Col: %2 Error: '%3'")
                .arg(errorLine).arg(errorCol).arg(error));
        return true;
    }

    LOG(VB_UPNP, LOG_DEBUG, LOC + "/n/n" + body.toString(4) + "/n/n");

    QDomNodeList properties = body.elementsByTagName("property");
    InfoMap results;

    // this deals with both one argument per property (compliant) and mutliple
    // arguments per property as sent by mediatomb
    for (int i = 0; i < properties.size(); i++)
    {
        QDomNodeList arguments = properties.at(i).childNodes();
        for (int j = 0; j < arguments.size(); j++)
        {
            QDomElement e = arguments.at(j).toElement();
            if (!e.isNull() && !e.text().isEmpty() && !e.tagName().isEmpty())
                results.insert(e.tagName(), e.text());
        }
    }

    // using MythObservable allows multiple objects to subscribe to the same
    // service but is less efficient from an eventing perspective, especially
    // if multiple objects are subscribing
    if (!results.isEmpty())
    {
        pRequest->m_nResponseStatus = 200;
        results.insert("usn", usn);
        results.insert("seq", seq);
        MythInfoMapEvent me("UPNP_EVENT", results);
        dispatch(me);
    }

    return true;
}
Пример #24
0
bool CAddonDatabase::GetRepositoryContent(const std::string& repoId, VECADDONS& addons)
{
  try
  {
    if (NULL == m_pDB.get()) return false;
    if (NULL == m_pDS.get()) return false;

    auto start = XbmcThreads::SystemClockMillis();

    std::string commonConstraint = PrepareSQL(
        "JOIN addonlinkrepo ON addon.id=addonlinkrepo.idAddon "
        "JOIN repo ON addonlinkrepo.idRepo=repo.id "
        "WHERE repo.checksum IS NOT NULL AND repo.checksum != ''");

    if (!repoId.empty())
      commonConstraint += PrepareSQL(" AND repo.addonId='%s'", repoId.c_str());

    commonConstraint += PrepareSQL(" ORDER BY addon.addonID");

    std::vector<CAddonBuilder> result;
    // Read basic info from the `addon` table
    {
      std::string sql = PrepareSQL("SELECT addon.*, broken.reason FROM addon "
          "LEFT JOIN broken ON broken.addonID=addon.addonID ") + commonConstraint;
      auto start = XbmcThreads::SystemClockMillis();
      m_pDS->query(sql);
      CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(),
          m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start);

      while (!m_pDS->eof())
      {
        std::string addonId = m_pDS->fv(addon_addonID).get_asString();
        AddonVersion version(m_pDS->fv(addon_version).get_asString());

        if (!result.empty() && result.back().GetId() == addonId && result.back().GetVersion() >= version)
        {
          // We already have a version of this addon in our list which is newer.
          m_pDS->next();
          continue;
        }

        CAddonBuilder builder;
        builder.SetId(addonId);
        builder.SetVersion(version);
        builder.SetType(TranslateType(m_pDS->fv(addon_type).get_asString()));
        builder.SetMinVersion(AddonVersion(m_pDS->fv(addon_minversion).get_asString()));
        builder.SetName(m_pDS->fv(addon_name).get_asString());
        builder.SetSummary(m_pDS->fv(addon_summary).get_asString());
        builder.SetDescription(m_pDS->fv(addon_description).get_asString());
        builder.SetChangelog(m_pDS->fv(addon_changelog).get_asString());
        builder.SetDisclaimer(m_pDS->fv(addon_disclaimer).get_asString());
        builder.SetAuthor(m_pDS->fv(addon_author).get_asString());
        builder.SetPath(m_pDS->fv(addon_path).get_asString());
        builder.SetIcon(m_pDS->fv(addon_icon).get_asString());
        builder.SetFanart(m_pDS->fv(addon_fanart).get_asString());
        builder.SetBroken(m_pDS->fv(broken_reason).get_asString());
        if (!result.empty() && result.back().GetId() == addonId)
          result.back() = std::move(builder);
        else
          result.push_back(std::move(builder));
        m_pDS->next();
      }
    }

    // Read extra info.
    {
      std::string sql = PrepareSQL(
          "SELECT addon.addonID as owner, addonextra.key, addonextra.value "
          "FROM addon JOIN addonextra ON addon.id=addonextra.id ") + commonConstraint;

      auto start = XbmcThreads::SystemClockMillis();
      m_pDS->query(sql);
      CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(),
          m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start);

      for (auto& builder : result)
      {
        //move cursor to current or next addon
        while (!m_pDS->eof() && m_pDS->fv(0).get_asString() < builder.GetId())
          m_pDS->next();

        InfoMap extraInfo;
        while (!m_pDS->eof() && m_pDS->fv(0).get_asString() == builder.GetId())
        {
          extraInfo.emplace(m_pDS->fv(1).get_asString(), m_pDS->fv(2).get_asString());
          m_pDS->next();
        }
        builder.SetExtrainfo(std::move(extraInfo));
      }
    }

    // Read dependency info.
    {
      std::string sql = PrepareSQL(
          "SELECT addon.addonID as owner, dependencies.addon, dependencies.version, dependencies.optional "
          "FROM addon JOIN dependencies ON addon.id=dependencies.id ") + commonConstraint;

      auto start = XbmcThreads::SystemClockMillis();
      m_pDS->query(sql);
      CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(),
          m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start);

      for (auto& builder : result)
      {
        //move cursor to the current or next addon
        while (!m_pDS->eof() && m_pDS->fv(0).get_asString() < builder.GetId())
          m_pDS->next();

        ADDONDEPS dependencies;
        while (!m_pDS->eof() && m_pDS->fv(0).get_asString() == builder.GetId())
        {
          dependencies.emplace(m_pDS->fv(1).get_asString(),
              std::make_pair(AddonVersion(m_pDS->fv(2).get_asString()), m_pDS->fv(3).get_asBool()));
          m_pDS->next();
        }
        builder.SetDependencies(std::move(dependencies));
      }
    }
    m_pDS->close();

    for (auto& builder : result)
    {
      auto addon = builder.Build();
      if (addon)
        addons.push_back(std::move(addon));
    }

    CLog::Log(LOGDEBUG, "CAddonDatabase::GetAddons took %i ms", XbmcThreads::SystemClockMillis() - start);
    return true;
  }
  catch (...)
  {
    CLog::Log(LOGERROR, "%s failed", __FUNCTION__);
  }
  return false;
}
Пример #25
0
bool CAddonDatabase::GetAddon(int id, AddonPtr &addon)
{
  try
  {
    if (NULL == m_pDB.get()) return false;
    if (NULL == m_pDS2.get()) return false;

    std::string sql = "SELECT addon.*,"
                      "       broken.reason,"
                      "       addonextra.key, addonextra.value,"
                      "       dependencies.addon, dependencies.version, dependencies.optional"
                      "  FROM addon"
                      "    LEFT JOIN broken"
                      "      ON broken.addonID = addon.addonID"
                      "    LEFT JOIN addonextra"
                      "      ON addonextra.id = addon.id"
                      "    LEFT JOIN dependencies"
                      "      ON dependencies.id = addon.id";

    sql += PrepareSQL(" WHERE addon.id=%i", id);

    m_pDS2->query(sql);
    if (!m_pDS2->eof())
    {
      const dbiplus::query_data &data = m_pDS2->get_result_set().records;
      const dbiplus::sql_record* const record = data[0];

      CAddonBuilder builder;
      builder.SetId(record->at(addon_addonID).get_asString());
      builder.SetType(TranslateType(record->at(addon_type).get_asString()));
      builder.SetVersion(AddonVersion(record->at(addon_version).get_asString()));
      builder.SetMinVersion(AddonVersion(record->at(addon_minversion).get_asString()));
      builder.SetName(record->at(addon_name).get_asString());
      builder.SetSummary(record->at(addon_summary).get_asString());
      builder.SetDescription(record->at(addon_description).get_asString());
      builder.SetChangelog(record->at(addon_changelog).get_asString());
      builder.SetDisclaimer(record->at(addon_disclaimer).get_asString());
      builder.SetAuthor(record->at(addon_author).get_asString());
      builder.SetBroken(record->at(broken_reason).get_asString());
      builder.SetPath(record->at(addon_path).get_asString());
      builder.SetIcon(record->at(addon_icon).get_asString());
      builder.SetFanart(record->at(addon_fanart).get_asString());

      InfoMap extrainfo;
      ADDONDEPS dependencies;
      /* while this is a cartesion join and we'll typically get multiple rows, we rely on the fact that
         extrainfo and dependencies are maps, so insert() will insert the first instance only */
      for (dbiplus::query_data::const_iterator i = data.begin(); i != data.end(); ++i)
      {
        const dbiplus::sql_record* const record = *i;
        if (!record->at(addonextra_key).get_asString().empty())
          extrainfo.insert(std::make_pair(record->at(addonextra_key).get_asString(), record->at(addonextra_value).get_asString()));
        if (!m_pDS2->fv(dependencies_addon).get_asString().empty())
          dependencies.insert(std::make_pair(record->at(dependencies_addon).get_asString(), std::make_pair(AddonVersion(record->at(dependencies_version).get_asString()), record->at(dependencies_optional).get_asBool())));
      }
      builder.SetExtrainfo(std::move(extrainfo));
      builder.SetDependencies(std::move(dependencies));

      addon = builder.Build();
      return NULL != addon.get();
    }
  }
  catch (...)
  {
    CLog::Log(LOGERROR, "%s failed on addon %i", __FUNCTION__, id);
  }
  addon.reset();
  return false;
}
Пример #26
0
/*
==================
SV_DirectConnect

A "connect" OOB command has been received
==================
*/
void SV_DirectConnect( netadr_t from, const Cmd::Args& args )
{
	if ( args.Argc() < 2 )
	{
		return;
	}

	Log::Debug( "SVC_DirectConnect ()" );

	InfoMap userinfo = InfoStringToMap(args.Argv(1));

	// DHM - Nerve :: Update Server allows any protocol to connect
	// NOTE TTimo: but we might need to store the protocol around for potential non http/ftp clients
	int version = atoi( userinfo["protocol"].c_str() );

	if ( version != PROTOCOL_VERSION )
	{
		Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\nServer uses protocol version %i (yours is %i).", PROTOCOL_VERSION, version );
		Log::Debug( "    rejected connect from version %i", version );
		return;
	}

	int qport = atoi( userinfo["qport"].c_str() );

	auto clients_begin = svs.clients;
	auto clients_end = clients_begin + sv_maxclients->integer;

	client_t* reconnecting = std::find_if(clients_begin, clients_end,
		[&from, qport](const client_t& client)
		{
			return NET_CompareBaseAdr( from, client.netchan.remoteAddress )
		     && ( client.netchan.qport == qport || from.port == client.netchan.remoteAddress.port );
		}
	);

	if ( reconnecting != clients_end &&
		svs.time - reconnecting->lastConnectTime < sv_reconnectlimit->integer * 1000 )
	{
		Log::Debug( "%s: reconnect rejected: too soon", NET_AdrToString( from ) );
		return;
	}


	if ( NET_IsLocalAddress( from ) )
	{
		userinfo["ip"] = "loopback";
	}
	else
	{
		// see if the challenge is valid (local clients don't need to challenge)
		Challenge::Duration ping_duration;
		if ( !ChallengeManager::MatchString( from, userinfo["challenge"], &ping_duration ) )
		{
			Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\n[err_dialog]No or bad challenge for address." );
			return;
		}

		userinfo["ip"] = NET_AdrToString( from );
	}

	client_t *new_client = nullptr;

	// if there is already a slot for this IP address, reuse it
	if ( reconnecting != clients_end )
	{
		Log::Notice( "%s:reconnect\n", NET_AdrToString( from ) );
		new_client = reconnecting;
	}
	else
	{
		// find a client slot
		// if "sv_privateClients" is set > 0, then that number
		// of client slots will be reserved for connections that
		// have "password" set to the value of "sv_privatePassword"
		// Info requests will report the maxclients as if the private
		// slots didn't exist, to prevent people from trying to connect
		// to a full server.
		// This is to allow us to reserve a couple slots here on our
		// servers so we can play without having to kick people.
		// check for privateClient password

		int startIndex = 0;
		if ( userinfo["password"] != sv_privatePassword->string )
		{
			// skip past the reserved slots
			startIndex = sv_privateClients->integer;
		}

		new_client = std::find_if(clients_begin, clients_end,
			[](const client_t& client) {
				return client.state == clientState_t::CS_FREE;
		});

		if ( new_client == clients_end )
		{
			if ( NET_IsLocalAddress( from ) )
			{
				int count = std::count_if(clients_begin+startIndex, clients_end,
					[](const client_t& client) { return SV_IsBot(&client); }
				);

				// if they're all bots
				if ( count >= sv_maxclients->integer - startIndex )
				{
					SV_DropClient( &svs.clients[ sv_maxclients->integer - 1 ], "only bots on server" );
					new_client = &svs.clients[ sv_maxclients->integer - 1 ];
				}
				else
				{
					Com_Error( errorParm_t::ERR_FATAL, "server is full on local connect" );
				}
			}
			else
			{
				Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\n%s", sv_fullmsg->string );
				Log::Debug( "Rejected a connection." );
				return;
			}
		}
	}

	// build a new connection
	// accept the new client
	// this is the only place a client_t is ever initialized
	memset( new_client, 0, sizeof( client_t ) );
	int clientNum = new_client - svs.clients;


#ifdef HAVE_GEOIP
		const char * country = NET_GeoIP_Country( &from );

		if ( country )
		{
			Log::Notice( "Client %i connecting from %s\n", clientNum, country );
			userinfo["geoip"] = country;
		}
		else
		{
			Log::Notice( "Client %i connecting from somewhere unknown\n", clientNum );
		}
#else
		Log::Notice( "Client %i connecting\n", clientNum );
#endif

	new_client->gentity = SV_GentityNum( clientNum );
	new_client->gentity->r.svFlags = 0;

	// save the address
	Netchan_Setup( netsrc_t::NS_SERVER, &new_client->netchan, from, qport );
	// init the netchan queue

	// Save the pubkey
	Q_strncpyz( new_client->pubkey, userinfo["pubkey"].c_str(), sizeof( new_client->pubkey ) );
	userinfo.erase("pubkey");
	// save the userinfo
	Q_strncpyz( new_client->userinfo, InfoMapToString(userinfo).c_str(), sizeof( new_client->userinfo ) );

	// get the game a chance to reject this connection or modify the userinfo
	char reason[ MAX_STRING_CHARS ];
	if ( gvm.GameClientConnect( reason, sizeof( reason ), clientNum, true, false ) )
	{
		Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\n[err_dialog]%s", reason );
		Log::Debug( "Game rejected a connection: %s.", reason );
		return;
	}

	SV_UserinfoChanged( new_client );

	// send the connect packet to the client
	Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "connectResponse" );

	Log::Debug( "Going from CS_FREE to CS_CONNECTED for %s", new_client->name );

	new_client->state = clientState_t::CS_CONNECTED;
	new_client->nextSnapshotTime = svs.time;
	new_client->lastPacketTime = svs.time;
	new_client->lastConnectTime = svs.time;

	// when we receive the first packet from the client, we will
	// notice that it is from a different serverid and that the
	// gamestate message was not just sent, forcing a retransmit
	new_client->gamestateMessageNum = -1;

	// if this was the first client on the server, or the last client
	// the server can hold, send a heartbeat to the master.
	int count = std::count_if(clients_begin, clients_end,
		[](const client_t& client) {
			return client.state >= clientState_t::CS_CONNECTED;
	});

	if ( count == 1 || count == sv_maxclients->integer )
	{
		SV_Heartbeat_f();
	}
}
Пример #27
0
BuildTask *ResourceUnitHandler::GetNewBuildTask ()
{
	// task for metal or energy?
	ResourceManager *rm = globals->resourceManager;
	IAICallback *cb = globals->cb;
	InfoMap *imap = globals->map;

	// check if storage has to be build
	if (rm->averageProd.metal > config.StorageConfig.MinMetalIncome && cb->GetMetal () > cb->GetMetalStorage () * config.StorageConfig.MaxRatio &&
		cb->GetMetalStorage() <= rm->averageProd.metal * config.StorageConfig.MaxMetalFactor)
	{
		BuildTask *t = CreateStorageTask (config.StorageConfig.MetalStorage.front());
		if (t) return t;
	}

	if (rm->averageProd.energy > config.StorageConfig.MinEnergyIncome && cb->GetEnergy () > cb->GetEnergyStorage () * config.StorageConfig.MaxRatio &&
		cb->GetEnergyStorage() <= rm->averageProd.energy * config.StorageConfig.MaxEnergyFactor)
	{
		BuildTask *t = CreateStorageTask (config.StorageConfig.EnergyStorage.front());
		if (t) return t;
	}

	if (rm->buildMultiplier.energy * config.MetalBuildRatio < rm->buildMultiplier.metal * config.EnergyBuildRatio) {
		// pick an energy producing unit to build

        // find the unit type that has the highest energyMake/ResourceValue(buildcost) ratio and
		// does not  with MaxResourceUpscale

		int best = -1;
		float bestRatio;
		float minWind = globals->cb->GetMinWind ();
		float maxWind = globals->cb->GetMaxWind ();

		for (int a=0;a<config.EnergyMakers.size();a++)
		{
			BuildTable::UDef*d = buildTable.GetCachedDef (config.EnergyMakers[a]);

			if (rm->averageProd.energy + d->make.energy > config.EnergyHeuristic.MaxUpscale * rm->averageProd.energy)
				continue;

			// calculate costs based on the heuristic parameters
			float cost = 
				d->buildTime * config.EnergyHeuristic.BuildTime +
				d->cost.metal * config.EnergyHeuristic.MetalCost +
				d->cost.energy * config.EnergyHeuristic.EnergyCost;

			float energyProduction = d->make.energy;

			if (d->flags & CUD_WindGen)
				energyProduction += 0.5f * (minWind + maxWind);

			float ratio = energyProduction / cost;

			if (best < 0 || ratio > bestRatio)
			{
				best = config.EnergyMakers[a];
				bestRatio = ratio;
			}
		}

		if (best >= 0)
			return new BuildTask (buildTable.GetDef (best));
	}
	else {
		// pick a metal producing unit to build
		float3 st (globals->map->baseCenter.x, 0.0f, globals->map->baseCenter.y);

		int best=0;
		float bestScore;
		MetalSpot* bestSpot=0;

		// sector has been found, now calculate the best suitable metal extractor
		for (int a=0;a<config.MetalExtracters.size();a++)
		{
			BuildTable::UDef *d = buildTable.GetCachedDef (config.MetalExtracters[a]);
			const UnitDef* def= buildTable.GetDef (config.MetalExtracters[a]);
			MetalSpotID spotID = globals->metalmap->FindSpot(st, imap, def->extractsMetal);
			if (spotID<0) break;

			MetalSpot* spot = globals->metalmap->GetSpot (spotID);
			if (!spot->metalProduction)
			{
				logPrintf ("Metalmap error: No metal production on spot.\n");
				spot->extractDepth=100;
				break;
			}

			// get threat info
			GameInfo *gi = imap->GetGameInfoFromMapSquare (spot->pos.x,spot->pos.y);
			float metalMake = spot->metalProduction * d->metalExtractDepth;
			float PaybackTime = d->cost.metal + gi->threat * config.MetalHeuristic.ThreatConversionFactor;
			PaybackTime /= metalMake;

			float score = config.MetalHeuristic.PaybackTimeFactor * PaybackTime + 
				d->energyUse * config.MetalHeuristic.EnergyUsageFactor;

			float upscale = 1.0f + metalMake / (1.0f + rm->averageProd.metal);
			if (upscale > config.MetalHeuristic.PrefUpscale)
				score += config.MetalHeuristic.UpscaleOvershootFactor * (upscale - config.MetalHeuristic.PrefUpscale);

			logPrintf ("ResourceUnitHandler: %s has score %f with threat %f\n",def->name.c_str(),score,gi->threat);
			if (!best || bestScore < score)
			{
				bestScore = score;
				best = config.MetalExtracters[a];
				bestSpot=spot;
			}
		}

		// compare the best extractor with the metal makers
		for (int a=0;a<config.MetalMakers.size();a++)
		{
			BuildTable::UDef *d = buildTable.GetCachedDef (config.MetalMakers[a]);

			const UnitDef* def = buildTable.GetDef (config.MetalMakers[a]);

			float PaybackTime = d->cost.metal / d->make.metal;
			float score = config.MetalHeuristic.PaybackTimeFactor * PaybackTime + 
				d->energyUse * config.MetalHeuristic.EnergyUsageFactor;

			// calculate upscale and use it in the score
			if (rm->averageProd.metal>0.0f)
			{
				float upscale = 1.0f + d->make.metal / rm->averageProd.metal;

				if (upscale > config.MetalHeuristic.PrefUpscale)
					score += config.MetalHeuristic.UpscaleOvershootFactor * (upscale - config.MetalHeuristic.PrefUpscale);
			}

			logPrintf ("ResourceUnitHandler: %s has score %f\n",def->name.c_str(),score);
			if (!best || bestScore < score)
			{
				bestScore = score;
				best = config.MetalMakers[a];
			}
		}

		if (best)
		{
			const UnitDef *def = buildTable.GetDef (best);
			Task *task = new Task (def);
			return task;
		}
	}

	return 0;
}
Пример #28
0
void OSD::SetText(const QString &window, const InfoMap &map,
                  OSDTimeout timeout)
{
    MythScreenType *win = GetWindow(window);
    if (!win)
        return;

    if (map.contains("numstars"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("ratingstate"));
        if (state)
            state->DisplayState(map["numstars"]);
    }
    if (map.contains("tvstate"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("tvstate"));
        if (state)
            state->DisplayState(map["tvstate"]);
    }
    if (map.contains("videocodec"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("videocodec"));
        if (state)
            state->DisplayState(map["videocodec"]);
    }
    if (map.contains("videodescrip"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("videodescrip"));
        if (state)
            state->DisplayState(map["videodescrip"]);
    }
    if (map.contains("audiocodec"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("audiocodec"));
        if (state)
            state->DisplayState(map["audiocodec"]);
    }
    if (map.contains("audiochannels"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("audiochannels"));
        if (state)
            state->DisplayState(map["audiochannels"]);
    }
    if (map.contains("chanid"))
    {
        MythUIImage *icon = dynamic_cast<MythUIImage *> (win->GetChild("iconpath"));
        if (icon)
        {
            icon->Reset();

            uint chanid = map["chanid"].toUInt();
            QString iconpath;
            if (map.contains("iconpath"))
                iconpath = map["iconpath"];
            else
                iconpath = ChannelUtil::GetIcon(chanid);

            if (!iconpath.isEmpty())
            {
                QString iconurl =
                                gCoreContext->GetMasterHostPrefix("ChannelIcons",
                                                                  iconpath);

                icon->SetFilename(iconurl);
                icon->Load(false);
            }
        }
    }
    if (map.contains("inetref"))
    {
        MythUIImage *cover = dynamic_cast<MythUIImage *> (win->GetChild("coverart"));
        if (cover && map.contains("coverartpath"))
        {
            QString coverpath = map["coverartpath"];
            cover->SetFilename(coverpath);
            cover->Load(false);
        }
        MythUIImage *fanart = dynamic_cast<MythUIImage *> (win->GetChild("fanart"));
        if (fanart && map.contains("fanartpath"))
        {
            QString fanartpath = map["fanartpath"];
            fanart->SetFilename(fanartpath);
            fanart->Load(false);
        }
        MythUIImage *banner = dynamic_cast<MythUIImage *> (win->GetChild("banner"));
        if (banner && map.contains("bannerpath"))
        {
            QString bannerpath = map["bannerpath"];
            banner->SetFilename(bannerpath);
            banner->Load(false);
        }
        MythUIImage *screenshot = dynamic_cast<MythUIImage *> (win->GetChild("screenshot"));
        if (screenshot && map.contains("screenshotpath"))
        {
            QString screenshotpath = map["screenshotpath"];
            screenshot->SetFilename(screenshotpath);
            screenshot->Load(false);
        }
    }
    if (map.contains("nightmode"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("nightmode"));
        if (state)
            state->DisplayState(map["nightmode"]);
    }
    if (map.contains("mediatype"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("mediatype"));
        if (state)
            state->DisplayState(map["mediatype"]);
    }

    MythUIProgressBar *bar =
        dynamic_cast<MythUIProgressBar *>(win->GetChild("elapsedpercent"));
    if (bar)
    {
        int startts = map["startts"].toInt();
        int endts   = map["endts"].toInt();
        int nowts   = MythDate::current().toTime_t();
        if (startts > nowts)
        {
            bar->SetUsed(0);
        }
        else if (endts < nowts)
        {
            bar->SetUsed(1000);
        }
        else
        {
            int duration = endts - startts;
            if (duration > 0)
                bar->SetUsed(1000 * (nowts - startts) / duration);
            else
                bar->SetUsed(0);
        }
        bar->SetVisible(startts > 0);
        bar->SetStart(0);
        bar->SetTotal(1000);
    }

    win->SetVisible(true);

    if (win == m_Dialog)
    {
        ChannelEditor *edit = dynamic_cast<ChannelEditor*>(m_Dialog);
        if (edit)
            edit->SetText(map);
    }
    else
        win->SetTextFromMap(map);

    SetExpiry(window, timeout);
}