Пример #1
0
/* EntryType::loadEntryTypes
 * Loads all built-in and custom user entry types
 *******************************************************************/
bool EntryType::loadEntryTypes()
{
	EntryDataFormat* fmt_any = EntryDataFormat::anyFormat();

	// Setup unknown type
	etype_unknown.format = fmt_any;
	etype_unknown.icon = "e_unknown";
	etype_unknown.detectable = false;
	etype_unknown.reliability = 0;
	etype_unknown.addToList();

	// Setup folder type
	etype_folder.format = fmt_any;
	etype_folder.icon = "e_folder";
	etype_folder.name = "Folder";
	etype_folder.detectable = false;
	etype_folder.addToList();

	// Setup marker type
	etype_marker.format = fmt_any;
	etype_marker.icon = "e_marker";
	etype_marker.name = "Marker";
	etype_marker.detectable = false;
	etype_marker.category = "";		// No category, markers only appear when 'All' categories shown
	etype_marker.addToList();

	// Setup map marker type
	etype_map.format = fmt_any;
	etype_map.icon = "e_map";
	etype_map.name = "Map Marker";
	etype_map.category = "Maps";	// Should appear with maps
	etype_map.detectable = false;
	etype_map.colour = rgba_t(0, 255, 0);
	etype_map.addToList();

	// -------- READ BUILT-IN TYPES ---------

	// Get builtin entry types from resource archive
	Archive* res_archive = theArchiveManager->programResourceArchive();

	// Check resource archive exists
	if (!res_archive)
	{
		wxLogMessage("Error: No resource archive open!");
		return false;
	}

	// Get entry types directory
	ArchiveTreeNode* et_dir = res_archive->getDir("config/entry_types/");

	// Check it exists
	if (!et_dir)
	{
		wxLogMessage("Error: config/entry_types does not exist in slade.pk3");
		return false;
	}

	// Read in each file in the directory
	bool etypes_read = false;
	for (unsigned a = 0; a < et_dir->numEntries(); a++)
	{
		if (readEntryTypeDefinition(et_dir->getEntry(a)->getMCData()))
			etypes_read = true;
	}

	// Warn if no types were read (this shouldn't happen unless the resource archive is corrupted)
	if (!etypes_read)
		wxLogMessage("Warning: No built-in entry types could be loaded from slade.pk3");

	// -------- READ CUSTOM TYPES ---------

	// If the directory doesn't exist create it
	if (!wxDirExists(appPath("entry_types", DIR_USER)))
		wxMkdir(appPath("entry_types", DIR_USER));

	// Open the custom palettes directory
	wxDir res_dir;
	res_dir.Open(appPath("entry_types", DIR_USER));

	// Go through each file in the directory
	string filename = wxEmptyString;
	bool files = res_dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES);
	while (files)
	{
		// Load file data
		MemChunk mc;
		mc.importFile(res_dir.GetName() + "/" + filename);

		// Parse file
		readEntryTypeDefinition(mc);

		// Next file
		files = res_dir.GetNext(&filename);
	}

	return true;
}
Пример #2
0
/* EntryType::readEntryTypeDefinition
 * Reads in a block of entry type definitions. Returns false if there
 * was a parsing error, true otherwise
 *******************************************************************/
