mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-19 23:03:56 -07:00
Avoid cases of filenames Update years in terms and other legal(ish) documents Don't update years in license headers, since change is not meaningful Will add linter rule in seperate commit Happy recompiling everyone! Original Patch By: Nescio Comment By: Gallaecio Differential Revision: D2620 This was SVN commit r27786.
200 lines
6.3 KiB
C++
200 lines
6.3 KiB
C++
/* Copyright (C) 2021 Wildfire Games.
|
||
* This file is part of 0 A.D.
|
||
*
|
||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation, either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* 0 A.D. 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 General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
// Public interface to almost all of AtlasObject.
|
||
// (See AtlasObjectText for the rest of it).
|
||
//
|
||
// Tries to include as few headers as possible, to minimise its impact
|
||
// on compile times.
|
||
|
||
#ifndef INCLUDED_ATLASOBJECT
|
||
#define INCLUDED_ATLASOBJECT
|
||
|
||
#if defined(_WIN32)
|
||
# define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2008
|
||
#endif
|
||
|
||
#include <string>
|
||
|
||
class wxString;
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// Mostly-private bits:
|
||
|
||
// Helper class to let us define a conversion operator only for AtSmartPtr<not const>
|
||
template<class ConstSmPtr, class T> struct ConstCastHelper { operator ConstSmPtr (); };
|
||
template<class ConstSmPtr, class T> struct ConstCastHelper<ConstSmPtr, const T> { };
|
||
|
||
// Simple reference-counted pointer. class T must contain a reference count,
|
||
// initialised to 0. An external implementation (in AtlasObjectImpl.cpp)
|
||
// provides the inc_ref and dec_ref methods, so that this header file doesn't
|
||
// need to know their implementations.
|
||
template<class T> class AtSmartPtr : public ConstCastHelper<AtSmartPtr<const T>, T>
|
||
{
|
||
friend struct ConstCastHelper<AtSmartPtr<const T>, T>;
|
||
private:
|
||
void inc_ref();
|
||
void dec_ref();
|
||
T* ptr;
|
||
public:
|
||
// Constructors
|
||
AtSmartPtr() : ptr(NULL) {}
|
||
explicit AtSmartPtr(T* p) : ptr(p) { inc_ref(); }
|
||
// Copy constructor
|
||
AtSmartPtr(const AtSmartPtr<T>& r) : ptr(r.ptr) { inc_ref(); }
|
||
// Assignment operators
|
||
AtSmartPtr<T>& operator=(T* p) { dec_ref(); ptr = p; inc_ref(); return *this; }
|
||
AtSmartPtr<T>& operator=(const AtSmartPtr<T>& r) { if (&r != this) { dec_ref(); ptr = r.ptr; inc_ref(); } return *this; }
|
||
// Destructor
|
||
~AtSmartPtr() { dec_ref(); }
|
||
// Allow conversion from non-const T* to const T*
|
||
//operator AtSmartPtr<const T> () { return AtSmartPtr<const T>(ptr); } // (actually provided by ConstCastHelper)
|
||
// Override ->
|
||
T* operator->() const { return ptr; }
|
||
// Test whether the pointer is pointing to anything
|
||
explicit operator bool() const { return ptr != nullptr; }
|
||
};
|
||
|
||
template<class ConstSmPtr, class T>
|
||
ConstCastHelper<ConstSmPtr, T>::operator ConstSmPtr ()
|
||
{
|
||
return ConstSmPtr(static_cast<AtSmartPtr<T>*>(this)->ptr);
|
||
}
|
||
|
||
// A few required declarations
|
||
class AtObj;
|
||
class AtNode;
|
||
class AtIterImpl;
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// Public bits:
|
||
|
||
|
||
// AtIter is an iterator over AtObjs - use it like:
|
||
//
|
||
// for (AtIter thing = whatever["thing"]; thing.defined(); ++thing)
|
||
// DoStuff(thing);
|
||
//
|
||
// to handle XML data like:
|
||
//
|
||
// <whatever>
|
||
// <thing>Stuff 1</thing>
|
||
// <thing>Stuff 2</thing>
|
||
// </whatever>
|
||
|
||
class AtIter
|
||
{
|
||
public:
|
||
// Increment the iterator; or make it undefined, if there weren't any
|
||
// AtObjs left to iterate over
|
||
AtIter& operator++ ();
|
||
// Return whether this iterator has an AtObj to point to
|
||
bool defined() const;
|
||
// Return whether this iterator is pointing to a non-contentless AtObj
|
||
bool hasContent() const;
|
||
// Return the number of AtObjs that will be iterated over (including the current one)
|
||
size_t count() const;
|
||
|
||
// Return an iterator to the children matching 'key'. (That is, children
|
||
// of the AtObj currently pointed to by this iterator)
|
||
const AtIter operator[] (const char* key) const;
|
||
|
||
// Return the AtObj currently pointed to by this iterator
|
||
const AtObj operator* () const;
|
||
|
||
// Return the string value of the AtObj currently pointed to by this iterator
|
||
operator const char* () const;
|
||
|
||
// Private implementation. (But not 'private:', because it's a waste of time
|
||
// adding loads of friend functions)
|
||
AtSmartPtr<AtIterImpl> m_Impl;
|
||
};
|
||
|
||
|
||
class AtObj
|
||
{
|
||
public:
|
||
AtObj() {}
|
||
AtObj(const AtObj& r) : m_Node(r.m_Node) {}
|
||
AtObj& operator=(const AtObj& r)
|
||
{
|
||
m_Node = r.m_Node;
|
||
return *this;
|
||
}
|
||
|
||
// Return an iterator to the children matching 'key'
|
||
const AtIter operator[] (const char* key) const;
|
||
|
||
// Return the string value of this object
|
||
operator const char* () const;
|
||
|
||
// Return the floating point value of this object
|
||
double getDouble() const;
|
||
|
||
// Return the integer value of this object
|
||
int getInt() const;
|
||
long getLong() const;
|
||
|
||
// Check whether the object contains anything (even if those things are empty)
|
||
bool defined() const { return static_cast<bool>(m_Node); }
|
||
|
||
// Check recursively whether there's actually any non-empty data in the object
|
||
bool hasContent() const;
|
||
|
||
// Add or set a child. The char* version creates a new AtObj with
|
||
// the appropriate string value, then uses that as the child.
|
||
//
|
||
// These alter the AtObj's internal pointer, and the pointed-to data is
|
||
// never actually altered. Copies of this AtObj (including copies stored
|
||
// inside other AtObjs) will not be affected.
|
||
void add(const char* key, const char* value);
|
||
void add(const char* key, AtObj& data);
|
||
void set(const char* key, const char* value);
|
||
void set(const char* key, AtObj& data);
|
||
void unset(const char* key);
|
||
void setBool(const char* key, bool value);
|
||
void setDouble(const char* key, double value);
|
||
void setInt(const char* key, int value);
|
||
void setString(const char* value);
|
||
void addOverlay(AtObj& data);
|
||
|
||
AtSmartPtr<const AtNode> m_Node;
|
||
};
|
||
|
||
|
||
// Miscellaneous utility functions:
|
||
namespace AtlasObject
|
||
{
|
||
// Returns AtObj() on failure - test with AtObj::defined()
|
||
AtObj LoadFromXML(const std::string& xml);
|
||
|
||
// Returns AtObj() on failure - test with AtObj::defined()
|
||
AtObj LoadFromJSON(const std::string& json);
|
||
|
||
// Returns UTF-8-encoded XML document string.
|
||
// Returns empty string on failure.
|
||
std::string SaveToXML(AtObj& obj);
|
||
|
||
// Returns UTF-8-encoded JSON string.
|
||
// Returns empty string on failure.
|
||
std::string SaveToJSON(AtObj& obj);
|
||
|
||
AtObj TrimEmptyChildren(AtObj& obj);
|
||
}
|
||
|
||
#endif // INCLUDED_ATLASOBJECT
|