void XMLFile::Patch(XMLElement patchElement) { pugi::xml_node root = pugi::xml_node(patchElement.GetNode()); for (pugi::xml_node::iterator patch = root.begin(); patch != root.end(); patch++) { pugi::xml_attribute sel = patch->attribute("sel"); if (sel.empty()) { URHO3D_LOGERROR("XML Patch failed due to node not having a sel attribute."); continue; } // Only select a single node at a time, they can use xpath to select specific ones in multiple otherwise the node set becomes invalid due to changes pugi::xpath_node original = document_->select_single_node(sel.value()); if (!original) { URHO3D_LOGERRORF("XML Patch failed with bad select: %s.", sel.value()); continue; } if (strcmp(patch->name(), "add") == 0) PatchAdd(*patch, original); else if (strcmp(patch->name(), "replace") == 0) PatchReplace(*patch, original); else if (strcmp(patch->name(), "remove") == 0) PatchRemove(original); else URHO3D_LOGERROR("XMLFiles used for patching should only use 'add', 'replace' or 'remove' elements."); } }
void LuaFunction::PushLuaTable(const char* tableName) { assert(numArguments_ >= 0); ++numArguments_; lua_getglobal(luaState_, tableName); if (!lua_istable(luaState_, -1)) URHO3D_LOGERRORF("Could not find lua table %s", tableName); // nil is pushed instead }
XMLElement XPathResultSet::operator [](unsigned index) const { if (!resultSet_) URHO3D_LOGERRORF( "Could not return result at index: %u. Most probably this is caused by the XPathResultSet not being stored in a lhs variable.", index); return resultSet_ && index < Size() ? XMLElement(file_, this, &resultSet_->operator [](index), index) : XMLElement(); }
void Spline::AddKnot(const Variant& knot) { if (knots_.Size() > 0 && knots_[0].GetType() == knot.GetType()) knots_.Push(knot); else if (knots_.Empty()) knots_.Push(knot); else URHO3D_LOGERRORF("Attempted to add Knot to Spline of type %s where elements are already using %s", knot.GetTypeName().CString(), knots_[0].GetTypeName().CString()); }
bool XMLFile::BeginLoad(Deserializer& source) { unsigned dataSize = source.GetSize(); if (!dataSize && !source.GetName().Empty()) { URHO3D_LOGERROR("Zero sized XML data in " + source.GetName()); return false; } SharedArrayPtr<char> buffer(new char[dataSize]); if (source.Read(buffer.Get(), dataSize) != dataSize) return false; if (!document_->load_buffer(buffer.Get(), dataSize)) { URHO3D_LOGERROR("Could not parse XML data from " + source.GetName()); document_->reset(); return false; } XMLElement rootElem = GetRoot(); String inherit = rootElem.GetAttribute("inherit"); if (!inherit.Empty()) { // The existence of this attribute indicates this is an RFC 5261 patch file ResourceCache* cache = GetSubsystem<ResourceCache>(); // If being async loaded, GetResource() is not safe, so use GetTempResource() instead XMLFile* inheritedXMLFile = GetAsyncLoadState() == ASYNC_DONE ? cache->GetResource<XMLFile>(inherit) : cache->GetTempResource<XMLFile>(inherit); if (!inheritedXMLFile) { URHO3D_LOGERRORF("Could not find inherited XML file: %s", inherit.CString()); return false; } // Patch this XMLFile and leave the original inherited XMLFile as it is pugi::xml_document* patchDocument = document_; document_ = new pugi::xml_document(); document_->reset(*inheritedXMLFile->document_); Patch(rootElem); delete patchDocument; // Store resource dependencies so we know when to reload/repatch when the inherited resource changes cache->StoreResourceDependency(this, inherit); // Approximate patched data size dataSize += inheritedXMLFile->GetMemoryUse(); } // Note: this probably does not reflect internal data structure size accurately SetMemoryUse(dataSize); return true; }
void Spline::SetKnot(const Variant& knot, unsigned index) { if (index < knots_.Size()) { if (knots_.Size() > 0 && knots_[0].GetType() == knot.GetType()) knots_[index] = knot; else if (knots_.Empty()) knots_.Push(knot); else URHO3D_LOGERRORF("Attempted to set a Spline's Knot value of type %s where elements are already using %s", knot.GetTypeName().CString(), knots_[0].GetTypeName().CString()); } }
void XMLFile::AddAttribute(const pugi::xml_node& patch, const pugi::xpath_node& original) const { pugi::xml_attribute attribute = patch.attribute("type"); if (!patch.first_child() && patch.first_child().type() != pugi::node_pcdata) { URHO3D_LOGERRORF("XML Patch failed calling Add due to attempting to add non text to an attribute for %s.", attribute.value()); return; } String name(attribute.value()); name = name.Substring(1); pugi::xml_attribute newAttribute = original.node().append_attribute(name.CString()); newAttribute.set_value(patch.child_value()); }
bool LuaFunction::EndCall(int numReturns) { assert(numArguments_ >= 0); int numArguments = numArguments_; numArguments_ = -1; if (lua_pcall(luaState_, numArguments, numReturns, 0) != 0) { const char* message = lua_tostring(luaState_, -1); URHO3D_LOGERRORF("Execute Lua function failed: %s", message); lua_pop(luaState_, 1); return false; } return true; }
void XMLFile::PatchAdd(const pugi::xml_node& patch, pugi::xpath_node& original) const { // If not a node, log an error if (original.attribute()) { URHO3D_LOGERRORF("XML Patch failed calling Add due to not selecting a node, %s attribute was selected.", original.attribute().name()); return; } // If no type add node, if contains '@' treat as attribute pugi::xml_attribute type = patch.attribute("type"); if (!type || strlen(type.value()) <= 0) AddNode(patch, original); else if (type.value()[0] == '@') AddAttribute(patch, original); }
VertexDeclaration::VertexDeclaration(Graphics* graphics, ShaderVariation* vertexShader, VertexBuffer** vertexBuffers, unsigned* elementMasks) : inputLayout_(0) { PODVector<D3D11_INPUT_ELEMENT_DESC> elementDescs; unsigned vbElementMask = 0; for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i) { if (vertexBuffers[i] && elementMasks[i]) { for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j) { if (elementMasks[i] & (1 << j)) { D3D11_INPUT_ELEMENT_DESC newDesc; newDesc.SemanticName = VertexBuffer::elementSemantics[j]; newDesc.SemanticIndex = VertexBuffer::elementSemanticIndices[j]; newDesc.Format = (DXGI_FORMAT)VertexBuffer::elementFormats[j]; newDesc.InputSlot = (UINT)i; newDesc.AlignedByteOffset = vertexBuffers[i]->GetElementOffset((VertexElement)j); newDesc.InputSlotClass = (j >= ELEMENT_INSTANCEMATRIX1 && j <= ELEMENT_INSTANCEMATRIX3) ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; newDesc.InstanceDataStepRate = (j >= ELEMENT_INSTANCEMATRIX1 && j <= ELEMENT_INSTANCEMATRIX3) ? 1 : 0; elementDescs.Push(newDesc); vbElementMask |= 1 << j; } } } } if (elementDescs.Empty()) return; ID3D11InputLayout* d3dInputLayout = 0; const PODVector<unsigned char>& byteCode = vertexShader->GetByteCode(); graphics->GetImpl()->GetDevice()->CreateInputLayout(&elementDescs[0], (UINT)elementDescs.Size(), &byteCode[0], byteCode.Size(), &d3dInputLayout); if (d3dInputLayout) inputLayout_ = d3dInputLayout; else URHO3D_LOGERRORF("Failed to create input layout for shader %s, missing element mask %d", vertexShader->GetFullName().CString(), vertexShader->GetElementMask() & ~vbElementMask); }
void UIComponent::OnElementResized(StringHash eventType, VariantMap& args) { int width = args[Resized::P_WIDTH].GetInt(); int height = args[Resized::P_HEIGHT].GetInt(); if (width < UICOMPONENT_MIN_TEXTURE_SIZE || width > UICOMPONENT_MAX_TEXTURE_SIZE || height < UICOMPONENT_MIN_TEXTURE_SIZE || height > UICOMPONENT_MAX_TEXTURE_SIZE) { URHO3D_LOGERRORF("UIComponent: Texture size %dx%d is not valid. Width and height should be between %d and %d.", width, height, UICOMPONENT_MIN_TEXTURE_SIZE, UICOMPONENT_MAX_TEXTURE_SIZE); return; } if (texture_->SetSize(width, height, Graphics::GetRGBAFormat(), TEXTURE_RENDERTARGET)) texture_->GetRenderSurface()->SetUpdateMode(SURFACE_MANUALUPDATE); else URHO3D_LOGERROR("UIComponent: resizing texture failed."); }
int PluginApplication::PluginMain(void* ctx_, size_t operation, PluginApplication*(*factory)(Context*)) { #ifndef __EMSCRIPTEN__ assert(ctx_); auto* ctx = static_cast<cr_plugin*>(ctx_); switch (operation) { case CR_LOAD: { auto* context = static_cast<Context*>(ctx->userdata); auto* application = factory(context); application->type_ = PLUGIN_NATIVE; application->Load(); ctx->userdata = application; return 0; } case CR_UNLOAD: case CR_CLOSE: { auto* application = static_cast<PluginApplication*>(ctx->userdata); application->Unload(); ctx->userdata = application->GetContext(); if (application->Refs() != 1) { URHO3D_LOGERRORF("Plugin application '%s' has more than one reference remaining. " "This may lead to memory leaks or crashes.", application->GetTypeName().c_str()); assert(false); } application->ReleaseRef(); return 0; } case CR_STEP: { return 0; } default: break; } assert(false); #endif return -3; }
VertexDeclaration::VertexDeclaration(Graphics* graphics, ShaderVariation* vertexShader, VertexBuffer** vertexBuffers) : inputLayout_(0) { PODVector<D3D11_INPUT_ELEMENT_DESC> elementDescs; unsigned prevBufferDescs = 0; for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i) { if (!vertexBuffers[i]) continue; const PODVector<VertexElement>& srcElements = vertexBuffers[i]->GetElements(); bool isExisting = false; for (unsigned j = 0; j < srcElements.Size(); ++j) { const VertexElement& srcElement = srcElements[j]; const char* semanticName = ShaderVariation::elementSemanticNames[srcElement.semantic_]; // Override existing element if necessary for (unsigned k = 0; k < prevBufferDescs; ++k) { if (elementDescs[k].SemanticName == semanticName && elementDescs[k].SemanticIndex == srcElement.index_) { isExisting = true; elementDescs[k].InputSlot = i; elementDescs[k].AlignedByteOffset = srcElement.offset_; elementDescs[k].InputSlotClass = srcElement.perInstance_ ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; elementDescs[k].InstanceDataStepRate = srcElement.perInstance_ ? 1 : 0; break; } } if (isExisting) continue; D3D11_INPUT_ELEMENT_DESC newDesc; newDesc.SemanticName = semanticName; newDesc.SemanticIndex = srcElement.index_; newDesc.Format = d3dElementFormats[srcElement.type_]; newDesc.InputSlot = (UINT)i; newDesc.AlignedByteOffset = srcElement.offset_; newDesc.InputSlotClass = srcElement.perInstance_ ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; newDesc.InstanceDataStepRate = srcElement.perInstance_ ? 1 : 0; elementDescs.Push(newDesc); } prevBufferDescs = elementDescs.Size(); } if (elementDescs.Empty()) return; const PODVector<unsigned char>& byteCode = vertexShader->GetByteCode(); HRESULT hr = graphics->GetImpl()->GetDevice()->CreateInputLayout(&elementDescs[0], (UINT)elementDescs.Size(), &byteCode[0], byteCode.Size(), (ID3D11InputLayout**)&inputLayout_); if (FAILED(hr)) { URHO3D_SAFE_RELEASE(inputLayout_); URHO3D_LOGERRORF("Failed to create input layout for shader %s due to missing vertex element(s) (HRESULT %x)", vertexShader->GetFullName().CString(), (unsigned)hr); } }
bool File::OpenInternal(const String& fileName, FileMode mode, bool fromPackage) { Close(); compressed_ = false; readSyncNeeded_ = false; writeSyncNeeded_ = false; FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem && !fileSystem->CheckAccess(GetPath(fileName))) { URHO3D_LOGERRORF("Access denied to %s", fileName.CString()); return false; } if (fileName.Empty()) { URHO3D_LOGERROR("Could not open file with empty name"); return false; } #ifdef __ANDROID__ if (URHO3D_IS_ASSET(fileName)) { if (mode != FILE_READ) { URHO3D_LOGERROR("Only read mode is supported for Android asset files"); return false; } assetHandle_ = SDL_RWFromFile(URHO3D_ASSET(fileName), "rb"); if (!assetHandle_) { URHO3D_LOGERRORF("Could not open Android asset file %s", fileName.CString()); return false; } else { fileName_ = fileName; mode_ = mode; position_ = 0; if (!fromPackage) { size_ = SDL_RWsize(assetHandle_); offset_ = 0; } checksum_ = 0; return true; } } #endif #ifdef _WIN32 handle_ = _wfopen(GetWideNativePath(fileName).CString(), openMode[mode]); #else handle_ = fopen(GetNativePath(fileName).CString(), openMode[mode]); #endif // If file did not exist in readwrite mode, retry with write-update mode if (mode == FILE_READWRITE && !handle_) { #ifdef _WIN32 handle_ = _wfopen(GetWideNativePath(fileName).CString(), openMode[mode + 1]); #else handle_ = fopen(GetNativePath(fileName).CString(), openMode[mode + 1]); #endif } if (!handle_) { URHO3D_LOGERRORF("Could not open file %s", fileName.CString()); return false; } if (!fromPackage) { fseek((FILE*)handle_, 0, SEEK_END); long size = ftell((FILE*)handle_); fseek((FILE*)handle_, 0, SEEK_SET); if (size > M_MAX_UNSIGNED) { URHO3D_LOGERRORF("Could not open file %s which is larger than 4GB", fileName.CString()); Close(); size_ = 0; return false; } size_ = (unsigned)size; offset_ = 0; } fileName_ = fileName; mode_ = mode; position_ = 0; checksum_ = 0; return true; }
bool Player::LoadPlugins(const JSONValue& plugins) { // Load plugins. bool failure = false; #if URHO3D_PLUGINS || URHO3D_CSHARP for (auto i = 0; i < plugins.Size(); i++) { if (plugins[i]["private"].GetBool()) continue; ea::string pluginName = plugins[i]["name"].GetString(); ea::string pluginFileName; bool loaded = false; #if !_WIN32 // Native plugins on unixes #if __linux__ pluginFileName = "lib" + pluginName + ".so"; #elif APPLE pluginFileName = "lib" + pluginName + ".dylib"; #endif #if URHO3D_PLUGINS #if MOBILE // On mobile libraries are loaded already so it is ok to not check for existence, TODO: iOS loaded = LoadAssembly(pluginFileName, PLUGIN_NATIVE); #else // On desktop we can access file system as usual if (GetFileSystem()->Exists(pluginFileName)) loaded = LoadAssembly(pluginFileName); else { pluginFileName = GetFileSystem()->GetProgramDir() + pluginFileName; if (GetFileSystem()->Exists(pluginFileName)) loaded = LoadAssembly(pluginFileName); } #endif // MOBILE #endif // URHO3D_PLUGINS #endif // !_WIN32 #if _WIN32 || URHO3D_CSHARP // Native plugins on windows or managed plugins on all platforms if (!loaded) { pluginFileName = pluginName + ".dll"; #if ANDROID pluginFileName = ea::string(APK) + "assets/.net/" + pluginFileName; #endif if (GetFileSystem()->Exists(pluginFileName)) loaded = LoadAssembly(pluginFileName); #if DESKTOP else { pluginFileName = GetFileSystem()->GetProgramDir() + pluginFileName; if (GetFileSystem()->Exists(pluginFileName)) loaded = LoadAssembly(pluginFileName); } #endif } #endif if (!loaded) { URHO3D_LOGERRORF("Loading of '%s' assembly failed.", pluginName.c_str()); return false; } } #endif // URHO3D_PLUGINS return true; }