bool EntryType::readEntryTypeDefinition(MemChunk& mc)
{
	// Parse the definition
	Parser p;
	p.parseText(mc);

	// Get entry_types tree
	ParseTreeNode* pt_etypes = (ParseTreeNode*)(p.parseTreeRoot()->getChild("entry_types"));

	// Check it exists
	if (!pt_etypes)
		return false;

	// Go through all parsed types
	for (unsigned a = 0; a < pt_etypes->nChildren(); a++)
	{
		// Get child as ParseTreeNode
		ParseTreeNode* typenode = (ParseTreeNode*)pt_etypes->getChild(a);

		// Create new entry type
		EntryType* ntype = new EntryType(typenode->getName().Lower());

		// Copy from existing type if inherited
		if (!typenode->getInherit().IsEmpty())
		{
			EntryType* parent_type = EntryType::getType(typenode->getInherit().Lower());

			if (parent_type != EntryType::unknownType())
				parent_type->copyToType(ntype);
			else
				wxLogMessage("Warning: Entry type %s inherits from unknown type %s", CHR(ntype->getId()), CHR(typenode->getInherit()));
		}

		// Go through all parsed fields
		for (unsigned b = 0; b < typenode->nChildren(); b++)
		{
			// Get child as ParseTreeNode
			ParseTreeNode* fieldnode = (ParseTreeNode*)typenode->getChild(b);

			// Process it
			if (S_CMPNOCASE(fieldnode->getName(), "name"))  				// Name field
			{
				ntype->name = fieldnode->getStringValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "detectable"))  		// Detectable field
			{
				ntype->detectable = fieldnode->getBoolValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "export_ext"))  		// Export Extension field
			{
				ntype->extension = fieldnode->getStringValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "format"))  			// Format field
			{
				string format_string = fieldnode->getStringValue();
				ntype->format = EntryDataFormat::getFormat(format_string);

				// Warn if undefined format
				if (ntype->format == EntryDataFormat::anyFormat())
					wxLogMessage("Warning: Entry type %s requires undefined format %s", CHR(ntype->getId()), CHR(format_string));
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "icon"))  			// Icon field
			{
				ntype->icon = fieldnode->getStringValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "editor"))  			// Editor field (to be removed)
			{
				ntype->editor = fieldnode->getStringValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "section"))  		// Section field
			{
				ntype->section = fieldnode->getStringValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "match_ext"))  		// Match Extension field
			{
				for (unsigned v = 0; v < fieldnode->nValues(); v++)
					ntype->match_extension.push_back(fieldnode->getStringValue(v).Lower());
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "match_name"))  		// Match Name field
			{
				for (unsigned v = 0; v < fieldnode->nValues(); v++)
					ntype->match_name.push_back(fieldnode->getStringValue(v).Lower());
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "match_extorname"))  // Match name or extension
			{
				ntype->matchextorname = fieldnode->getBoolValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "size"))  			// Size field
			{
				for (unsigned v = 0; v < fieldnode->nValues(); v++)
					ntype->match_size.push_back(fieldnode->getIntValue(v));
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "min_size"))  		// Min Size field
			{
				ntype->size_limit[0] = fieldnode->getIntValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "max_size"))  		// Max Size field
			{
				ntype->size_limit[1] = fieldnode->getIntValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "size_multiple"))  	// Size Multiple field
			{
				for (unsigned v = 0; v < fieldnode->nValues(); v++)
					ntype->size_multiple.push_back(fieldnode->getIntValue(v));
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "reliability"))  	// Reliability field
			{
				ntype->reliability = fieldnode->getIntValue();
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "match_archive"))  	// Archive field
			{
				for (unsigned v = 0; v < fieldnode->nValues(); v++)
					ntype->match_archive.push_back(fieldnode->getStringValue(v).Lower());
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "extra"))  			// Extra properties
			{
				for (unsigned v = 0; v < fieldnode->nValues(); v++)
					ntype->extra.addFlag(fieldnode->getStringValue(v));
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "category"))  		// Type category
			{
				ntype->category = fieldnode->getStringValue();

				// Add to category list if needed
				bool exists = false;
				for (unsigned b = 0; b < entry_categories.size(); b++)
				{
					if (S_CMPNOCASE(entry_categories[b], ntype->category))
					{
						exists = true;
						break;
					}
				}
				if (!exists) entry_categories.push_back(ntype->category);
			}
			else if (S_CMPNOCASE(fieldnode->getName(), "image_format"))		// Image format hint
				ntype->extra["image_format"] = fieldnode->getStringValue(0);
			else if (S_CMPNOCASE(fieldnode->getName(), "colour"))  			// Colour
			{
				if (fieldnode->nValues() >= 3)
					ntype->colour = rgba_t(fieldnode->getIntValue(0), fieldnode->getIntValue(1), fieldnode->getIntValue(2));
				else
					wxLogMessage("Not enough colour components defined for entry type %s", CHR(ntype->getId()));
			}
			else
			{
				// Unhandled properties can go into 'extra', only their first value is kept
				ntype->extra[fieldnode->getName()] = fieldnode->getStringValue();
			}
		}

		//ntype->dump();
		ntype->addToList();
	}

	return true;
}