Ejemplo n.º 1
0
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.");
    }
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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();
}
Ejemplo n.º 4
0
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());
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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());
    }
}
Ejemplo n.º 7
0
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());
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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.");
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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);
    }
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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;
}