diff options
Diffstat (limited to 'src/player/ArgList.cpp')
-rw-r--r-- | src/player/ArgList.cpp | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/src/player/ArgList.cpp b/src/player/ArgList.cpp new file mode 100644 index 0000000..5abe78c --- /dev/null +++ b/src/player/ArgList.cpp @@ -0,0 +1,278 @@ +// +// libavg - Media Playback Engine. +// Copyright (C) 2003-2014 Ulrich von Zadow +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Current versions can be found at www.libavg.de +// +// Original author of this file is Nick Hebner (hebnern@gmail.com). +// + +#include "ArgList.h" + +#include "ExportedObject.h" +#include "FontStyle.h" + +#include "../base/Logger.h" +#include "../base/Exception.h" +#include "../base/StringHelper.h" +#include "../base/UTF8String.h" + +#include <sstream> + +using namespace std; + +namespace avg { + +typedef std::vector<std::vector<glm::vec2> > CollVec2Vector; + +ArgList::ArgList() +{ +} + +ArgList::ArgList(const ArgList& argTemplates, const xmlNodePtr xmlNode) +{ + copyArgsFrom(argTemplates); + + for (xmlAttrPtr prop = xmlNode->properties; prop; prop = prop->next) + { + string name = (char*)prop->name; + string value = (char*)prop->children->content; + setArgValue(name, value); + } +} + +ArgList::ArgList(const ArgList& argTemplates, const py::dict& PyDict) +{ + // TODO: Check if all required args are being set. + copyArgsFrom(argTemplates); + py::list keys = PyDict.keys(); + int nKeys = py::len(keys); + for (int i = 0; i < nKeys; i++) + { + py::object keyObj = keys[i]; + py::object valObj = PyDict[keyObj]; + + py::extract<string> keyStrProxy(keyObj); + if (!keyStrProxy.check()) { + throw Exception(AVG_ERR_INVALID_ARGS, "Argument name must be a string."); + } + string keyStr = keyStrProxy(); + + setArgValue(keyStr, valObj); + } +} + +ArgList::~ArgList() +{ +} + +bool ArgList::hasArg(const std::string& sName) const +{ + ArgMap::const_iterator it = m_Args.find(sName); + return (it != m_Args.end() && !(it->second->isDefault())); +} + +const ArgBasePtr ArgList::getArg(const string& sName) const +{ + ArgMap::const_iterator valIt = m_Args.find(sName); + if (valIt == m_Args.end()) { + // TODO: The error message should mention line number and node type. + throw Exception(AVG_ERR_INVALID_ARGS, string("Argument ")+sName+" is not valid."); + } + return valIt->second; +} + +void ArgList::getOverlayedArgVal(glm::vec2* pResult, const string& sName, + const string& sOverlay1, const string& sOverlay2, const string& sID) const +{ + if (hasArg(sName)) { + if (hasArg(sOverlay1) || hasArg(sOverlay2)) { + throw (Exception(AVG_ERR_INVALID_ARGS, + string("Duplicate node arguments (")+sName+" and "+ + sOverlay1+","+sOverlay2+") for node '"+sID+"'")); + } + *pResult = getArgVal<glm::vec2>(sName); + } +} + +const ArgMap& ArgList::getArgMap() const +{ + return m_Args; +} + +void ArgList::setArg(const ArgBase& newArg) +{ + m_Args[newArg.getName()] = ArgBasePtr(newArg.createCopy()); +} + +void ArgList::setArgs(const ArgList& args) +{ + for (ArgMap::const_iterator it = args.m_Args.begin(); it != args.m_Args.end(); it++) { + m_Args.insert(*it); + } +} + +void ArgList::setMembers(ExportedObject * pObj) const +{ + for (ArgMap::const_iterator it = m_Args.begin(); it != m_Args.end(); it++) { + const ArgBasePtr pCurArg = it->second; + pCurArg->setMember(pObj); + } + pObj->setArgs(*this); +} + +template<class T> +void setArgValue(Arg<T>* pArg, const std::string & sName, const py::object& value) +{ + py::extract<T> valProxy(value); + if (!valProxy.check()) { + string sTypeName = getFriendlyTypeName(pArg->getValue()); + throw Exception(AVG_ERR_INVALID_ARGS, "Type error in argument "+sName+": " + +sTypeName+" expected."); + } + pArg->setValue(valProxy()); +} + +void ArgList::setArgValue(const std::string & sName, const py::object& value) +{ + ArgBasePtr pArg = getArg(sName); + Arg<string>* pStringArg = dynamic_cast<Arg<string>* >(&*pArg); + Arg<UTF8String>* pUTF8StringArg = dynamic_cast<Arg<UTF8String>* >(&*pArg); + Arg<int>* pIntArg = dynamic_cast<Arg<int>* >(&*pArg); + Arg<float>* pFloatArg = dynamic_cast<Arg<float>* >(&*pArg); + Arg<bool>* pBoolArg = dynamic_cast<Arg<bool>* >(&*pArg); + Arg<glm::vec2>* pVec2Arg = dynamic_cast<Arg<glm::vec2>* >(&*pArg); + Arg<glm::vec3>* pVec3Arg = dynamic_cast<Arg<glm::vec3>* >(&*pArg); + Arg<glm::ivec3>* pIVec3Arg = dynamic_cast<Arg<glm::ivec3>* >(&*pArg); + Arg<vector<float> >* pFVectorArg = dynamic_cast<Arg<vector<float> >* >(&*pArg); + Arg<vector<int> >* pIVectorArg = dynamic_cast<Arg<vector<int> >* >(&*pArg); + Arg<vector<glm::vec2> >* pVec2VectorArg = + dynamic_cast<Arg<vector<glm::vec2> >* >(&*pArg); + Arg<vector<glm::ivec3> >* pIVec3VectorArg = + dynamic_cast<Arg<vector<glm::ivec3> >* >(&*pArg); + Arg<CollVec2Vector>* pCollVec2VectorArg = + dynamic_cast<Arg<CollVec2Vector>* >(&*pArg); + Arg<FontStyle>* pFontStyleArg = dynamic_cast<Arg<FontStyle>* >(&*pArg); + Arg<FontStylePtr>* pFontStylePtrArg = dynamic_cast<Arg<FontStylePtr>* >(&*pArg); + if(pStringArg) { + avg::setArgValue(pStringArg, sName, value); + } else if (pUTF8StringArg) { + avg::setArgValue(pUTF8StringArg, sName, value); + } else if (pIntArg) { + avg::setArgValue(pIntArg, sName, value); + } else if (pFloatArg) { + avg::setArgValue(pFloatArg, sName, value); + } else if (pBoolArg) { + avg::setArgValue(pBoolArg, sName, value); + } else if (pVec2Arg) { + avg::setArgValue(pVec2Arg, sName, value); + } else if (pVec3Arg) { + avg::setArgValue(pVec3Arg, sName, value); + } else if (pIVec3Arg) { + avg::setArgValue(pIVec3Arg, sName, value); + } else if (pFVectorArg) { + avg::setArgValue(pFVectorArg, sName, value); + } else if (pIVectorArg) { + avg::setArgValue(pIVectorArg, sName, value); + } else if (pVec2VectorArg) { + avg::setArgValue(pVec2VectorArg, sName, value); + } else if (pIVec3VectorArg) { + avg::setArgValue(pIVec3VectorArg, sName, value); + } else if (pCollVec2VectorArg) { + avg::setArgValue(pCollVec2VectorArg, sName, value); + } else if (pFontStyleArg) { + avg::setArgValue(pFontStyleArg, sName, value); + } else if (pFontStylePtrArg) { + avg::setArgValue(pFontStylePtrArg, sName, value); + } else { + AVG_ASSERT(false); + } +} + +void ArgList::setArgValue(const std::string & sName, const std::string & sValue) +{ + ArgBasePtr pArg = getArg(sName); + Arg<string>* pStringArg = dynamic_cast<Arg<string>* >(&*pArg); + Arg<UTF8String>* pUTF8StringArg = dynamic_cast<Arg<UTF8String>* >(&*pArg); + Arg<int>* pIntArg = dynamic_cast<Arg<int>* >(&*pArg); + Arg<float>* pFloatArg = dynamic_cast<Arg<float>* >(&*pArg); + Arg<bool>* pBoolArg = dynamic_cast<Arg<bool>* >(&*pArg); + Arg<glm::vec2>* pVec2Arg = dynamic_cast<Arg<glm::vec2>* >(&*pArg); + Arg<glm::vec3>* pVec3Arg = dynamic_cast<Arg<glm::vec3>* >(&*pArg); + Arg<glm::ivec3>* pIVec3Arg = dynamic_cast<Arg<glm::ivec3>* >(&*pArg); + Arg<vector<float> >* pFVectorArg = dynamic_cast<Arg<vector<float> >* >(&*pArg); + Arg<vector<int> >* pIVectorArg = dynamic_cast<Arg<vector<int> >* >(&*pArg); + Arg<vector<glm::vec2> >* pVec2VectorArg = + dynamic_cast<Arg<vector<glm::vec2> >* >(&*pArg); + Arg<vector<glm::ivec3> >* pIVec3VectorArg = + dynamic_cast<Arg<vector<glm::ivec3> >* >(&*pArg); + Arg<CollVec2Vector>* pCollVec2VectorArg = + dynamic_cast<Arg<CollVec2Vector>* >(&*pArg); + if (pStringArg) { + pStringArg->setValue(sValue); + } else if (pUTF8StringArg) { + pUTF8StringArg->setValue(sValue); + } else if (pIntArg) { + pIntArg->setValue(stringToInt(sValue)); + } else if (pFloatArg) { + pFloatArg->setValue(stringToFloat(sValue)); + } else if (pBoolArg) { + pBoolArg->setValue(stringToBool(sValue)); + } else if (pVec2Arg) { + pVec2Arg->setValue(stringToVec2(sValue)); + } else if (pVec3Arg) { + pVec3Arg->setValue(stringToVec3(sValue)); + } else if (pIVec3Arg) { + pIVec3Arg->setValue(stringToIVec3(sValue)); + } else if (pFVectorArg) { + vector<float> v; + fromString(sValue, v); + pFVectorArg->setValue(v); + } else if (pIVectorArg) { + vector<int> v; + fromString(sValue, v); + pIVectorArg->setValue(v); + } else if (pVec2VectorArg) { + vector<glm::vec2> v; + fromString(sValue, v); + pVec2VectorArg->setValue(v); + } else if (pIVec3VectorArg) { + vector<glm::ivec3> v; + fromString(sValue, v); + pIVec3VectorArg->setValue(v); + } else if (pCollVec2VectorArg) { + CollVec2Vector v; + fromString(sValue, v); + pCollVec2VectorArg->setValue(v); + } else { + AVG_ASSERT(false); + } +} + +void ArgList::copyArgsFrom(const ArgList& argTemplates) +{ + for (ArgMap::const_iterator it = argTemplates.m_Args.begin(); + it != argTemplates.m_Args.end(); it++) + { + string sKey = it->first; + ArgBasePtr pArg = ArgBasePtr(it->second->createCopy()); + m_Args[sKey] = pArg; + } +} + +} + |