Fixed some lua methods, set decorations enabled by default, allow toggling of decorations with ctrl+b, saving and loading of render, display and colour modes for the renderer
This commit is contained in:
parent
ec6d1012b2
commit
5546f7d01e
4
.gitignore
vendored
4
.gitignore
vendored
@ -5,4 +5,6 @@
|
|||||||
*.a
|
*.a
|
||||||
*.la
|
*.la
|
||||||
*~
|
*~
|
||||||
*.pref
|
*.pref
|
||||||
|
stdout.txt
|
||||||
|
stderr.txt
|
@ -1762,7 +1762,8 @@ Renderer::Renderer(Graphics * g, Simulation * sim):
|
|||||||
zoomScopePosition(0, 0),
|
zoomScopePosition(0, 0),
|
||||||
zoomScopeSize(10),
|
zoomScopeSize(10),
|
||||||
ZFACTOR(8),
|
ZFACTOR(8),
|
||||||
zoomEnabled(false)
|
zoomEnabled(false),
|
||||||
|
decorations_enable(1)
|
||||||
{
|
{
|
||||||
this->g = g;
|
this->g = g;
|
||||||
this->sim = sim;
|
this->sim = sim;
|
||||||
@ -1832,6 +1833,11 @@ void Renderer::SetRenderMode(std::vector<unsigned int> render)
|
|||||||
CompileRenderMode();
|
CompileRenderMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned int> Renderer::GetRenderMode()
|
||||||
|
{
|
||||||
|
return render_modes;
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::CompileDisplayMode()
|
void Renderer::CompileDisplayMode()
|
||||||
{
|
{
|
||||||
display_mode = 0;
|
display_mode = 0;
|
||||||
@ -1871,11 +1877,21 @@ void Renderer::SetDisplayMode(std::vector<unsigned int> display)
|
|||||||
CompileDisplayMode();
|
CompileDisplayMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned int> Renderer::GetDisplayMode()
|
||||||
|
{
|
||||||
|
return display_modes;
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::SetColourMode(unsigned int mode)
|
void Renderer::SetColourMode(unsigned int mode)
|
||||||
{
|
{
|
||||||
colour_mode = mode;
|
colour_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int Renderer::GetColourMode()
|
||||||
|
{
|
||||||
|
return colour_mode;
|
||||||
|
}
|
||||||
|
|
||||||
Renderer::~Renderer()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
free(graphicscache);
|
free(graphicscache);
|
||||||
|
@ -71,11 +71,14 @@ public:
|
|||||||
void CompileRenderMode();
|
void CompileRenderMode();
|
||||||
void AddRenderMode(unsigned int mode);
|
void AddRenderMode(unsigned int mode);
|
||||||
void SetRenderMode(std::vector<unsigned int> render);
|
void SetRenderMode(std::vector<unsigned int> render);
|
||||||
|
std::vector<unsigned int> GetRenderMode();
|
||||||
void RemoveRenderMode(unsigned int mode);
|
void RemoveRenderMode(unsigned int mode);
|
||||||
void AddDisplayMode(unsigned int mode);
|
void AddDisplayMode(unsigned int mode);
|
||||||
void RemoveDisplayMode(unsigned int mode);
|
void RemoveDisplayMode(unsigned int mode);
|
||||||
void SetDisplayMode(std::vector<unsigned int> display);
|
void SetDisplayMode(std::vector<unsigned int> display);
|
||||||
|
std::vector<unsigned int> GetDisplayMode();
|
||||||
void SetColourMode(unsigned int mode);
|
void SetColourMode(unsigned int mode);
|
||||||
|
unsigned int GetColourMode();
|
||||||
|
|
||||||
Renderer(Graphics * g, Simulation * sim);
|
Renderer(Graphics * g, Simulation * sim);
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
@ -1,442 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 2009-2010, Terry Caton
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the projecct nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include "visitor.h"
|
|
||||||
#include "reader.h"
|
|
||||||
#include <cassert>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
TODO:
|
|
||||||
* better documentation
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace json
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
inline Exception::Exception(const std::string& sMessage) :
|
|
||||||
std::runtime_error(sMessage) {}
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////
|
|
||||||
// UnknownElement members
|
|
||||||
|
|
||||||
class UnknownElement::Imp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~Imp() {}
|
|
||||||
virtual Imp* Clone() const = 0;
|
|
||||||
|
|
||||||
virtual bool Compare(const Imp& imp) const = 0;
|
|
||||||
|
|
||||||
virtual void Accept(ConstVisitor& visitor) const = 0;
|
|
||||||
virtual void Accept(Visitor& visitor) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
class UnknownElement::Imp_T : public UnknownElement::Imp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Imp_T(const ElementTypeT& element) : m_Element(element) {}
|
|
||||||
virtual Imp* Clone() const { return new Imp_T<ElementTypeT>(*this); }
|
|
||||||
|
|
||||||
virtual void Accept(ConstVisitor& visitor) const { visitor.Visit(m_Element); }
|
|
||||||
virtual void Accept(Visitor& visitor) { visitor.Visit(m_Element); }
|
|
||||||
|
|
||||||
virtual bool Compare(const Imp& imp) const
|
|
||||||
{
|
|
||||||
ConstCastVisitor_T<ElementTypeT> castVisitor;
|
|
||||||
imp.Accept(castVisitor);
|
|
||||||
return castVisitor.m_pElement &&
|
|
||||||
m_Element == *castVisitor.m_pElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ElementTypeT m_Element;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class UnknownElement::ConstCastVisitor : public ConstVisitor
|
|
||||||
{
|
|
||||||
virtual void Visit(const Array& array) {}
|
|
||||||
virtual void Visit(const Object& object) {}
|
|
||||||
virtual void Visit(const Number& number) {}
|
|
||||||
virtual void Visit(const String& string) {}
|
|
||||||
virtual void Visit(const Boolean& boolean) {}
|
|
||||||
virtual void Visit(const Null& null) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
class UnknownElement::ConstCastVisitor_T : public ConstCastVisitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConstCastVisitor_T() : m_pElement(0) {}
|
|
||||||
virtual void Visit(const ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions
|
|
||||||
const ElementTypeT* m_pElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class UnknownElement::CastVisitor : public Visitor
|
|
||||||
{
|
|
||||||
virtual void Visit(Array& array) {}
|
|
||||||
virtual void Visit(Object& object) {}
|
|
||||||
virtual void Visit(Number& number) {}
|
|
||||||
virtual void Visit(String& string) {}
|
|
||||||
virtual void Visit(Boolean& boolean) {}
|
|
||||||
virtual void Visit(Null& null) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
class UnknownElement::CastVisitor_T : public CastVisitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastVisitor_T() : m_pElement(0) {}
|
|
||||||
virtual void Visit(ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions
|
|
||||||
ElementTypeT* m_pElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline UnknownElement::UnknownElement() : m_pImp( new Imp_T<Null>( Null() ) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {}
|
|
||||||
inline UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T<Object>(object) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(const Array& array) : m_pImp( new Imp_T<Array>(array) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(const Number& number) : m_pImp( new Imp_T<Number>(number) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(const Boolean& boolean) : m_pImp( new Imp_T<Boolean>(boolean) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(const String& string) : m_pImp( new Imp_T<String>(string) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(const Null& null) : m_pImp( new Imp_T<Null>(null) ) {}
|
|
||||||
|
|
||||||
inline UnknownElement::~UnknownElement() { delete m_pImp; }
|
|
||||||
|
|
||||||
inline UnknownElement::operator const Object& () const { return CastTo<Object>(); }
|
|
||||||
inline UnknownElement::operator const Array& () const { return CastTo<Array>(); }
|
|
||||||
inline UnknownElement::operator const Number& () const { return CastTo<Number>(); }
|
|
||||||
inline UnknownElement::operator const Boolean& () const { return CastTo<Boolean>(); }
|
|
||||||
inline UnknownElement::operator const String& () const { return CastTo<String>(); }
|
|
||||||
inline UnknownElement::operator const Null& () const { return CastTo<Null>(); }
|
|
||||||
|
|
||||||
inline UnknownElement::operator Object& () { return ConvertTo<Object>(); }
|
|
||||||
inline UnknownElement::operator Array& () { return ConvertTo<Array>(); }
|
|
||||||
inline UnknownElement::operator Number& () { return ConvertTo<Number>(); }
|
|
||||||
inline UnknownElement::operator Boolean& () { return ConvertTo<Boolean>(); }
|
|
||||||
inline UnknownElement::operator String& () { return ConvertTo<String>(); }
|
|
||||||
inline UnknownElement::operator Null& () { return ConvertTo<Null>(); }
|
|
||||||
|
|
||||||
inline UnknownElement& UnknownElement::operator = (const UnknownElement& unknown)
|
|
||||||
{
|
|
||||||
// always check for this
|
|
||||||
if (&unknown != this)
|
|
||||||
{
|
|
||||||
// we might be copying from a subtree of ourselves. delete the old imp
|
|
||||||
// only after the clone operation is complete. yes, this could be made
|
|
||||||
// more efficient, but isn't worth the complexity
|
|
||||||
Imp* pOldImp = m_pImp;
|
|
||||||
m_pImp = unknown.m_pImp->Clone();
|
|
||||||
delete pOldImp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline UnknownElement& UnknownElement::operator[] (const std::string& key)
|
|
||||||
{
|
|
||||||
// the people want an object. make us one if we aren't already
|
|
||||||
Object& object = ConvertTo<Object>();
|
|
||||||
return object[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const UnknownElement& UnknownElement::operator[] (const std::string& key) const
|
|
||||||
{
|
|
||||||
// throws if we aren't an object
|
|
||||||
const Object& object = CastTo<Object>();
|
|
||||||
return object[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline UnknownElement& UnknownElement::operator[] (size_t index)
|
|
||||||
{
|
|
||||||
// the people want an array. make us one if we aren't already
|
|
||||||
Array& array = ConvertTo<Array>();
|
|
||||||
return array[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const UnknownElement& UnknownElement::operator[] (size_t index) const
|
|
||||||
{
|
|
||||||
// throws if we aren't an array
|
|
||||||
const Array& array = CastTo<Array>();
|
|
||||||
return array[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
const ElementTypeT& UnknownElement::CastTo() const
|
|
||||||
{
|
|
||||||
ConstCastVisitor_T<ElementTypeT> castVisitor;
|
|
||||||
m_pImp->Accept(castVisitor);
|
|
||||||
if (castVisitor.m_pElement == 0)
|
|
||||||
throw Exception("Bad cast");
|
|
||||||
return *castVisitor.m_pElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
ElementTypeT& UnknownElement::ConvertTo()
|
|
||||||
{
|
|
||||||
CastVisitor_T<ElementTypeT> castVisitor;
|
|
||||||
m_pImp->Accept(castVisitor);
|
|
||||||
if (castVisitor.m_pElement == 0)
|
|
||||||
{
|
|
||||||
// we're not the right type. fix it & try again
|
|
||||||
*this = ElementTypeT();
|
|
||||||
m_pImp->Accept(castVisitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *castVisitor.m_pElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); }
|
|
||||||
inline void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); }
|
|
||||||
|
|
||||||
|
|
||||||
inline bool UnknownElement::operator == (const UnknownElement& element) const
|
|
||||||
{
|
|
||||||
return m_pImp->Compare(*element.m_pImp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////
|
|
||||||
// Object members
|
|
||||||
|
|
||||||
|
|
||||||
inline Object::Member::Member(const std::string& nameIn, const UnknownElement& elementIn) :
|
|
||||||
name(nameIn), element(elementIn) {}
|
|
||||||
|
|
||||||
inline bool Object::Member::operator == (const Member& member) const
|
|
||||||
{
|
|
||||||
return name == member.name &&
|
|
||||||
element == member.element;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Object::Finder : public std::unary_function<Object::Member, bool>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Finder(const std::string& name) : m_name(name) {}
|
|
||||||
bool operator () (const Object::Member& member) {
|
|
||||||
return member.name == m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline Object::iterator Object::Begin() { return m_Members.begin(); }
|
|
||||||
inline Object::iterator Object::End() { return m_Members.end(); }
|
|
||||||
inline Object::const_iterator Object::Begin() const { return m_Members.begin(); }
|
|
||||||
inline Object::const_iterator Object::End() const { return m_Members.end(); }
|
|
||||||
|
|
||||||
inline size_t Object::Size() const { return m_Members.size(); }
|
|
||||||
inline bool Object::Empty() const { return m_Members.empty(); }
|
|
||||||
|
|
||||||
inline Object::iterator Object::Find(const std::string& name)
|
|
||||||
{
|
|
||||||
return std::find_if(m_Members.begin(), m_Members.end(), Finder(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Object::const_iterator Object::Find(const std::string& name) const
|
|
||||||
{
|
|
||||||
return std::find_if(m_Members.begin(), m_Members.end(), Finder(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Object::iterator Object::Insert(const Member& member)
|
|
||||||
{
|
|
||||||
return Insert(member, End());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Object::iterator Object::Insert(const Member& member, iterator itWhere)
|
|
||||||
{
|
|
||||||
iterator it = Find(member.name);
|
|
||||||
if (it != m_Members.end())
|
|
||||||
throw Exception(std::string("Object member already exists: ") + member.name);
|
|
||||||
|
|
||||||
it = m_Members.insert(itWhere, member);
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Object::iterator Object::Erase(iterator itWhere)
|
|
||||||
{
|
|
||||||
return m_Members.erase(itWhere);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline UnknownElement& Object::operator [](const std::string& name)
|
|
||||||
{
|
|
||||||
|
|
||||||
iterator it = Find(name);
|
|
||||||
if (it == m_Members.end())
|
|
||||||
{
|
|
||||||
Member member(name);
|
|
||||||
it = Insert(member, End());
|
|
||||||
}
|
|
||||||
return it->element;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const UnknownElement& Object::operator [](const std::string& name) const
|
|
||||||
{
|
|
||||||
const_iterator it = Find(name);
|
|
||||||
if (it == End())
|
|
||||||
throw Exception(std::string("Object member not found: ") + name);
|
|
||||||
return it->element;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Object::Clear()
|
|
||||||
{
|
|
||||||
m_Members.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Object::operator == (const Object& object) const
|
|
||||||
{
|
|
||||||
return m_Members == object.m_Members;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////
|
|
||||||
// Array members
|
|
||||||
|
|
||||||
inline Array::iterator Array::Begin() { return m_Elements.begin(); }
|
|
||||||
inline Array::iterator Array::End() { return m_Elements.end(); }
|
|
||||||
inline Array::const_iterator Array::Begin() const { return m_Elements.begin(); }
|
|
||||||
inline Array::const_iterator Array::End() const { return m_Elements.end(); }
|
|
||||||
|
|
||||||
inline Array::iterator Array::Insert(const UnknownElement& element, iterator itWhere)
|
|
||||||
{
|
|
||||||
return m_Elements.insert(itWhere, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Array::iterator Array::Insert(const UnknownElement& element)
|
|
||||||
{
|
|
||||||
return Insert(element, End());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Array::iterator Array::Erase(iterator itWhere)
|
|
||||||
{
|
|
||||||
return m_Elements.erase(itWhere);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Array::Resize(size_t newSize)
|
|
||||||
{
|
|
||||||
m_Elements.resize(newSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t Array::Size() const { return m_Elements.size(); }
|
|
||||||
inline bool Array::Empty() const { return m_Elements.empty(); }
|
|
||||||
|
|
||||||
inline UnknownElement& Array::operator[] (size_t index)
|
|
||||||
{
|
|
||||||
size_t nMinSize = index + 1; // zero indexed
|
|
||||||
if (m_Elements.size() < nMinSize)
|
|
||||||
m_Elements.resize(nMinSize);
|
|
||||||
return m_Elements[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const UnknownElement& Array::operator[] (size_t index) const
|
|
||||||
{
|
|
||||||
if (index >= m_Elements.size())
|
|
||||||
throw Exception("Array out of bounds");
|
|
||||||
return m_Elements[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Array::Clear() {
|
|
||||||
m_Elements.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Array::operator == (const Array& array) const
|
|
||||||
{
|
|
||||||
return m_Elements == array.m_Elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////
|
|
||||||
// TrivialType_T members
|
|
||||||
|
|
||||||
template <typename DataTypeT>
|
|
||||||
TrivialType_T<DataTypeT>::TrivialType_T(const DataTypeT& t) :
|
|
||||||
m_tValue(t) {}
|
|
||||||
|
|
||||||
template <typename DataTypeT>
|
|
||||||
TrivialType_T<DataTypeT>::operator DataTypeT&()
|
|
||||||
{
|
|
||||||
return Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename DataTypeT>
|
|
||||||
TrivialType_T<DataTypeT>::operator const DataTypeT&() const
|
|
||||||
{
|
|
||||||
return Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename DataTypeT>
|
|
||||||
DataTypeT& TrivialType_T<DataTypeT>::Value()
|
|
||||||
{
|
|
||||||
return m_tValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename DataTypeT>
|
|
||||||
const DataTypeT& TrivialType_T<DataTypeT>::Value() const
|
|
||||||
{
|
|
||||||
return m_tValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename DataTypeT>
|
|
||||||
bool TrivialType_T<DataTypeT>::operator == (const TrivialType_T<DataTypeT>& trivial) const
|
|
||||||
{
|
|
||||||
return m_tValue == trivial.m_tValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////
|
|
||||||
// Null members
|
|
||||||
|
|
||||||
inline bool Null::operator == (const Null& trivial) const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // End namespace
|
|
@ -1,533 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 2009-2010, Terry Caton
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the projecct nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <set>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
TODO:
|
|
||||||
* better documentation
|
|
||||||
* unicode character decoding
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace json
|
|
||||||
{
|
|
||||||
|
|
||||||
inline std::istream& operator >> (std::istream& istr, UnknownElement& elementRoot) {
|
|
||||||
Reader::Read(elementRoot, istr);
|
|
||||||
return istr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Reader::Location::Location() :
|
|
||||||
m_nLine(0),
|
|
||||||
m_nLineOffset(0),
|
|
||||||
m_nDocOffset(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////
|
|
||||||
// Reader::InputStream
|
|
||||||
|
|
||||||
class Reader::InputStream // would be cool if we could inherit from std::istream & override "get"
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InputStream(std::istream& iStr) :
|
|
||||||
m_iStr(iStr) {}
|
|
||||||
|
|
||||||
// protect access to the input stream, so we can keeep track of document/line offsets
|
|
||||||
char Get(); // big, define outside
|
|
||||||
char Peek() {
|
|
||||||
assert(m_iStr.eof() == false); // enforce reading of only valid stream data
|
|
||||||
return m_iStr.peek();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EOS() {
|
|
||||||
m_iStr.peek(); // apparently eof flag isn't set until a character read is attempted. whatever.
|
|
||||||
return m_iStr.eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Location& GetLocation() const { return m_Location; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::istream& m_iStr;
|
|
||||||
Location m_Location;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline char Reader::InputStream::Get()
|
|
||||||
{
|
|
||||||
assert(m_iStr.eof() == false); // enforce reading of only valid stream data
|
|
||||||
char c = m_iStr.get();
|
|
||||||
|
|
||||||
++m_Location.m_nDocOffset;
|
|
||||||
if (c == '\n') {
|
|
||||||
++m_Location.m_nLine;
|
|
||||||
m_Location.m_nLineOffset = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++m_Location.m_nLineOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////
|
|
||||||
// Reader::TokenStream
|
|
||||||
|
|
||||||
class Reader::TokenStream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TokenStream(const Tokens& tokens);
|
|
||||||
|
|
||||||
const Token& Peek();
|
|
||||||
const Token& Get();
|
|
||||||
|
|
||||||
bool EOS() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const Tokens& m_Tokens;
|
|
||||||
Tokens::const_iterator m_itCurrent;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline Reader::TokenStream::TokenStream(const Tokens& tokens) :
|
|
||||||
m_Tokens(tokens),
|
|
||||||
m_itCurrent(tokens.begin())
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline const Reader::Token& Reader::TokenStream::Peek() {
|
|
||||||
if (EOS())
|
|
||||||
{
|
|
||||||
const Token& lastToken = *m_Tokens.rbegin();
|
|
||||||
std::string sMessage = "Unexpected end of token stream";
|
|
||||||
throw ParseException(sMessage, lastToken.locBegin, lastToken.locEnd); // nowhere to point to
|
|
||||||
}
|
|
||||||
return *(m_itCurrent);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const Reader::Token& Reader::TokenStream::Get() {
|
|
||||||
const Token& token = Peek();
|
|
||||||
++m_itCurrent;
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Reader::TokenStream::EOS() const {
|
|
||||||
return m_itCurrent == m_Tokens.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////
|
|
||||||
// Reader (finally)
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); }
|
|
||||||
inline void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); }
|
|
||||||
inline void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); }
|
|
||||||
inline void Reader::Read(Number& number, std::istream& istr) { Read_i(number, istr); }
|
|
||||||
inline void Reader::Read(Boolean& boolean, std::istream& istr) { Read_i(boolean, istr); }
|
|
||||||
inline void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); }
|
|
||||||
inline void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
void Reader::Read_i(ElementTypeT& element, std::istream& istr)
|
|
||||||
{
|
|
||||||
Reader reader;
|
|
||||||
|
|
||||||
Tokens tokens;
|
|
||||||
InputStream inputStream(istr);
|
|
||||||
reader.Scan(tokens, inputStream);
|
|
||||||
|
|
||||||
TokenStream tokenStream(tokens);
|
|
||||||
reader.Parse(element, tokenStream);
|
|
||||||
|
|
||||||
if (tokenStream.EOS() == false)
|
|
||||||
{
|
|
||||||
const Token& token = tokenStream.Peek();
|
|
||||||
std::string sMessage = std::string("Expected End of token stream; found ") + token.sValue;
|
|
||||||
throw ParseException(sMessage, token.locBegin, token.locEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
|
||||||
{
|
|
||||||
while (EatWhiteSpace(inputStream), // ignore any leading white space...
|
|
||||||
inputStream.EOS() == false) // ...before checking for EOS
|
|
||||||
{
|
|
||||||
// if all goes well, we'll create a token each pass
|
|
||||||
Token token;
|
|
||||||
token.locBegin = inputStream.GetLocation();
|
|
||||||
|
|
||||||
// gives us null-terminated string
|
|
||||||
char sChar = inputStream.Peek();
|
|
||||||
switch (sChar)
|
|
||||||
{
|
|
||||||
case '{':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, "{");
|
|
||||||
token.nType = Token::TOKEN_OBJECT_BEGIN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '}':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, "}");
|
|
||||||
token.nType = Token::TOKEN_OBJECT_END;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '[':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, "[");
|
|
||||||
token.nType = Token::TOKEN_ARRAY_BEGIN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ']':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, "]");
|
|
||||||
token.nType = Token::TOKEN_ARRAY_END;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ',':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, ",");
|
|
||||||
token.nType = Token::TOKEN_NEXT_ELEMENT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ':':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, ":");
|
|
||||||
token.nType = Token::TOKEN_MEMBER_ASSIGN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '"':
|
|
||||||
token.sValue = MatchString(inputStream);
|
|
||||||
token.nType = Token::TOKEN_STRING;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-':
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
token.sValue = MatchNumber(inputStream);
|
|
||||||
token.nType = Token::TOKEN_NUMBER;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 't':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, "true");
|
|
||||||
token.nType = Token::TOKEN_BOOLEAN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'f':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, "false");
|
|
||||||
token.nType = Token::TOKEN_BOOLEAN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'n':
|
|
||||||
token.sValue = MatchExpectedString(inputStream, "null");
|
|
||||||
token.nType = Token::TOKEN_NULL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
std::string sErrorMessage = std::string("Unexpected character in stream: ") + sChar;
|
|
||||||
throw ScanException(sErrorMessage, inputStream.GetLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
token.locEnd = inputStream.GetLocation();
|
|
||||||
tokens.push_back(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::EatWhiteSpace(InputStream& inputStream)
|
|
||||||
{
|
|
||||||
while (inputStream.EOS() == false &&
|
|
||||||
::isspace(inputStream.Peek()))
|
|
||||||
inputStream.Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string Reader::MatchExpectedString(InputStream& inputStream, const std::string& sExpected)
|
|
||||||
{
|
|
||||||
std::string::const_iterator it(sExpected.begin()),
|
|
||||||
itEnd(sExpected.end());
|
|
||||||
for ( ; it != itEnd; ++it) {
|
|
||||||
if (inputStream.EOS() || // did we reach the end before finding what we're looking for...
|
|
||||||
inputStream.Get() != *it) // ...or did we find something different?
|
|
||||||
{
|
|
||||||
std::string sMessage = std::string("Expected string: ") + sExpected;
|
|
||||||
throw ScanException(sMessage, inputStream.GetLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// all's well if we made it here
|
|
||||||
return sExpected;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string Reader::MatchString(InputStream& inputStream)
|
|
||||||
{
|
|
||||||
MatchExpectedString(inputStream, "\"");
|
|
||||||
|
|
||||||
std::string string;
|
|
||||||
while (inputStream.EOS() == false &&
|
|
||||||
inputStream.Peek() != '"')
|
|
||||||
{
|
|
||||||
char c = inputStream.Get();
|
|
||||||
|
|
||||||
// escape?
|
|
||||||
if (c == '\\' &&
|
|
||||||
inputStream.EOS() == false) // shouldn't have reached the end yet
|
|
||||||
{
|
|
||||||
c = inputStream.Get();
|
|
||||||
switch (c) {
|
|
||||||
case '/': string.push_back('/'); break;
|
|
||||||
case '"': string.push_back('"'); break;
|
|
||||||
case '\\': string.push_back('\\'); break;
|
|
||||||
case 'b': string.push_back('\b'); break;
|
|
||||||
case 'f': string.push_back('\f'); break;
|
|
||||||
case 'n': string.push_back('\n'); break;
|
|
||||||
case 'r': string.push_back('\r'); break;
|
|
||||||
case 't': string.push_back('\t'); break;
|
|
||||||
//case 'u': string.push_back('\u'); break; // TODO: what do we do with this?
|
|
||||||
default: {
|
|
||||||
std::string sMessage = std::string("Unrecognized escape sequence found in string: \\") + c;
|
|
||||||
throw ScanException(sMessage, inputStream.GetLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
string.push_back(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eat the last '"' that we just peeked
|
|
||||||
MatchExpectedString(inputStream, "\"");
|
|
||||||
|
|
||||||
// all's well if we made it here
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string Reader::MatchNumber(InputStream& inputStream)
|
|
||||||
{
|
|
||||||
const char sNumericChars[] = "0123456789.eE-+";
|
|
||||||
std::set<char> numericChars;
|
|
||||||
numericChars.insert(sNumericChars, sNumericChars + sizeof(sNumericChars));
|
|
||||||
|
|
||||||
std::string sNumber;
|
|
||||||
while (inputStream.EOS() == false &&
|
|
||||||
numericChars.find(inputStream.Peek()) != numericChars.end())
|
|
||||||
{
|
|
||||||
sNumber.push_back(inputStream.Get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return sNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream)
|
|
||||||
{
|
|
||||||
const Token& token = tokenStream.Peek();
|
|
||||||
switch (token.nType) {
|
|
||||||
case Token::TOKEN_OBJECT_BEGIN:
|
|
||||||
{
|
|
||||||
// implicit non-const cast will perform conversion for us (if necessary)
|
|
||||||
Object& object = element;
|
|
||||||
Parse(object, tokenStream);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Token::TOKEN_ARRAY_BEGIN:
|
|
||||||
{
|
|
||||||
Array& array = element;
|
|
||||||
Parse(array, tokenStream);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Token::TOKEN_STRING:
|
|
||||||
{
|
|
||||||
String& string = element;
|
|
||||||
Parse(string, tokenStream);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Token::TOKEN_NUMBER:
|
|
||||||
{
|
|
||||||
Number& number = element;
|
|
||||||
Parse(number, tokenStream);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Token::TOKEN_BOOLEAN:
|
|
||||||
{
|
|
||||||
Boolean& boolean = element;
|
|
||||||
Parse(boolean, tokenStream);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Token::TOKEN_NULL:
|
|
||||||
{
|
|
||||||
Null& null = element;
|
|
||||||
Parse(null, tokenStream);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
std::string sMessage = std::string("Unexpected token: ") + token.sValue;
|
|
||||||
throw ParseException(sMessage, token.locBegin, token.locEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Object& object, Reader::TokenStream& tokenStream)
|
|
||||||
{
|
|
||||||
MatchExpectedToken(Token::TOKEN_OBJECT_BEGIN, tokenStream);
|
|
||||||
|
|
||||||
bool bContinue = (tokenStream.EOS() == false &&
|
|
||||||
tokenStream.Peek().nType != Token::TOKEN_OBJECT_END);
|
|
||||||
while (bContinue)
|
|
||||||
{
|
|
||||||
Object::Member member;
|
|
||||||
|
|
||||||
// first the member name. save the token in case we have to throw an exception
|
|
||||||
const Token& tokenName = tokenStream.Peek();
|
|
||||||
member.name = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
|
|
||||||
|
|
||||||
// ...then the key/value separator...
|
|
||||||
MatchExpectedToken(Token::TOKEN_MEMBER_ASSIGN, tokenStream);
|
|
||||||
|
|
||||||
// ...then the value itself (can be anything).
|
|
||||||
Parse(member.element, tokenStream);
|
|
||||||
|
|
||||||
// try adding it to the object (this could throw)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
object.Insert(member);
|
|
||||||
}
|
|
||||||
catch (Exception&)
|
|
||||||
{
|
|
||||||
// must be a duplicate name
|
|
||||||
std::string sMessage = std::string("Duplicate object member token: ") + member.name;
|
|
||||||
throw ParseException(sMessage, tokenName.locBegin, tokenName.locEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
bContinue = (tokenStream.EOS() == false &&
|
|
||||||
tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT);
|
|
||||||
if (bContinue)
|
|
||||||
MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
MatchExpectedToken(Token::TOKEN_OBJECT_END, tokenStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Array& array, Reader::TokenStream& tokenStream)
|
|
||||||
{
|
|
||||||
MatchExpectedToken(Token::TOKEN_ARRAY_BEGIN, tokenStream);
|
|
||||||
|
|
||||||
bool bContinue = (tokenStream.EOS() == false &&
|
|
||||||
tokenStream.Peek().nType != Token::TOKEN_ARRAY_END);
|
|
||||||
while (bContinue)
|
|
||||||
{
|
|
||||||
// ...what's next? could be anything
|
|
||||||
Array::iterator itElement = array.Insert(UnknownElement());
|
|
||||||
UnknownElement& element = *itElement;
|
|
||||||
Parse(element, tokenStream);
|
|
||||||
|
|
||||||
bContinue = (tokenStream.EOS() == false &&
|
|
||||||
tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT);
|
|
||||||
if (bContinue)
|
|
||||||
MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
MatchExpectedToken(Token::TOKEN_ARRAY_END, tokenStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(String& string, Reader::TokenStream& tokenStream)
|
|
||||||
{
|
|
||||||
string = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Number& number, Reader::TokenStream& tokenStream)
|
|
||||||
{
|
|
||||||
const Token& currentToken = tokenStream.Peek(); // might need this later for throwing exception
|
|
||||||
const std::string& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream);
|
|
||||||
|
|
||||||
std::istringstream iStr(sValue);
|
|
||||||
double dValue;
|
|
||||||
iStr >> dValue;
|
|
||||||
|
|
||||||
// did we consume all characters in the token?
|
|
||||||
if (iStr.eof() == false)
|
|
||||||
{
|
|
||||||
char c = iStr.peek();
|
|
||||||
std::string sMessage = std::string("Unexpected character in NUMBER token: ") + c;
|
|
||||||
throw ParseException(sMessage, currentToken.locBegin, currentToken.locEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
number = dValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Boolean& boolean, Reader::TokenStream& tokenStream)
|
|
||||||
{
|
|
||||||
const std::string& sValue = MatchExpectedToken(Token::TOKEN_BOOLEAN, tokenStream);
|
|
||||||
boolean = (sValue == "true" ? true : false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Null&, Reader::TokenStream& tokenStream)
|
|
||||||
{
|
|
||||||
MatchExpectedToken(Token::TOKEN_NULL, tokenStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& Reader::MatchExpectedToken(Token::Type nExpected, Reader::TokenStream& tokenStream)
|
|
||||||
{
|
|
||||||
const Token& token = tokenStream.Get();
|
|
||||||
if (token.nType != nExpected)
|
|
||||||
{
|
|
||||||
std::string sMessage = std::string("Unexpected token: ") + token.sValue;
|
|
||||||
throw ParseException(sMessage, token.locBegin, token.locEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return token.sValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End namespace
|
|
@ -1,178 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 2009-2010, Terry Caton
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the projecct nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include "writer.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
TODO:
|
|
||||||
* better documentation
|
|
||||||
* unicode character encoding
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace json
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
inline void Writer::Write(const UnknownElement& elementRoot, std::ostream& ostr) { Write_i(elementRoot, ostr); }
|
|
||||||
inline void Writer::Write(const Object& object, std::ostream& ostr) { Write_i(object, ostr); }
|
|
||||||
inline void Writer::Write(const Array& array, std::ostream& ostr) { Write_i(array, ostr); }
|
|
||||||
inline void Writer::Write(const Number& number, std::ostream& ostr) { Write_i(number, ostr); }
|
|
||||||
inline void Writer::Write(const String& string, std::ostream& ostr) { Write_i(string, ostr); }
|
|
||||||
inline void Writer::Write(const Boolean& boolean, std::ostream& ostr) { Write_i(boolean, ostr); }
|
|
||||||
inline void Writer::Write(const Null& null, std::ostream& ostr) { Write_i(null, ostr); }
|
|
||||||
|
|
||||||
|
|
||||||
inline Writer::Writer(std::ostream& ostr) :
|
|
||||||
m_ostr(ostr),
|
|
||||||
m_nTabDepth(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
void Writer::Write_i(const ElementTypeT& element, std::ostream& ostr)
|
|
||||||
{
|
|
||||||
Writer writer(ostr);
|
|
||||||
writer.Write_i(element);
|
|
||||||
ostr.flush(); // all done
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Write_i(const Array& array)
|
|
||||||
{
|
|
||||||
if (array.Empty())
|
|
||||||
m_ostr << "[]";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_ostr << '[' << std::endl;
|
|
||||||
++m_nTabDepth;
|
|
||||||
|
|
||||||
Array::const_iterator it(array.Begin()),
|
|
||||||
itEnd(array.End());
|
|
||||||
while (it != itEnd) {
|
|
||||||
m_ostr << std::string(m_nTabDepth, '\t');
|
|
||||||
|
|
||||||
Write_i(*it);
|
|
||||||
|
|
||||||
if (++it != itEnd)
|
|
||||||
m_ostr << ',';
|
|
||||||
m_ostr << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
--m_nTabDepth;
|
|
||||||
m_ostr << std::string(m_nTabDepth, '\t') << ']';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Write_i(const Object& object)
|
|
||||||
{
|
|
||||||
if (object.Empty())
|
|
||||||
m_ostr << "{}";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_ostr << '{' << std::endl;
|
|
||||||
++m_nTabDepth;
|
|
||||||
|
|
||||||
Object::const_iterator it(object.Begin()),
|
|
||||||
itEnd(object.End());
|
|
||||||
while (it != itEnd) {
|
|
||||||
m_ostr << std::string(m_nTabDepth, '\t');
|
|
||||||
|
|
||||||
Write_i(it->name);
|
|
||||||
|
|
||||||
m_ostr << " : ";
|
|
||||||
Write_i(it->element);
|
|
||||||
|
|
||||||
if (++it != itEnd)
|
|
||||||
m_ostr << ',';
|
|
||||||
m_ostr << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
--m_nTabDepth;
|
|
||||||
m_ostr << std::string(m_nTabDepth, '\t') << '}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Write_i(const Number& numberElement)
|
|
||||||
{
|
|
||||||
m_ostr << std::setprecision(20) << numberElement.Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Write_i(const Boolean& booleanElement)
|
|
||||||
{
|
|
||||||
m_ostr << (booleanElement.Value() ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Write_i(const String& stringElement)
|
|
||||||
{
|
|
||||||
m_ostr << '"';
|
|
||||||
|
|
||||||
const std::string& s = stringElement.Value();
|
|
||||||
std::string::const_iterator it(s.begin()),
|
|
||||||
itEnd(s.end());
|
|
||||||
for (; it != itEnd; ++it)
|
|
||||||
{
|
|
||||||
switch (*it)
|
|
||||||
{
|
|
||||||
case '"': m_ostr << "\\\""; break;
|
|
||||||
case '\\': m_ostr << "\\\\"; break;
|
|
||||||
case '\b': m_ostr << "\\b"; break;
|
|
||||||
case '\f': m_ostr << "\\f"; break;
|
|
||||||
case '\n': m_ostr << "\\n"; break;
|
|
||||||
case '\r': m_ostr << "\\r"; break;
|
|
||||||
case '\t': m_ostr << "\\t"; break;
|
|
||||||
//case '\u': m_ostr << "\\u"; break; // uh...
|
|
||||||
default: m_ostr << *it; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ostr << '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Write_i(const Null& )
|
|
||||||
{
|
|
||||||
m_ostr << "null";
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Write_i(const UnknownElement& unknown)
|
|
||||||
{
|
|
||||||
unknown.Accept(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Visit(const Array& array) { Write_i(array); }
|
|
||||||
inline void Writer::Visit(const Object& object) { Write_i(object); }
|
|
||||||
inline void Writer::Visit(const Number& number) { Write_i(number); }
|
|
||||||
inline void Writer::Visit(const String& string) { Write_i(string); }
|
|
||||||
inline void Writer::Visit(const Boolean& boolean) { Write_i(boolean); }
|
|
||||||
inline void Writer::Visit(const Null& null) { Write_i(null); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // End namespace
|
|
@ -839,6 +839,7 @@ int luatpt_error(lua_State* l)
|
|||||||
free(error);
|
free(error);
|
||||||
return luaL_error(l, "Screen buffer does not exist");*/
|
return luaL_error(l, "Screen buffer does not exist");*/
|
||||||
//TODO IMPLEMENT
|
//TODO IMPLEMENT
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
int luatpt_drawtext(lua_State* l)
|
int luatpt_drawtext(lua_State* l)
|
||||||
{
|
{
|
||||||
@ -931,6 +932,7 @@ int luatpt_log(lua_State* l)
|
|||||||
return 0;*/
|
return 0;*/
|
||||||
//luacon_ci->lastError = luaL_optstring(l, 1, "");
|
//luacon_ci->lastError = luaL_optstring(l, 1, "");
|
||||||
//TODO IMPLEMENT - Have some sort of error log that is visible outside the console.
|
//TODO IMPLEMENT - Have some sort of error log that is visible outside the console.
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int luatpt_set_pressure(lua_State* l)
|
int luatpt_set_pressure(lua_State* l)
|
||||||
@ -1640,6 +1642,7 @@ int luatpt_input(lua_State* l)
|
|||||||
free(shadow);
|
free(shadow);
|
||||||
return luaL_error(l, "Screen buffer does not exist");*/
|
return luaL_error(l, "Screen buffer does not exist");*/
|
||||||
//TODO IMPLEMENT
|
//TODO IMPLEMENT
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
int luatpt_message_box(lua_State* l)
|
int luatpt_message_box(lua_State* l)
|
||||||
{
|
{
|
||||||
@ -1657,6 +1660,7 @@ int luatpt_message_box(lua_State* l)
|
|||||||
free(text);
|
free(text);
|
||||||
return luaL_error(l, "Screen buffer does not exist");;*/
|
return luaL_error(l, "Screen buffer does not exist");;*/
|
||||||
//TODO IMPLEMENT
|
//TODO IMPLEMENT
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
int luatpt_get_numOfParts(lua_State* l)
|
int luatpt_get_numOfParts(lua_State* l)
|
||||||
{
|
{
|
||||||
@ -1704,6 +1708,7 @@ int luatpt_hud(lua_State* l)
|
|||||||
hud_enable = (hudstate==0?0:1);
|
hud_enable = (hudstate==0?0:1);
|
||||||
return 0;*/
|
return 0;*/
|
||||||
//TODO IMPLEMENT
|
//TODO IMPLEMENT
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
int luatpt_gravity(lua_State* l)
|
int luatpt_gravity(lua_State* l)
|
||||||
{
|
{
|
||||||
@ -1737,11 +1742,10 @@ int luatpt_active_menu(lua_State* l)
|
|||||||
}
|
}
|
||||||
int luatpt_decorations_enable(lua_State* l)
|
int luatpt_decorations_enable(lua_State* l)
|
||||||
{
|
{
|
||||||
/*int aheatstate;
|
int decostate;
|
||||||
aheatstate = luaL_optint(l, 1, 0);
|
decostate = luaL_optint(l, 1, 0);
|
||||||
decorations_enable = (aheatstate==0?0:1);
|
luacon_model->SetDecoration(decostate==0?false:true);
|
||||||
return 0;*/
|
return 0;
|
||||||
//TODO IMPLEMENT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int luatpt_heat(lua_State* l)
|
int luatpt_heat(lua_State* l)
|
||||||
@ -1753,13 +1757,13 @@ int luatpt_heat(lua_State* l)
|
|||||||
}
|
}
|
||||||
int luatpt_cmode_set(lua_State* l)
|
int luatpt_cmode_set(lua_State* l)
|
||||||
{
|
{
|
||||||
|
//TODO IMPLEMENT
|
||||||
return luaL_error(l, "Not implemented");
|
return luaL_error(l, "Not implemented");
|
||||||
}
|
}
|
||||||
int luatpt_setfire(lua_State* l)
|
int luatpt_setfire(lua_State* l)
|
||||||
{
|
{
|
||||||
int firesize = luaL_optint(l, 2, 4);
|
int firesize = luaL_optint(l, 2, 4);
|
||||||
float fireintensity = (float)luaL_optnumber(l, 1, 1.0f);
|
float fireintensity = (float)luaL_optnumber(l, 1, 1.0f);
|
||||||
//prepare_alpha(firesize, fireintensity);
|
|
||||||
luacon_model->GetRenderer()->prepare_alpha(firesize, fireintensity);
|
luacon_model->GetRenderer()->prepare_alpha(firesize, fireintensity);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1769,6 +1773,7 @@ int luatpt_setdebug(lua_State* l)
|
|||||||
debug_flags = debug;
|
debug_flags = debug;
|
||||||
return 0;*/
|
return 0;*/
|
||||||
//TODO IMPLEMENT
|
//TODO IMPLEMENT
|
||||||
|
return luaL_error(l, "Not implemented");
|
||||||
}
|
}
|
||||||
int luatpt_setfpscap(lua_State* l)
|
int luatpt_setfpscap(lua_State* l)
|
||||||
{
|
{
|
||||||
@ -1778,7 +1783,6 @@ int luatpt_setfpscap(lua_State* l)
|
|||||||
}
|
}
|
||||||
int luatpt_getscript(lua_State* l)
|
int luatpt_getscript(lua_State* l)
|
||||||
{
|
{
|
||||||
//TODO: IMPLEMENT
|
|
||||||
/*char *fileid = NULL, *filedata = NULL, *fileuri = NULL, *fileauthor = NULL, *filename = NULL, *lastError = NULL, *luacommand = NULL;
|
/*char *fileid = NULL, *filedata = NULL, *fileuri = NULL, *fileauthor = NULL, *filename = NULL, *lastError = NULL, *luacommand = NULL;
|
||||||
int len, ret,run_script;
|
int len, ret,run_script;
|
||||||
FILE * outputfile;
|
FILE * outputfile;
|
||||||
@ -1863,6 +1867,8 @@ fin:
|
|||||||
|
|
||||||
if(lastError) return luaL_error(l, lastError);
|
if(lastError) return luaL_error(l, lastError);
|
||||||
return 0;*/
|
return 0;*/
|
||||||
|
//TODO IMPLEMENT
|
||||||
|
return luaL_error(l, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
int luatpt_setwindowsize(lua_State* l)
|
int luatpt_setwindowsize(lua_State* l)
|
||||||
@ -1874,6 +1880,7 @@ int luatpt_setwindowsize(lua_State* l)
|
|||||||
lua_pushnumber(l, result);
|
lua_pushnumber(l, result);
|
||||||
return 1;*/
|
return 1;*/
|
||||||
//TODO Implement
|
//TODO Implement
|
||||||
|
return luaL_error(l, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
int luatpt_screenshot(lua_State* l)
|
int luatpt_screenshot(lua_State* l)
|
||||||
@ -1892,6 +1899,6 @@ int luatpt_screenshot(lua_State* l)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}*/
|
}*/
|
||||||
return luaL_error(l, "Screen buffer does not exist");
|
return luaL_error(l, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,6 +282,16 @@ void GameController::SetPaused()
|
|||||||
gameModel->SetPaused(!gameModel->GetPaused());
|
gameModel->SetPaused(!gameModel->GetPaused());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameController::SetDecoration(bool decorationState)
|
||||||
|
{
|
||||||
|
gameModel->SetDecoration(decorationState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameController::SetDecoration()
|
||||||
|
{
|
||||||
|
gameModel->SetDecoration(!gameModel->GetDecoration());
|
||||||
|
}
|
||||||
|
|
||||||
void GameController::SetActiveMenu(Menu * menu)
|
void GameController::SetActiveMenu(Menu * menu)
|
||||||
{
|
{
|
||||||
gameModel->SetActiveMenu(menu);
|
gameModel->SetActiveMenu(menu);
|
||||||
|
@ -52,6 +52,8 @@ public:
|
|||||||
void Update();
|
void Update();
|
||||||
void SetPaused(bool pauseState);
|
void SetPaused(bool pauseState);
|
||||||
void SetPaused();
|
void SetPaused();
|
||||||
|
void SetDecoration(bool decorationState);
|
||||||
|
void SetDecoration();
|
||||||
void SetActiveMenu(Menu * menu);
|
void SetActiveMenu(Menu * menu);
|
||||||
void SetActiveTool(int toolSelection, Tool * tool);
|
void SetActiveTool(int toolSelection, Tool * tool);
|
||||||
void OpenSearch();
|
void OpenSearch();
|
||||||
|
@ -19,6 +19,44 @@ GameModel::GameModel():
|
|||||||
sim = new Simulation();
|
sim = new Simulation();
|
||||||
ren = new Renderer(ui::Engine::Ref().g, sim);
|
ren = new Renderer(ui::Engine::Ref().g, sim);
|
||||||
|
|
||||||
|
//Load config into renderer
|
||||||
|
try
|
||||||
|
{
|
||||||
|
json::Number tempNumber = Client::Ref().configDocument["Renderer"]["ColourMode"];
|
||||||
|
if(tempNumber.Value())
|
||||||
|
ren->SetColourMode(tempNumber.Value());
|
||||||
|
|
||||||
|
json::Array tempArray = Client::Ref().configDocument["Renderer"]["DisplayModes"];
|
||||||
|
if(tempArray.Size())
|
||||||
|
{
|
||||||
|
std::vector<unsigned int> displayModes;
|
||||||
|
json::Array::const_iterator itDisplayModes(tempArray.Begin()), itDisplayModesEnd(tempArray.End());
|
||||||
|
for (; itDisplayModes != itDisplayModesEnd; ++itDisplayModes)
|
||||||
|
{
|
||||||
|
json::Number tempNumberI = *itDisplayModes;
|
||||||
|
displayModes.push_back(tempNumberI.Value());
|
||||||
|
}
|
||||||
|
ren->SetDisplayMode(displayModes);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempArray = Client::Ref().configDocument["Renderer"]["RenderModes"];
|
||||||
|
if(tempArray.Size())
|
||||||
|
{
|
||||||
|
std::vector<unsigned int> renderModes;
|
||||||
|
json::Array::const_iterator itRenderModes(tempArray.Begin()), itRenderModesEnd(tempArray.End());
|
||||||
|
for (; itRenderModes != itRenderModesEnd; ++itRenderModes)
|
||||||
|
{
|
||||||
|
json::Number tempNumberI = *itRenderModes;
|
||||||
|
renderModes.push_back(tempNumberI.Value());
|
||||||
|
}
|
||||||
|
ren->SetRenderMode(renderModes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(json::Exception & e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
menuList.clear();
|
menuList.clear();
|
||||||
for(int i = 0; i < 12; i++)
|
for(int i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
@ -71,6 +109,30 @@ GameModel::GameModel():
|
|||||||
|
|
||||||
GameModel::~GameModel()
|
GameModel::~GameModel()
|
||||||
{
|
{
|
||||||
|
//Save to config:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Client::Ref().configDocument["Renderer"]["ColourMode"] = json::Number(ren->GetColourMode());
|
||||||
|
|
||||||
|
((json::Array)Client::Ref().configDocument["Renderer"]["DisplayModes"]).Clear();
|
||||||
|
std::vector<unsigned int> displayModes = ren->GetDisplayMode();
|
||||||
|
for (int i = 0; i < displayModes.size(); i++)
|
||||||
|
{
|
||||||
|
Client::Ref().configDocument["Renderer"]["DisplayModes"][i] = json::Number(displayModes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
((json::Array)Client::Ref().configDocument["Renderer"]["RenderModes"]).Clear();
|
||||||
|
std::vector<unsigned int> renderModes = ren->GetRenderMode();
|
||||||
|
for (int i = 0; i < renderModes.size(); i++)
|
||||||
|
{
|
||||||
|
Client::Ref().configDocument["Renderer"]["RenderModes"][i] = json::Number(renderModes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(json::Exception & e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = 0; i < menuList.size(); i++)
|
for(int i = 0; i < menuList.size(); i++)
|
||||||
{
|
{
|
||||||
for(int j = 0; i < menuList[i]->GetToolList().size(); i++)
|
for(int j = 0; i < menuList[i]->GetToolList().size(); i++)
|
||||||
@ -277,6 +339,17 @@ bool GameModel::GetPaused()
|
|||||||
return sim->sys_pause?true:false;
|
return sim->sys_pause?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameModel::SetDecoration(bool decorationState)
|
||||||
|
{
|
||||||
|
ren->decorations_enable = decorationState?1:0;
|
||||||
|
notifyDecorationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameModel::GetDecoration()
|
||||||
|
{
|
||||||
|
return ren->decorations_enable?true:false;
|
||||||
|
}
|
||||||
|
|
||||||
void GameModel::FrameStep(int frames)
|
void GameModel::FrameStep(int frames)
|
||||||
{
|
{
|
||||||
sim->framerender += frames;
|
sim->framerender += frames;
|
||||||
@ -319,6 +392,14 @@ void GameModel::notifyPausedChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameModel::notifyDecorationChanged()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < observers.size(); i++)
|
||||||
|
{
|
||||||
|
//observers[i]->NotifyPausedChanged(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GameModel::notifyBrushChanged()
|
void GameModel::notifyBrushChanged()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < observers.size(); i++)
|
for(int i = 0; i < observers.size(); i++)
|
||||||
|
@ -45,6 +45,7 @@ private:
|
|||||||
void notifyRendererChanged();
|
void notifyRendererChanged();
|
||||||
void notifySimulationChanged();
|
void notifySimulationChanged();
|
||||||
void notifyPausedChanged();
|
void notifyPausedChanged();
|
||||||
|
void notifyDecorationChanged();
|
||||||
void notifySaveChanged();
|
void notifySaveChanged();
|
||||||
void notifyBrushChanged();
|
void notifyBrushChanged();
|
||||||
void notifyMenuListChanged();
|
void notifyMenuListChanged();
|
||||||
@ -65,6 +66,8 @@ public:
|
|||||||
void SetActiveTool(int selection, Tool * tool);
|
void SetActiveTool(int selection, Tool * tool);
|
||||||
bool GetPaused();
|
bool GetPaused();
|
||||||
void SetPaused(bool pauseState);
|
void SetPaused(bool pauseState);
|
||||||
|
bool GetDecoration();
|
||||||
|
void SetDecoration(bool decorationState);
|
||||||
void ClearSimulation();
|
void ClearSimulation();
|
||||||
vector<Menu*> GetMenuList();
|
vector<Menu*> GetMenuList();
|
||||||
vector<Tool*> GetToolList();
|
vector<Tool*> GetToolList();
|
||||||
|
@ -516,6 +516,10 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool
|
|||||||
case 'f':
|
case 'f':
|
||||||
c->FrameStep();
|
c->FrameStep();
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
if(ctrl)
|
||||||
|
c->SetDecoration();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,40 +10,7 @@
|
|||||||
RenderModel::RenderModel():
|
RenderModel::RenderModel():
|
||||||
renderer(NULL)
|
renderer(NULL)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
json::Number tempNumber = Client::Ref().configDocument["Renderer"]["ColourMode"];
|
|
||||||
if(tempNumber.Value())
|
|
||||||
renderer->SetColourMode(tempNumber.Value());
|
|
||||||
|
|
||||||
json::Array tempArray = Client::Ref().configDocument["Renderer"]["DisplayModes"];
|
|
||||||
if(tempArray.Size())
|
|
||||||
{
|
|
||||||
std::vector<unsigned int> displayModes;
|
|
||||||
json::Array::const_iterator itDisplayModes(tempArray.Begin()), itDisplayModesEnd(tempArray.End());
|
|
||||||
for (; itDisplayModes != itDisplayModesEnd; ++itDisplayModes)
|
|
||||||
{
|
|
||||||
json::Number tempNumberI = *itDisplayModes;
|
|
||||||
displayModes.push_back(tempNumberI.Value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tempArray = Client::Ref().configDocument["Renderer"]["RenderModes"];
|
|
||||||
if(tempArray.Size())
|
|
||||||
{
|
|
||||||
std::vector<unsigned int> renderModes;
|
|
||||||
json::Array::const_iterator itRenderModes(tempArray.Begin()), itRenderModesEnd(tempArray.End());
|
|
||||||
for (; itRenderModes != itRenderModesEnd; ++itRenderModes)
|
|
||||||
{
|
|
||||||
json::Number tempNumberI = *itRenderModes;
|
|
||||||
renderModes.push_back(tempNumberI.Value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(json::Exception & e)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderModel::AddObserver(RenderView * observer)
|
void RenderModel::AddObserver(RenderView * observer)
|
||||||
|
Loading…
Reference in New Issue
Block a user