<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *	  if any, must include the following acknowledgment:
 *		 "This product includes software developed by the
 *		  Apache Software Foundation (http://www.apache.org/)."
 *	  Alternately, this acknowledgment may appear in the software itself,
 *	  if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *	  not be used to endorse or promote products derived from this
 *	  software without prior written permission. For written
 *	  permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *	  nor may "Apache" appear in their name, without prior written
 *	  permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(XercesPARSERLIAISON_HEADER_GUARD_1357924680)
#define XercesPARSERLIAISON_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <XercesParserLiaison/XercesParserLiaisonDefinitions.hpp>

// Standard Library header files.
#include <map>

// Xerces DOM header files
#include <util/XercesDefs.hpp>
#include <sax/ErrorHandler.hpp>
#include <dom/DOM_Document.hpp>

// Base class header file.
#include <XMLSupport/XMLParserLiaison.hpp>

class DOMParser;
class DOMSupport;
class EntityResolver;
class InputSource;
class SAXParser;
class XercesDOMSupport;
class XercesDocumentBridge;
class XSLProcessor;

class XALAN_XERCESPARSERLIAISON_EXPORT XercesParserLiaison : public XMLParserLiaison, public ErrorHandler
{
public:

	/**
	 * Construct a XercesParserLiaison instance.
	 *
	 * @param theSupport instance of DOMSupport object
	 * @param theStartingNumber the starting number for documents
	 *
	 * @deprecated This constructor is deprecated.  Use the next constructor instead.
	 */
	XercesParserLiaison(
			XercesDOMSupport&	theSupport,
			DocumentNumberType	theStartingNumber);

	/**
	 * Construct a XercesParserLiaison instance.
	 *
	 * @param theStartingNumber the starting number for documents
	 */
	XercesParserLiaison(DocumentNumberType	theStartingNumber = 0);

	virtual
	~XercesParserLiaison();

	// These interfaces are inherited from XMLParserLiaison...

	virtual void
	reset();

	virtual ExecutionContext*
	getExecutionContext() const;

	virtual void
	setExecutionContext(ExecutionContext&	theContext);

	virtual XalanDocument*
	parseXMLStream(
			const InputSource&		reader,
			const XalanDOMString&	identifier = XalanDOMString());

	virtual void
	parseXMLStream(
			const InputSource&		urlInputSource,
			DocumentHandler&		handler,
			const XalanDOMString&	identifier = XalanDOMString());

	// Create a non-thread safe document, with no synchronization and no bridge...
	virtual XalanDocument*
	createDocument();

	// Create a non-thread safe document, with no synchronization and no bridge...
	virtual XalanDocument*
	createDOMFactory();

	virtual void
	destroyDocument(XalanDocument*	theDocument);

	virtual DocumentNumberType
	getNextDocumentNumber();

	virtual int
	getIndent() const;

	virtual void
	setIndent(int	i);

	virtual bool
	getUseValidation() const;

	virtual void
	setUseValidation(bool	b);

	virtual const XalanDOMString
	getParserDescription() const;

	virtual EntityResolver*
	getEntityResolver() const;

	virtual void
	setEntityResolver(EntityResolver*	resolver);

	// These interfaces are new to XercesParserLiaison...

	/** Get the 'include ignorable whitespace' flag.
	  *
	  * This method returns the state of the parser's include ignorable
	  * whitespace flag.
	  *
	  * @return 'true' if the include ignorable whitespace flag is set on
	  * 		the parser, 'false' otherwise.
	  *
	  * @see #setIncludeIgnorableWhitespace
	  */
	virtual bool
	getIncludeIgnorableWhitespace() const;

	/** Set the 'include ignorable whitespace' flag
	  *
	  * This method allows the user to specify whether a validating parser
	  * should include ignorable whitespaces as text nodes.  It has no effect
	  * on non-validating parsers which always include non-markup text.
	  *
When set to true (also the default), ignorable whitespaces will be
	  * added to the DOM tree as text nodes.  The method
	  * DOM_Text::isIgnorableWhitespace() will return true for those text
	  * nodes only.
	  *
When set to false, all ignorable whitespace will be discarded and
	  * no text node is added to the DOM tree.	Note: applications intended
	  * to process the "xml:space" attribute should not set this flag to false.
	  *
	  * @param include The new state of the include ignorable whitespace
	  * 			   flag.
	  *
	  * @see #getIncludeIgnorableWhitespace
	  */
	virtual void
	setIncludeIgnorableWhitespace(bool	include);

	/**
	  * This method returns the installed error handler.
	  *
	  * @return A pointer to the installed error handler object.
	  */
	virtual ErrorHandler*
	getErrorHandler() const;

	/**
	  * This method installs the user specified error handler on
	  * the parser.
	  *
	  * @param handler A pointer to the error handler to be called
	  * 			   when the parser comes across 'error' events
	  * 			   as per the SAX specification.
	  */
	virtual void
	setErrorHandler(ErrorHandler*	handler);

	/**
	  * This method returns the state of the parser's namespace
	  * handling capability.
	  *
	  * @return true, if the parser is currently configured to
	  * 		understand namespaces, false otherwise.
	  *
	  * @see #setDoNamespaces
	  */
	virtual bool
	getDoNamespaces() const;

	/**
	  * This method allows users to enable or disable the parser's
	  * namespace processing. When set to true, parser starts enforcing
	  * all the constraints / rules specified by the NameSpace
	  * specification.
	  *
	  *
The parser's default state is: false.

	  *
	  *
This flag is ignored by the underlying scanner if the installed
	  * validator indicates that namespace constraints should be
	  * enforced.

	  *
	  * @param newState The value specifying whether NameSpace rules should
	  * 				be enforced or not.
	  *
	  * @see #getDoNamespaces
	  */
	virtual void
	setDoNamespaces(bool	newState);

	/**
	  * This method returns the state of the parser's
	  * exit-on-First-Fatal-Error flag.
	  *
	  * @return true, if the parser is currently configured to
	  * 		exit on the first fatal error, false otherwise.
	  *
	  * @see #setExitOnFirstFatalError
	  */
	virtual bool
	getExitOnFirstFatalError() const;

	/**
	  * This method allows users to set the parser's behaviour when it
	  * encounters the first fatal error. If set to true, the parser
	  * will exit at the first fatal error. If false, then it will
	  * report the error and continue processing.
	  *
	  *
The default value is 'true' and the parser exits on the
	  * first fatal error.

	  *
	  * @param newState The value specifying whether the parser should
	  * 				continue or exit when it encounters the first
	  * 				fatal error.
	  *
	  * @see #getExitOnFirstFatalError
	  */
	virtual void
	setExitOnFirstFatalError(bool	newState);

	/**
	 * Create a XalanDocument proxy for an existing Xerces document.
	 * The parser liaison owns the instance, and you must not delete
	 * it.	The liaison will delete it when reset() is called, or the
	 * liaison is destroyed.
	 *
	 * @param theXercesDocument The Xerces document.
	 * @param threadSafe If true, read access to the tree will be thread-safe (implies buildBridge == true).
	 * @param buildBridge If true, the entire bridge structure is built.
	 * @return a pointer to a new XalanDocument-derived instance.
	 */
	virtual XalanDocument*
	createDocument(
			const DOM_Document&		theXercesDocument,
			bool					threadSafe = false,
			bool					buildBridge = false);

	/**
	 * Map a pointer to a XalanDocument instance to its implementation
	 * class pointer.  Normally, you should have no reason for doing
	 * this.  The liaison will return a null pointer if it did not
	 * create the instance passed.
	 *
	 * @param theDocument A pointer to a XalanDocument instance.
	 * @return A pointer to the XercesDocumentBridge instance.
	 */
	XercesDocumentBridge*
	mapDocument(const XalanDocument*	theDocument) const;

	/**
	 * Map a pointer to a XalanDocument instance to its corresponding
	 * class pointer.  Normally, you should have no reason for doing
	 * this.  The liaison will return a null pointer if it did not
	 * create the instance passed.
	 *
	 * @param theDocument A pointer to a XalanDocument instance.
	 * @return A pointer to the XercesDocumentBridge instance.
	 */
	DOM_Document
	mapXercesDocument(const XalanDocument*	theDocument) const;

	// Implementations for SAX ErrorHandler

	virtual void
	warning(const SAXParseException& exception);

	virtual void
	error(const SAXParseException& exception);

	virtual void
	fatalError(const SAXParseException& exception);

	virtual void
	resetErrors();

#if defined(XALAN_NO_NAMESPACES)
	typedef map<const XalanDocument*,
				XercesDocumentBridge*,
				less<const XalanDocument*> >	DocumentMapType;
#else
	typedef std::map<const XalanDocument*,
					 XercesDocumentBridge*>		DocumentMapType;
#endif

	/**
	 * This functions returns the state of the liaison's build-bridge-nodes flag.
	 *
	 * @return true, if the bridge nodes are automatically built, false otherwise.
	 */
	bool
	getBuildBridgeNodes() const

	{
		return m_buildBridge;
	}

	/**
	 * This functions sets the state of the liaison's build-bridge-nodes flag.
	 * This flag must be set for the document to be thread safe.  It can also be
	 * set to true to increase performance.  If this flag is set to false, then
	 * the thread-safe flag will also be set to false.
	 *
	 * @param newState The new state for the flag.
	 *
	 */
	void
	setBuildBridgeNodes(bool	newState)
	{
		m_buildBridge = newState;

		if (newState == false)
		{
			m_threadSafe = false;
		}
	}

	/**
	 * This functions returns the state of the liaison's thread-safe flag.
	 * If true, documents created will be safe when data is read.  By default,
	 * documents are _not_ thread-safe.
	 *
	 * Note -- modifications are _never_ synchronized.
	 *
	 * @return true, if the new documents will be thread safe, false otherwise.
	 */
	bool
	getThreadSafe() const

	{
		return m_threadSafe;
	}

	/**
	 * This functions sets the state of the liaison's thread-safe flag.
	 * This flag must be set for the document to be thread safe.  If this
	 * flag is set to true, then the build-bridge-nodes flag will also be
	 * set to true.
	 *
	 * @param newState The new state for the flag.
	 *
	 */
	void
	setThreadSafe(bool	newState)
	{
		m_threadSafe = newState;

		if (m_threadSafe == true)
		{
			m_buildBridge = true;
		}
	}

	DocumentNumberType
	getDocumentNumber() const
	{
		return m_documentNumber;
	}

protected:

	static void
	formatErrorMessage(
			const SAXParseException&	e,
			XalanDOMString&				theMessage);

	virtual DOMParser*
	CreateDOMParser();

	virtual SAXParser*
	CreateSAXParser();

	/**
	 * Create a XalanDocument proxy for an existing Xerces document.
	 *
	 * @param theXercesDocument The Xerces document.
	 * @param threadSafe If true, read access to the tree will be thread-safe (implies buildBridge == true).
	 * @param buildBridge If true, the entire bridge structure is built.
	 * @return a pointer to a new XercesDocumentBridge instance.
	 */
	virtual XercesDocumentBridge*
	doCreateDocument(
			const DOM_Document&		theXercesDocument,
			bool					threadSafe,
			bool					buildBridge);

private:

	// Data members...
	unsigned long		m_documentNumber;

	int 				m_indent;

	bool				m_useValidation;

	bool				m_includeIgnorableWhitespace;

	bool				m_doNamespaces;

	bool				m_exitOnFirstFatalError;

	EntityResolver* 	m_entityResolver;

	ErrorHandler*		m_errorHandler;

	DocumentMapType 	m_documentMap;

	bool				m_buildBridge;

	bool				m_threadSafe;

	ExecutionContext*	m_executionContext;
};

#endif	// XercesPARSERLIAISON_HEADER_GUARD_1357924680
<commit_msg>Added default for parameter.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *	  if any, must include the following acknowledgment:
 *		 "This product includes software developed by the
 *		  Apache Software Foundation (http://www.apache.org/)."
 *	  Alternately, this acknowledgment may appear in the software itself,
 *	  if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *	  not be used to endorse or promote products derived from this
 *	  software without prior written permission. For written
 *	  permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *	  nor may "Apache" appear in their name, without prior written
 *	  permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(XercesPARSERLIAISON_HEADER_GUARD_1357924680)
#define XercesPARSERLIAISON_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <XercesParserLiaison/XercesParserLiaisonDefinitions.hpp>

// Standard Library header files.
#include <map>

// Xerces DOM header files
#include <util/XercesDefs.hpp>
#include <sax/ErrorHandler.hpp>
#include <dom/DOM_Document.hpp>

// Base class header file.
#include <XMLSupport/XMLParserLiaison.hpp>

class DOMParser;
class DOMSupport;
class EntityResolver;
class InputSource;
class SAXParser;
class XercesDOMSupport;
class XercesDocumentBridge;
class XSLProcessor;

class XALAN_XERCESPARSERLIAISON_EXPORT XercesParserLiaison : public XMLParserLiaison, public ErrorHandler
{
public:

	/**
	 * Construct a XercesParserLiaison instance.
	 *
	 * @param theSupport instance of DOMSupport object
	 * @param theStartingNumber the starting number for documents
	 *
	 * @deprecated This constructor is deprecated.  Use the next constructor instead.
	 */
	XercesParserLiaison(
			XercesDOMSupport&	theSupport,
			DocumentNumberType	theStartingNumber = 0);

	/**
	 * Construct a XercesParserLiaison instance.
	 *
	 * @param theStartingNumber the starting number for documents
	 */
	XercesParserLiaison(DocumentNumberType	theStartingNumber = 0);

	virtual
	~XercesParserLiaison();

	// These interfaces are inherited from XMLParserLiaison...

	virtual void
	reset();

	virtual ExecutionContext*
	getExecutionContext() const;

	virtual void
	setExecutionContext(ExecutionContext&	theContext);

	virtual XalanDocument*
	parseXMLStream(
			const InputSource&		reader,
			const XalanDOMString&	identifier = XalanDOMString());

	virtual void
	parseXMLStream(
			const InputSource&		urlInputSource,
			DocumentHandler&		handler,
			const XalanDOMString&	identifier = XalanDOMString());

	// Create a non-thread safe document, with no synchronization and no bridge...
	virtual XalanDocument*
	createDocument();

	// Create a non-thread safe document, with no synchronization and no bridge...
	virtual XalanDocument*
	createDOMFactory();

	virtual void
	destroyDocument(XalanDocument*	theDocument);

	virtual DocumentNumberType
	getNextDocumentNumber();

	virtual int
	getIndent() const;

	virtual void
	setIndent(int	i);

	virtual bool
	getUseValidation() const;

	virtual void
	setUseValidation(bool	b);

	virtual const XalanDOMString
	getParserDescription() const;

	virtual EntityResolver*
	getEntityResolver() const;

	virtual void
	setEntityResolver(EntityResolver*	resolver);

	// These interfaces are new to XercesParserLiaison...

	/** Get the 'include ignorable whitespace' flag.
	  *
	  * This method returns the state of the parser's include ignorable
	  * whitespace flag.
	  *
	  * @return 'true' if the include ignorable whitespace flag is set on
	  * 		the parser, 'false' otherwise.
	  *
	  * @see #setIncludeIgnorableWhitespace
	  */
	virtual bool
	getIncludeIgnorableWhitespace() const;

	/** Set the 'include ignorable whitespace' flag
	  *
	  * This method allows the user to specify whether a validating parser
	  * should include ignorable whitespaces as text nodes.  It has no effect
	  * on non-validating parsers which always include non-markup text.
	  *
When set to true (also the default), ignorable whitespaces will be
	  * added to the DOM tree as text nodes.  The method
	  * DOM_Text::isIgnorableWhitespace() will return true for those text
	  * nodes only.
	  *
When set to false, all ignorable whitespace will be discarded and
	  * no text node is added to the DOM tree.	Note: applications intended
	  * to process the "xml:space" attribute should not set this flag to false.
	  *
	  * @param include The new state of the include ignorable whitespace
	  * 			   flag.
	  *
	  * @see #getIncludeIgnorableWhitespace
	  */
	virtual void
	setIncludeIgnorableWhitespace(bool	include);

	/**
	  * This method returns the installed error handler.
	  *
	  * @return A pointer to the installed error handler object.
	  */
	virtual ErrorHandler*
	getErrorHandler() const;

	/**
	  * This method installs the user specified error handler on
	  * the parser.
	  *
	  * @param handler A pointer to the error handler to be called
	  * 			   when the parser comes across 'error' events
	  * 			   as per the SAX specification.
	  */
	virtual void
	setErrorHandler(ErrorHandler*	handler);

	/**
	  * This method returns the state of the parser's namespace
	  * handling capability.
	  *
	  * @return true, if the parser is currently configured to
	  * 		understand namespaces, false otherwise.
	  *
	  * @see #setDoNamespaces
	  */
	virtual bool
	getDoNamespaces() const;

	/**
	  * This method allows users to enable or disable the parser's
	  * namespace processing. When set to true, parser starts enforcing
	  * all the constraints / rules specified by the NameSpace
	  * specification.
	  *
	  *
The parser's default state is: false.

	  *
	  *
This flag is ignored by the underlying scanner if the installed
	  * validator indicates that namespace constraints should be
	  * enforced.

	  *
	  * @param newState The value specifying whether NameSpace rules should
	  * 				be enforced or not.
	  *
	  * @see #getDoNamespaces
	  */
	virtual void
	setDoNamespaces(bool	newState);

	/**
	  * This method returns the state of the parser's
	  * exit-on-First-Fatal-Error flag.
	  *
	  * @return true, if the parser is currently configured to
	  * 		exit on the first fatal error, false otherwise.
	  *
	  * @see #setExitOnFirstFatalError
	  */
	virtual bool
	getExitOnFirstFatalError() const;

	/**
	  * This method allows users to set the parser's behaviour when it
	  * encounters the first fatal error. If set to true, the parser
	  * will exit at the first fatal error. If false, then it will
	  * report the error and continue processing.
	  *
	  *
The default value is 'true' and the parser exits on the
	  * first fatal error.

	  *
	  * @param newState The value specifying whether the parser should
	  * 				continue or exit when it encounters the first
	  * 				fatal error.
	  *
	  * @see #getExitOnFirstFatalError
	  */
	virtual void
	setExitOnFirstFatalError(bool	newState);

	/**
	 * Create a XalanDocument proxy for an existing Xerces document.
	 * The parser liaison owns the instance, and you must not delete
	 * it.	The liaison will delete it when reset() is called, or the
	 * liaison is destroyed.
	 *
	 * @param theXercesDocument The Xerces document.
	 * @param threadSafe If true, read access to the tree will be thread-safe (implies buildBridge == true).
	 * @param buildBridge If true, the entire bridge structure is built.
	 * @return a pointer to a new XalanDocument-derived instance.
	 */
	virtual XalanDocument*
	createDocument(
			const DOM_Document&		theXercesDocument,
			bool					threadSafe = false,
			bool					buildBridge = false);

	/**
	 * Map a pointer to a XalanDocument instance to its implementation
	 * class pointer.  Normally, you should have no reason for doing
	 * this.  The liaison will return a null pointer if it did not
	 * create the instance passed.
	 *
	 * @param theDocument A pointer to a XalanDocument instance.
	 * @return A pointer to the XercesDocumentBridge instance.
	 */
	XercesDocumentBridge*
	mapDocument(const XalanDocument*	theDocument) const;

	/**
	 * Map a pointer to a XalanDocument instance to its corresponding
	 * class pointer.  Normally, you should have no reason for doing
	 * this.  The liaison will return a null pointer if it did not
	 * create the instance passed.
	 *
	 * @param theDocument A pointer to a XalanDocument instance.
	 * @return A pointer to the XercesDocumentBridge instance.
	 */
	DOM_Document
	mapXercesDocument(const XalanDocument*	theDocument) const;

	// Implementations for SAX ErrorHandler

	virtual void
	warning(const SAXParseException& exception);

	virtual void
	error(const SAXParseException& exception);

	virtual void
	fatalError(const SAXParseException& exception);

	virtual void
	resetErrors();

#if defined(XALAN_NO_NAMESPACES)
	typedef map<const XalanDocument*,
				XercesDocumentBridge*,
				less<const XalanDocument*> >	DocumentMapType;
#else
	typedef std::map<const XalanDocument*,
					 XercesDocumentBridge*>		DocumentMapType;
#endif

	/**
	 * This functions returns the state of the liaison's build-bridge-nodes flag.
	 *
	 * @return true, if the bridge nodes are automatically built, false otherwise.
	 */
	bool
	getBuildBridgeNodes() const

	{
		return m_buildBridge;
	}

	/**
	 * This functions sets the state of the liaison's build-bridge-nodes flag.
	 * This flag must be set for the document to be thread safe.  It can also be
	 * set to true to increase performance.  If this flag is set to false, then
	 * the thread-safe flag will also be set to false.
	 *
	 * @param newState The new state for the flag.
	 *
	 */
	void
	setBuildBridgeNodes(bool	newState)
	{
		m_buildBridge = newState;

		if (newState == false)
		{
			m_threadSafe = false;
		}
	}

	/**
	 * This functions returns the state of the liaison's thread-safe flag.
	 * If true, documents created will be safe when data is read.  By default,
	 * documents are _not_ thread-safe.
	 *
	 * Note -- modifications are _never_ synchronized.
	 *
	 * @return true, if the new documents will be thread safe, false otherwise.
	 */
	bool
	getThreadSafe() const

	{
		return m_threadSafe;
	}

	/**
	 * This functions sets the state of the liaison's thread-safe flag.
	 * This flag must be set for the document to be thread safe.  If this
	 * flag is set to true, then the build-bridge-nodes flag will also be
	 * set to true.
	 *
	 * @param newState The new state for the flag.
	 *
	 */
	void
	setThreadSafe(bool	newState)
	{
		m_threadSafe = newState;

		if (m_threadSafe == true)
		{
			m_buildBridge = true;
		}
	}

	DocumentNumberType
	getDocumentNumber() const
	{
		return m_documentNumber;
	}

protected:

	static void
	formatErrorMessage(
			const SAXParseException&	e,
			XalanDOMString&				theMessage);

	virtual DOMParser*
	CreateDOMParser();

	virtual SAXParser*
	CreateSAXParser();

	/**
	 * Create a XalanDocument proxy for an existing Xerces document.
	 *
	 * @param theXercesDocument The Xerces document.
	 * @param threadSafe If true, read access to the tree will be thread-safe (implies buildBridge == true).
	 * @param buildBridge If true, the entire bridge structure is built.
	 * @return a pointer to a new XercesDocumentBridge instance.
	 */
	virtual XercesDocumentBridge*
	doCreateDocument(
			const DOM_Document&		theXercesDocument,
			bool					threadSafe,
			bool					buildBridge);

private:

	// Data members...
	unsigned long		m_documentNumber;

	int 				m_indent;

	bool				m_useValidation;

	bool				m_includeIgnorableWhitespace;

	bool				m_doNamespaces;

	bool				m_exitOnFirstFatalError;

	EntityResolver* 	m_entityResolver;

	ErrorHandler*		m_errorHandler;

	DocumentMapType 	m_documentMap;

	bool				m_buildBridge;

	bool				m_threadSafe;

	ExecutionContext*	m_executionContext;
};

#endif	// XercesPARSERLIAISON_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <iostream>
#include <memory>
#include <string>

#include <grpc/support/log.h>
#include <grpcpp/grpcpp.h>

#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif

using grpc::Channel;
using grpc::ClientAsyncResponseReader;
using grpc::ClientContext;
using grpc::CompletionQueue;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;

class GreeterClient {
 public:
  explicit GreeterClient(std::shared_ptr<Channel> channel)
      : stub_(Greeter::NewStub(channel)) {}

  // Assembles the client's payload, sends it and presents the response back
  // from the server.
  std::string SayHello(const std::string& user) {
    // Data we are sending to the server.
    HelloRequest request;
    request.set_name(user);

    // Container for the data we expect from the server.
    HelloReply reply;

    // Context for the client. It could be used to convey extra information to
    // the server and/or tweak certain RPC behaviors.
    ClientContext context;

    // The producer-consumer queue we use to communicate asynchronously with the
    // gRPC runtime.
    CompletionQueue cq;

    // Storage for the status of the RPC upon completion.
    Status status;

    // stub_->PrepareAsyncSayHello() creates an RPC object, returning
    // an instance to store in "call" but does not actually start the RPC
    // Because we are using the asynchronous API, we need to hold on to
    // the "call" instance in order to get updates on the ongoing RPC.
    std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
        stub_->PrepareAsyncSayHello(&context, request, &cq));

    // StartCall initiates the RPC call
    rpc->StartCall();

    // Request that, upon completion of the RPC, "reply" be updated with the
    // server's response; "status" with the indication of whether the operation
    // was successful. Tag the request with the integer 1.
    rpc->Finish(&reply, &status, (void*)1);
    void* got_tag;
    bool ok = false;
    // Block until the next result is available in the completion queue "cq".
    // The return value of Next should always be checked. This return value
    // tells us whether there is any kind of event or the cq_ is shutting down.
    GPR_ASSERT(cq.Next(&got_tag, &ok));

    // Verify that the result from "cq" corresponds, by its tag, our previous
    // request.
    GPR_ASSERT(got_tag == (void*)1);
    // ... and that the request was completed successfully. Note that "ok"
    // corresponds solely to the request for updates introduced by Finish().
    GPR_ASSERT(ok);

    // Act upon the status of the actual RPC.
    if (status.ok()) {
      return reply.message();
    } else {
      return "RPC failed";
    }
  }

 private:
  // Out of the passed in Channel comes the stub, stored here, our view of the
  // server's exposed services.
  std::unique_ptr<Greeter::Stub> stub_;
};

int main(int argc, char** argv) {
  // Instantiate the client. It requires a channel, out of which the actual RPCs
  // are created. This channel models a connection to an endpoint (in this case,
  // localhost at port 50051). We indicate that the channel isn't authenticated
  // (use of InsecureChannelCredentials()).
  GreeterClient greeter(grpc::CreateChannel(
      "localhost:50051", grpc::InsecureChannelCredentials()));
  std::string user("world");
  std::string reply = greeter.SayHello(user);  // The actual RPC call!
  std::cout << "Greeter received: " << reply << std::endl;

  return 0;
}
<commit_msg>Match the greeter async example to the tutorial (#30731)<commit_after>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <iostream>
#include <memory>
#include <string>

#include <grpc/support/log.h>
#include <grpcpp/grpcpp.h>

#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif

using grpc::Channel;
using grpc::ClientAsyncResponseReader;
using grpc::ClientContext;
using grpc::CompletionQueue;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;

class GreeterClient {
 public:
  explicit GreeterClient(std::shared_ptr<Channel> channel)
      : stub_(Greeter::NewStub(channel)) {}

  // Assembles the client's payload, sends it and presents the response back
  // from the server.
  std::string SayHello(const std::string& user) {
    // Data we are sending to the server.
    HelloRequest request;
    request.set_name(user);

    // Container for the data we expect from the server.
    HelloReply reply;

    // Context for the client. It could be used to convey extra information to
    // the server and/or tweak certain RPC behaviors.
    ClientContext context;

    // The producer-consumer queue we use to communicate asynchronously with the
    // gRPC runtime.
    CompletionQueue cq;

    // Storage for the status of the RPC upon completion.
    Status status;

    std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
        stub_->AsyncSayHello(&context, request, &cq));

    // Request that, upon completion of the RPC, "reply" be updated with the
    // server's response; "status" with the indication of whether the operation
    // was successful. Tag the request with the integer 1.
    rpc->Finish(&reply, &status, (void*)1);
    void* got_tag;
    bool ok = false;
    // Block until the next result is available in the completion queue "cq".
    // The return value of Next should always be checked. This return value
    // tells us whether there is any kind of event or the cq_ is shutting down.
    GPR_ASSERT(cq.Next(&got_tag, &ok));

    // Verify that the result from "cq" corresponds, by its tag, our previous
    // request.
    GPR_ASSERT(got_tag == (void*)1);
    // ... and that the request was completed successfully. Note that "ok"
    // corresponds solely to the request for updates introduced by Finish().
    GPR_ASSERT(ok);

    // Act upon the status of the actual RPC.
    if (status.ok()) {
      return reply.message();
    } else {
      return "RPC failed";
    }
  }

 private:
  // Out of the passed in Channel comes the stub, stored here, our view of the
  // server's exposed services.
  std::unique_ptr<Greeter::Stub> stub_;
};

int main(int argc, char** argv) {
  // Instantiate the client. It requires a channel, out of which the actual RPCs
  // are created. This channel models a connection to an endpoint (in this case,
  // localhost at port 50051). We indicate that the channel isn't authenticated
  // (use of InsecureChannelCredentials()).
  GreeterClient greeter(grpc::CreateChannel(
      "localhost:50051", grpc::InsecureChannelCredentials()));
  std::string user("world");
  std::string reply = greeter.SayHello(user);  // The actual RPC call!
  std::cout << "Greeter received: " << reply << std::endl;

  return 0;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2010-2012 Stanford University
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "TestUtil.h"
#include "ClientException.h"
#include "CoordinatorClient.h"
#include "CoordinatorService.h"
#include "MasterService.h"
#include "MembershipService.h"
#include "MockCluster.h"
#include "RamCloud.h"
#include "Recovery.h"
#include "TaskQueue.h"

namespace RAMCloud {

class CoordinatorServiceTest : public ::testing::Test {
  public:
    TestLog::Enable logEnabler;
    Context context;
    ServerConfig masterConfig;
    MockCluster cluster;
    Tub<RamCloud> ramcloud;
    CoordinatorService* service;
    MasterService* master;
    ServerId masterServerId;

    CoordinatorServiceTest()
        : logEnabler()
        , context()
        , masterConfig(ServerConfig::forTesting())
        , cluster(&context)
        , ramcloud()
        , service()
        , master()
        , masterServerId()
    {
        Logger::get().setLogLevels(RAMCloud::SILENT_LOG_LEVEL);

        service = cluster.coordinator.get();

        masterConfig.services = {WireFormat::MASTER_SERVICE,
                                 WireFormat::PING_SERVICE,
                                 WireFormat::MEMBERSHIP_SERVICE};
        masterConfig.localLocator = "mock:host=master";
        Server* masterServer = cluster.addServer(masterConfig);
        master = masterServer->master.get();
        master->objectManager.log.sync();
        masterServerId = masterServer->serverId;

        ramcloud.construct(&context, "mock:host=coordinator");
    }

    // Generate a string containing all of the service locators in a
    // list of servers.
    string
    getLocators(ProtoBuf::ServerList& serverList)
    {
        string result;
        foreach (const ProtoBuf::ServerList::Entry& server,
                serverList.server()) {
            if (result.size() != 0) {
                result += " ";
            }
            result += server.service_locator();
        }
        return result;
    }

    DISALLOW_COPY_AND_ASSIGN(CoordinatorServiceTest);
};

TEST_F(CoordinatorServiceTest, createTable_idempotence) {
    EXPECT_EQ(1UL, ramcloud->createTable("duplicate", 1));
    EXPECT_EQ(1UL, ramcloud->createTable("duplicate", 1));
    EXPECT_EQ(2UL, ramcloud->createTable("another", 1));
}

TEST_F(CoordinatorServiceTest, getServerList) {
    ServerConfig master2Config = masterConfig;
    master2Config.localLocator = "mock:host=master2";
    master2Config.services = {WireFormat::MASTER_SERVICE,
                              WireFormat::BACKUP_SERVICE,
                              WireFormat::PING_SERVICE};
    cluster.addServer(master2Config);
    ServerConfig backupConfig = masterConfig;
    backupConfig.localLocator = "mock:host=backup1";
    backupConfig.services = {WireFormat::BACKUP_SERVICE,
                             WireFormat::PING_SERVICE};
    cluster.addServer(backupConfig);
    ProtoBuf::ServerList list;
    CoordinatorClient::getServerList(&context, &list);
    EXPECT_EQ("mock:host=master mock:host=master2 mock:host=backup1",
              getLocators(list));
}

TEST_F(CoordinatorServiceTest, getServerList_backups) {
    ServerConfig master2Config = masterConfig;
    master2Config.localLocator = "mock:host=master2";
    master2Config.services = {WireFormat::MASTER_SERVICE,
                              WireFormat::BACKUP_SERVICE,
                              WireFormat::PING_SERVICE};
    cluster.addServer(master2Config);
    ServerConfig backupConfig = masterConfig;
    backupConfig.localLocator = "mock:host=backup1";
    backupConfig.services = {WireFormat::BACKUP_SERVICE,
                             WireFormat::PING_SERVICE};
    cluster.addServer(backupConfig);
    ProtoBuf::ServerList list;
    CoordinatorClient::getBackupList(&context, &list);
    EXPECT_EQ("mock:host=master2 mock:host=backup1",
            getLocators(list));
}

TEST_F(CoordinatorServiceTest, getRuntimeOption){
    Buffer value;
    ramcloud->setRuntimeOption("failRecoveryMasters", "1 2 3");
    ASSERT_EQ(3u, service->runtimeOptions.failRecoveryMasters.size());
    ramcloud->getRuntimeOption("failRecoveryMasters", &value);
    EXPECT_STREQ("1 2 3", service->getString(&value, 0,
                                            value.getTotalLength()));
    EXPECT_THROW(ramcloud->getRuntimeOption("optionNotExisting",
                                            &value),
                 ObjectDoesntExistException);
}

TEST_F(CoordinatorServiceTest, getServerList_masters) {
    ServerConfig master2Config = masterConfig;
    master2Config.localLocator = "mock:host=master2";
    master2Config.services = {WireFormat::MASTER_SERVICE,
                              WireFormat::BACKUP_SERVICE,
                              WireFormat::PING_SERVICE};
    cluster.addServer(master2Config);
    ServerConfig backupConfig = masterConfig;
    backupConfig.localLocator = "mock:host=backup1";
    backupConfig.services = {WireFormat::BACKUP_SERVICE,
                             WireFormat::PING_SERVICE};
    cluster.addServer(backupConfig);
    ProtoBuf::ServerList list;
    CoordinatorClient::getMasterList(&context, &list);
    EXPECT_EQ("mock:host=master mock:host=master2",
            getLocators(list));
}

TEST_F(CoordinatorServiceTest, getTabletMap) {
    ramcloud->createTable("foo");
    ProtoBuf::Tablets tabletMapProtoBuf;
    CoordinatorClient::getTabletMap(&context, &tabletMapProtoBuf);
    EXPECT_EQ("tablet { table_id: 1 start_key_hash: 0 "
              "end_key_hash: 18446744073709551615 "
              "state: NORMAL server_id: 1 "
              "service_locator: \"mock:host=master\" "
              "ctime_log_head_id: 0 ctime_log_head_offset: 0 }",
              tabletMapProtoBuf.ShortDebugString());
}

TEST_F(CoordinatorServiceTest, setRuntimeOption) {
    ramcloud->setRuntimeOption("failRecoveryMasters", "1 2 3");
    ASSERT_EQ(3u, service->runtimeOptions.failRecoveryMasters.size());
    EXPECT_EQ(1u, service->runtimeOptions.popFailRecoveryMasters());
    EXPECT_EQ(2u, service->runtimeOptions.popFailRecoveryMasters());
    EXPECT_EQ(3u, service->runtimeOptions.popFailRecoveryMasters());
    EXPECT_EQ(0u, service->runtimeOptions.popFailRecoveryMasters());
    EXPECT_THROW(ramcloud->setRuntimeOption("BAD", "1 2 3"),
                 ObjectDoesntExistException);
}

TEST_F(CoordinatorServiceTest, setMasterRecoveryInfo) {
    ProtoBuf::MasterRecoveryInfo info;
    info.set_min_open_segment_id(10);
    info.set_min_open_segment_epoch(1);
    CoordinatorClient::setMasterRecoveryInfo(&context, masterServerId, info);
    EXPECT_EQ(10u, service->context->coordinatorServerList->operator[](
            masterServerId).masterRecoveryInfo.min_open_segment_id());
}

TEST_F(CoordinatorServiceTest, setMasterRecoveryInfo_noSuchServer) {
    string message = "no exception";
    try {
        ProtoBuf::MasterRecoveryInfo info;
        info.set_min_open_segment_id(10);
        info.set_min_open_segment_epoch(1);
        CoordinatorClient::setMasterRecoveryInfo(&context, {999, 999}, info);
    }
    catch (const ServerNotUpException& e) {
        message = e.toSymbol();
    }
    EXPECT_EQ("STATUS_SERVER_NOT_UP", message);
}

TEST_F(CoordinatorServiceTest, verifyMembership) {
    CoordinatorClient::verifyMembership(&context, masterServerId);
    ServerId bogus(3, 2);
    EXPECT_THROW(CoordinatorClient::verifyMembership(&context, bogus, false),
                 CallerNotInClusterException);
}

TEST_F(CoordinatorServiceTest, verifyServerFailure) {
    // Case 1: server up.
    EXPECT_FALSE(service->verifyServerFailure(masterServerId));

    // Case 2: server incommunicado.
    MockTransport mockTransport(&context);
    context.transportManager->registerMock(&mockTransport, "mock2");
    ServerId deadId = service->serverList->enlistServer(
                {WireFormat::PING_SERVICE}, 100, "mock2:");
    EXPECT_TRUE(service->verifyServerFailure(deadId));
}

}  // namespace RAMCloud
<commit_msg>Fixed crash in CoordinatorServiceTest (I'm not sure why this didn't start causing problems a long time ago).<commit_after>/* Copyright (c) 2010-2012 Stanford University
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "TestUtil.h"
#include "ClientException.h"
#include "CoordinatorClient.h"
#include "CoordinatorService.h"
#include "MasterService.h"
#include "MembershipService.h"
#include "MockCluster.h"
#include "RamCloud.h"
#include "Recovery.h"
#include "TaskQueue.h"

namespace RAMCloud {

class CoordinatorServiceTest : public ::testing::Test {
  public:
    TestLog::Enable logEnabler;
    Context context;
    ServerConfig masterConfig;
    MockCluster cluster;
    Tub<RamCloud> ramcloud;
    CoordinatorService* service;
    MasterService* master;
    ServerId masterServerId;

    CoordinatorServiceTest()
        : logEnabler()
        , context()
        , masterConfig(ServerConfig::forTesting())
        , cluster(&context)
        , ramcloud()
        , service()
        , master()
        , masterServerId()
    {
        Logger::get().setLogLevels(RAMCloud::SILENT_LOG_LEVEL);

        service = cluster.coordinator.get();

        masterConfig.services = {WireFormat::MASTER_SERVICE,
                                 WireFormat::PING_SERVICE,
                                 WireFormat::MEMBERSHIP_SERVICE};
        masterConfig.localLocator = "mock:host=master";
        Server* masterServer = cluster.addServer(masterConfig);
        master = masterServer->master.get();
        master->objectManager.log.sync();
        masterServerId = masterServer->serverId;

        ramcloud.construct(&context, "mock:host=coordinator");
    }

    // Generate a string containing all of the service locators in a
    // list of servers.
    string
    getLocators(ProtoBuf::ServerList& serverList)
    {
        string result;
        foreach (const ProtoBuf::ServerList::Entry& server,
                serverList.server()) {
            if (result.size() != 0) {
                result += " ";
            }
            result += server.service_locator();
        }
        return result;
    }

    DISALLOW_COPY_AND_ASSIGN(CoordinatorServiceTest);
};

TEST_F(CoordinatorServiceTest, createTable_idempotence) {
    EXPECT_EQ(1UL, ramcloud->createTable("duplicate", 1));
    EXPECT_EQ(1UL, ramcloud->createTable("duplicate", 1));
    EXPECT_EQ(2UL, ramcloud->createTable("another", 1));
}

TEST_F(CoordinatorServiceTest, getServerList) {
    ServerConfig master2Config = masterConfig;
    master2Config.localLocator = "mock:host=master2";
    master2Config.services = {WireFormat::MASTER_SERVICE,
                              WireFormat::BACKUP_SERVICE,
                              WireFormat::PING_SERVICE};
    cluster.addServer(master2Config);
    ServerConfig backupConfig = masterConfig;
    backupConfig.localLocator = "mock:host=backup1";
    backupConfig.services = {WireFormat::BACKUP_SERVICE,
                             WireFormat::PING_SERVICE};
    cluster.addServer(backupConfig);
    ProtoBuf::ServerList list;
    CoordinatorClient::getServerList(&context, &list);
    EXPECT_EQ("mock:host=master mock:host=master2 mock:host=backup1",
              getLocators(list));
}

TEST_F(CoordinatorServiceTest, getServerList_backups) {
    ServerConfig master2Config = masterConfig;
    master2Config.localLocator = "mock:host=master2";
    master2Config.services = {WireFormat::MASTER_SERVICE,
                              WireFormat::BACKUP_SERVICE,
                              WireFormat::PING_SERVICE};
    cluster.addServer(master2Config);
    ServerConfig backupConfig = masterConfig;
    backupConfig.localLocator = "mock:host=backup1";
    backupConfig.services = {WireFormat::BACKUP_SERVICE,
                             WireFormat::PING_SERVICE};
    cluster.addServer(backupConfig);
    ProtoBuf::ServerList list;
    CoordinatorClient::getBackupList(&context, &list);
    EXPECT_EQ("mock:host=master2 mock:host=backup1",
            getLocators(list));
}

TEST_F(CoordinatorServiceTest, getRuntimeOption){
    Buffer value;
    ramcloud->setRuntimeOption("failRecoveryMasters", "1 2 3");
    ASSERT_EQ(3u, service->runtimeOptions.failRecoveryMasters.size());
    ramcloud->getRuntimeOption("failRecoveryMasters", &value);
    EXPECT_STREQ("1 2 3", service->getString(&value, 0,
                                            value.getTotalLength()));
    EXPECT_THROW(ramcloud->getRuntimeOption("optionNotExisting",
                                            &value),
                 ObjectDoesntExistException);
}

TEST_F(CoordinatorServiceTest, getServerList_masters) {
    ServerConfig master2Config = masterConfig;
    master2Config.localLocator = "mock:host=master2";
    master2Config.services = {WireFormat::MASTER_SERVICE,
                              WireFormat::BACKUP_SERVICE,
                              WireFormat::PING_SERVICE};
    cluster.addServer(master2Config);
    ServerConfig backupConfig = masterConfig;
    backupConfig.localLocator = "mock:host=backup1";
    backupConfig.services = {WireFormat::BACKUP_SERVICE,
                             WireFormat::PING_SERVICE};
    cluster.addServer(backupConfig);
    ProtoBuf::ServerList list;
    CoordinatorClient::getMasterList(&context, &list);
    EXPECT_EQ("mock:host=master mock:host=master2",
            getLocators(list));
}

TEST_F(CoordinatorServiceTest, getTabletMap) {
    ramcloud->createTable("foo");
    ProtoBuf::Tablets tabletMapProtoBuf;
    CoordinatorClient::getTabletMap(&context, &tabletMapProtoBuf);
    EXPECT_EQ("tablet { table_id: 1 start_key_hash: 0 "
              "end_key_hash: 18446744073709551615 "
              "state: NORMAL server_id: 1 "
              "service_locator: \"mock:host=master\" "
              "ctime_log_head_id: 0 ctime_log_head_offset: 0 }",
              tabletMapProtoBuf.ShortDebugString());
}

TEST_F(CoordinatorServiceTest, setRuntimeOption) {
    ramcloud->setRuntimeOption("failRecoveryMasters", "1 2 3");
    ASSERT_EQ(3u, service->runtimeOptions.failRecoveryMasters.size());
    EXPECT_EQ(1u, service->runtimeOptions.popFailRecoveryMasters());
    EXPECT_EQ(2u, service->runtimeOptions.popFailRecoveryMasters());
    EXPECT_EQ(3u, service->runtimeOptions.popFailRecoveryMasters());
    EXPECT_EQ(0u, service->runtimeOptions.popFailRecoveryMasters());
    EXPECT_THROW(ramcloud->setRuntimeOption("BAD", "1 2 3"),
                 ObjectDoesntExistException);
}

TEST_F(CoordinatorServiceTest, setMasterRecoveryInfo) {
    ProtoBuf::MasterRecoveryInfo info;
    info.set_min_open_segment_id(10);
    info.set_min_open_segment_epoch(1);
    CoordinatorClient::setMasterRecoveryInfo(&context, masterServerId, info);
    EXPECT_EQ(10u, service->context->coordinatorServerList->operator[](
            masterServerId).masterRecoveryInfo.min_open_segment_id());
}

TEST_F(CoordinatorServiceTest, setMasterRecoveryInfo_noSuchServer) {
    string message = "no exception";
    try {
        ProtoBuf::MasterRecoveryInfo info;
        info.set_min_open_segment_id(10);
        info.set_min_open_segment_epoch(1);
        CoordinatorClient::setMasterRecoveryInfo(&context, {999, 999}, info);
    }
    catch (const ServerNotUpException& e) {
        message = e.toSymbol();
    }
    EXPECT_EQ("STATUS_SERVER_NOT_UP", message);
}

TEST_F(CoordinatorServiceTest, verifyMembership) {
    CoordinatorClient::verifyMembership(&context, masterServerId);
    ServerId bogus(3, 2);
    EXPECT_THROW(CoordinatorClient::verifyMembership(&context, bogus, false),
                 CallerNotInClusterException);
}

TEST_F(CoordinatorServiceTest, verifyServerFailure) {
    // Case 1: server up.
    EXPECT_FALSE(service->verifyServerFailure(masterServerId));

    // Case 2: server incommunicado.
    MockTransport mockTransport(&context);
    context.transportManager->registerMock(&mockTransport, "mock2");
    service->serverList->haltUpdater();
    ServerId deadId = service->serverList->enlistServer(
                {WireFormat::PING_SERVICE}, 100, "mock2:");
    EXPECT_TRUE(service->verifyServerFailure(deadId));
}

}  // namespace RAMCloud
<|endoftext|>


<commit_before>/*
 * FTGL - OpenGL font library
 *
 * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
 * Copyright (c) 2008 Éric Beets <ericbeets@free.fr>
 * Copyright (c) 2008 Sam Hocevar <sam@hocevar.net>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "config.h"

#include "FTInternals.h"

static const FTBBox static_ftbbox;

FTGL_BEGIN_C_DECLS

#define C_TOR(cname, cargs, cxxname, cxxarg, cxxtype) \
    FTGLlayout* cname cargs \
    { \
        cxxname *l = new cxxname cxxarg; \
        if(l->Error()) \
        { \
            delete l; \
            return NULL; \
        } \
        FTGLlayout *ftgl = (FTGLlayout *)malloc(sizeof(FTGLlayout)); \
        ftgl->ptr = l; \
        ftgl->type = cxxtype; \
        return ftgl; \
    }

// FTSimpleLayout::FTSimpleLayout();
C_TOR(ftglCreateSimpleLayout, (), FTSimpleLayout, (), LAYOUT_SIMPLE);

#define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \
    cret cname cargs \
    { \
        if(!l || !l->ptr) \
        { \
            fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \
            cxxerr; \
        } \
        return l->ptr->cxxname cxxarg; \
    }

// FTLayout::~FTLayout();
void ftglDestroyLayout(FTGLlayout *l)
{
    if(!l || !l->ptr)
    {
        fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
        return;
    }
    delete l->ptr;
    free(l);
}

// virtual FTBBox FTLayout::BBox(const char* string)
extern "C++" {
C_FUN(static FTBBox, _ftglGetLayoutBBox, (FTGLlayout *l, const char *s),
      return static_ftbbox, BBox, (s));
}

void ftglGetLayoutBBox(FTGLlayout *l, const char * s, float c[6])
{
    FTBBox ret = _ftglGetLayoutBBox(l, s);
    FTPoint lower = ret.Lower(), upper = ret.Upper();
    c[0] = lower.Xf(); c[1] = lower.Yf(); c[2] = lower.Zf();
    c[3] = upper.Xf(); c[4] = upper.Yf(); c[5] = upper.Zf();
}

// virtual void FTLayout::Render(const char* string, int renderMode);
C_FUN(void, ftglRenderLayout, (FTGLlayout *l, const char *s, int r),
      return, Render, (s, r));

// FT_Error FTLayout::Error() const;
C_FUN(FT_Error, ftglGetLayoutError, (FTGLlayout *l), return -1, Error, ());

// void FTSimpleLayout::SetFont(FTFont *fontInit)
void ftglSetLayoutFont(FTGLlayout *l, FTGLfont *font)
{
    if(!l || !l->ptr)
    {
        fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
        return;
    }
    if(l->type != FTGL::LAYOUT_SIMPLE)
    {
        fprintf(stderr, "FTGL warning: %s not implemented for %d\n",
                        __FUNCTION__, l->type);
    }
    l->font = font;
    return dynamic_cast<FTSimpleLayout*>(l->ptr)->SetFont(font->ptr);
}

// FTFont *FTSimpleLayout::GetFont()
FTGLfont *ftglGetLayoutFont(FTGLlayout *l)
{
    if(!l || !l->ptr)
    {
        fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
        return NULL;
    }
    if(l->type != FTGL::LAYOUT_SIMPLE)
    {
        fprintf(stderr, "FTGL warning: %s not implemented for %d\n",
                        __FUNCTION__, l->type);
    }
    return l->font;
}

#undef C_FUN

#define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \
    cret cname cargs \
    { \
        if(!l || !l->ptr) \
        { \
            fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \
            cxxerr; \
        } \
        if(l->type != FTGL::LAYOUT_SIMPLE) \
        { \
            fprintf(stderr, "FTGL warning: %s not implemented for %d\n", \
                            __FUNCTION__, l->type); \
            cxxerr; \
        } \
        return dynamic_cast<FTSimpleLayout*>(l->ptr)->cxxname cxxarg; \
    }

// void FTSimpleLayout::SetLineLength(const float LineLength);
C_FUN(void, ftglSetLayoutLineLength, (FTGLlayout *l, const float length),
      return, SetLineLength, (length));

// float FTSimpleLayout::GetLineLength() const
C_FUN(float, ftglGetLayoutLineLength, (FTGLlayout *l),
      return 0.0f, GetLineLength, ());

// void FTSimpleLayout::SetAlignment(const TextAlignment Alignment)
C_FUN(void, ftglSetLayoutAlignment, (FTGLlayout *l, const int a),
      return, SetAlignment, ((FTGL::TextAlignment)a));

// TextAlignment FTSimpleLayout::GetAlignment() const
C_FUN(int, ftglGetLayoutAlignment, (FTGLlayout *l),
      return FTGL::ALIGN_LEFT, GetAlignment, ());
C_FUN(int, ftglGetLayoutAlignement, (FTGLlayout *l),
      return FTGL::ALIGN_LEFT, GetAlignment, ()); // old typo

// void FTSimpleLayout::SetLineSpacing(const float LineSpacing)
C_FUN(void, ftglSetLayoutLineSpacing, (FTGLlayout *l, const float f),
      return, SetLineSpacing, (f));

FTGL_END_C_DECLS

<commit_msg>Fix ftglRenderLayout() implementation. Fix courtesy of Tobias Gunkel. Addresses SF bug #2122839.<commit_after>/*
 * FTGL - OpenGL font library
 *
 * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
 * Copyright (c) 2008 Éric Beets <ericbeets@free.fr>
 * Copyright (c) 2008 Sam Hocevar <sam@hocevar.net>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "config.h"

#include "FTInternals.h"

static const FTBBox static_ftbbox;

FTGL_BEGIN_C_DECLS

#define C_TOR(cname, cargs, cxxname, cxxarg, cxxtype) \
    FTGLlayout* cname cargs \
    { \
        cxxname *l = new cxxname cxxarg; \
        if(l->Error()) \
        { \
            delete l; \
            return NULL; \
        } \
        FTGLlayout *ftgl = (FTGLlayout *)malloc(sizeof(FTGLlayout)); \
        ftgl->ptr = l; \
        ftgl->type = cxxtype; \
        return ftgl; \
    }

// FTSimpleLayout::FTSimpleLayout();
C_TOR(ftglCreateSimpleLayout, (), FTSimpleLayout, (), LAYOUT_SIMPLE);

#define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \
    cret cname cargs \
    { \
        if(!l || !l->ptr) \
        { \
            fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \
            cxxerr; \
        } \
        return l->ptr->cxxname cxxarg; \
    }

// FTLayout::~FTLayout();
void ftglDestroyLayout(FTGLlayout *l)
{
    if(!l || !l->ptr)
    {
        fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
        return;
    }
    delete l->ptr;
    free(l);
}

// virtual FTBBox FTLayout::BBox(const char* string)
extern "C++" {
C_FUN(static FTBBox, _ftglGetLayoutBBox, (FTGLlayout *l, const char *s),
      return static_ftbbox, BBox, (s));
}

void ftglGetLayoutBBox(FTGLlayout *l, const char * s, float c[6])
{
    FTBBox ret = _ftglGetLayoutBBox(l, s);
    FTPoint lower = ret.Lower(), upper = ret.Upper();
    c[0] = lower.Xf(); c[1] = lower.Yf(); c[2] = lower.Zf();
    c[3] = upper.Xf(); c[4] = upper.Yf(); c[5] = upper.Zf();
}

// virtual void FTLayout::Render(const char* string, int renderMode);
C_FUN(void, ftglRenderLayout, (FTGLlayout *l, const char *s, int r),
      return, Render, (s, -1, FTPoint(), r));

// FT_Error FTLayout::Error() const;
C_FUN(FT_Error, ftglGetLayoutError, (FTGLlayout *l), return -1, Error, ());

// void FTSimpleLayout::SetFont(FTFont *fontInit)
void ftglSetLayoutFont(FTGLlayout *l, FTGLfont *font)
{
    if(!l || !l->ptr)
    {
        fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
        return;
    }
    if(l->type != FTGL::LAYOUT_SIMPLE)
    {
        fprintf(stderr, "FTGL warning: %s not implemented for %d\n",
                        __FUNCTION__, l->type);
    }
    l->font = font;
    return dynamic_cast<FTSimpleLayout*>(l->ptr)->SetFont(font->ptr);
}

// FTFont *FTSimpleLayout::GetFont()
FTGLfont *ftglGetLayoutFont(FTGLlayout *l)
{
    if(!l || !l->ptr)
    {
        fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
        return NULL;
    }
    if(l->type != FTGL::LAYOUT_SIMPLE)
    {
        fprintf(stderr, "FTGL warning: %s not implemented for %d\n",
                        __FUNCTION__, l->type);
    }
    return l->font;
}

#undef C_FUN

#define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \
    cret cname cargs \
    { \
        if(!l || !l->ptr) \
        { \
            fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \
            cxxerr; \
        } \
        if(l->type != FTGL::LAYOUT_SIMPLE) \
        { \
            fprintf(stderr, "FTGL warning: %s not implemented for %d\n", \
                            __FUNCTION__, l->type); \
            cxxerr; \
        } \
        return dynamic_cast<FTSimpleLayout*>(l->ptr)->cxxname cxxarg; \
    }

// void FTSimpleLayout::SetLineLength(const float LineLength);
C_FUN(void, ftglSetLayoutLineLength, (FTGLlayout *l, const float length),
      return, SetLineLength, (length));

// float FTSimpleLayout::GetLineLength() const
C_FUN(float, ftglGetLayoutLineLength, (FTGLlayout *l),
      return 0.0f, GetLineLength, ());

// void FTSimpleLayout::SetAlignment(const TextAlignment Alignment)
C_FUN(void, ftglSetLayoutAlignment, (FTGLlayout *l, const int a),
      return, SetAlignment, ((FTGL::TextAlignment)a));

// TextAlignment FTSimpleLayout::GetAlignment() const
C_FUN(int, ftglGetLayoutAlignment, (FTGLlayout *l),
      return FTGL::ALIGN_LEFT, GetAlignment, ());
C_FUN(int, ftglGetLayoutAlignement, (FTGLlayout *l),
      return FTGL::ALIGN_LEFT, GetAlignment, ()); // old typo

// void FTSimpleLayout::SetLineSpacing(const float LineSpacing)
C_FUN(void, ftglSetLayoutLineSpacing, (FTGLlayout *l, const float f),
      return, SetLineSpacing, (f));

FTGL_END_C_DECLS

<|endoftext|>


<commit_before>
#ifndef CLIENT_H
#define CLIENT_H

class Client
{
};

#endif // CLIENT_H
<commit_msg>Delete client.hpp<commit_after><|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2012, John Haddon. All rights reserved.
//  Copyright (c) 2013, Image Engine Design Inc. 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 John Haddon nor the names of
//        any other contributors to this software 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 "Gaffer/DependencyNode.h"
#include "Gaffer/CompoundPlug.h"

using namespace Gaffer;

IE_CORE_DEFINERUNTIMETYPED( DependencyNode );

DependencyNode::DependencyNode( const std::string &name )
	:	Node( name )
{
}

DependencyNode::~DependencyNode()
{
}

void DependencyNode::affects( const Plug *input, AffectedPlugsContainer &outputs ) const
{
	if( input->isInstanceOf( CompoundPlug::staticTypeId() ) )
	{
		throw IECore::Exception( "DependencyNode::affects() called with non-leaf plug " + input->fullName() );
	}
}

BoolPlug *DependencyNode::enabledPlug()
{
	return 0;
}

const BoolPlug *DependencyNode::enabledPlug() const
{
	return 0;
}

Plug *DependencyNode::correspondingInput( const Plug *output )
{
	return 0;
}

const Plug *DependencyNode::correspondingInput( const Plug *output ) const
{
	return 0;
}
<commit_msg>DependencyNode : Remove use of CompoundPlug.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2012, John Haddon. All rights reserved.
//  Copyright (c) 2013, Image Engine Design Inc. 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 John Haddon nor the names of
//        any other contributors to this software 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 "Gaffer/DependencyNode.h"

using namespace Gaffer;

IE_CORE_DEFINERUNTIMETYPED( DependencyNode );

DependencyNode::DependencyNode( const std::string &name )
	:	Node( name )
{
}

DependencyNode::~DependencyNode()
{
}

void DependencyNode::affects( const Plug *input, AffectedPlugsContainer &outputs ) const
{
	if( !input->children().empty() )
	{
		throw IECore::Exception( "DependencyNode::affects() called with non-leaf plug " + input->fullName() );
	}
}

BoolPlug *DependencyNode::enabledPlug()
{
	return 0;
}

const BoolPlug *DependencyNode::enabledPlug() const
{
	return 0;
}

Plug *DependencyNode::correspondingInput( const Plug *output )
{
	return 0;
}

const Plug *DependencyNode::correspondingInput( const Plug *output ) const
{
	return 0;
}
<|endoftext|>


<commit_before>/************************************************************************
*
* Flood Project  (2008-201x)
* Licensed under the simplified BSD license. All rights reserved.
*
************************************************************************/

#include "Graphics/API.h"

#ifdef ENABLE_RENDERER_OPENGL

#include "Graphics/RenderDevice.h"
#include "Graphics/RenderContext.h"
#include "Graphics/RenderBackend.h"
#include "Graphics/RenderBatch.h"
#include "Graphics/RenderView.h"
#include "Graphics/ShaderProgram.h"
#include "Graphics/GeometryBuffer.h"

#include "Graphics/BufferManager.h"
#include "Graphics/ShaderProgramManager.h"
#include "Graphics/TextureManager.h"

#include "Core/Utilities.h"
#include <algorithm>

NAMESPACE_GRAPHICS_BEGIN

//-----------------------------------//

REFLECT_ENUM(RenderPipeline)
	ENUM(Fixed)
	ENUM(ShaderForward)
	ENUM(ShaderDeferred)
REFLECT_ENUM_END()

//-----------------------------------//

static RenderDevice* gs_RenderDevice = nullptr;
RenderDevice* GetRenderDevice() { return gs_RenderDevice; }

RenderDevice::RenderDevice()
	: activeContext(nullptr)
	, activeTarget(nullptr)
	, activeView(nullptr)
	, renderBackend(nullptr)
	//, shadowDepthBuffer(nullptr)
	, pipeline(RenderPipeline::ShaderForward)
{
	gs_RenderDevice = this;
}

//-----------------------------------//

RenderDevice::~RenderDevice()
{
}

//-----------------------------------//

void RenderDevice::updateRenderTargets()
{
}

//-----------------------------------//

static bool RenderStateSorter(const RenderState& lhs, const RenderState& rhs)
{
	int rA = (int) lhs.renderable->getRenderLayer();
	int rB = (int) rhs.renderable->getRenderLayer();
	int pA = lhs.priority;
	int pB = rhs.priority;

	return (rA == rB) ? (pA < pB) : (rA < rB);
}

//-----------------------------------//

void RenderDevice::render( RenderBlock& queue )
{
	#pragma TODO("Sort the render group by depth distance")

	// Sort the renderables by render group.
	std::sort( queue.renderables.begin(), queue.renderables.end(), &RenderStateSorter );

	// Render all the renderables in the queue.
	for( size_t i = 0; i < queue.renderables.size(); i++ )
	{
		const RenderState& state = queue.renderables[i];
		render(state, queue.lights);
	}
}

//-----------------------------------//

void RenderDevice::render( const RenderState& state, const LightQueue& lights )
{
	BufferManager* buffers = activeContext->bufferManager;
	ProgramManager* programs = activeContext->programManager;

	RenderBatch* renderable = state.renderable;
	bindBuffers(renderable);

	const GeometryBuffer* gb = renderable->getGeometryBuffer().get();
	if( gb->data.empty() ) return;

	BufferEntry* bufs = buffers->getBuffer(gb);

	// Setup the vertex buffer format.
	VertexBuffer* vb = bufs->vb.get();
	renderBackend->setupVertexBuffer(vb);

	Material* material = state.material;
	ShaderMaterial* shader = material->getShader().Resolve();

	ShaderProgram* shaderProgram = programs->getProgram(shader);
	if( !shaderProgram ) return;

	if( !shaderProgram->isLinked() && !shaderProgram->link() )
		return;

	shaderProgram->bind();

	renderBackend->setupRenderState(state, true);
	bindTextureUnits(state, true);

	if( !renderable->onPreRender.empty() )
	{
		// Call the user pre render hook.
		renderable->onPreRender(activeView, state);
	}

	RenderLayer stage = renderable->getRenderLayer();

	if( stage != RenderLayer::Overlays )
	{
		if( !setupRenderStateMatrix(state) )
			return;

		//if( !setupRenderStateLight(state, lights) )
		//	return;
	}
	else if( stage == RenderLayer::Overlays )
	{
		if( !setupRenderStateOverlay(state) )
			return;
	}

	UniformBuffer* ub = renderable->getUniformBuffer().get();
	shaderProgram->setUniforms(ub);

	renderBackend->renderBatch(renderable);

	if( !renderable->onPostRender.empty() )
	{
		// Call the user post render hook.
		renderable->onPostRender(activeView, state);
	}

	renderBackend->unsetupRenderState(state);
	unbindTextureUnits(state.material);

	shaderProgram->unbind();

	renderBackend->unbindVertexBuffer(vb);
	unbindBuffers(renderable);
}

//-----------------------------------//

void RenderDevice::bindTextureUnits(const RenderState& state, bool bindUniforms)
{
	TextureUnitMap& units = state.material->textureUnits;
	UniformBuffer* ub = state.renderable->getUniformBuffer().get();

	TextureUnitMap::const_iterator it;
	for( it = units.begin(); it != units.end(); it++ )
	{
		const TextureUnit& unit = it->second;
		const ImageHandle& handle = unit.image;

		Texture* texture = activeContext->textureManager->getTexture(handle).get();
		if( !texture ) continue;

		if( !texture->isUploaded() )
		{
			renderBackend->uploadTexture(texture);
			renderBackend->configureTexture(texture);
		}

		renderBackend->setupTextureUnit(texture, unit);
		renderBackend->bindTexture(texture);

		if( !bindUniforms ) continue;

		char s_TextureUniform[] = "vp_Texture0";
		size_t s_TextureUniformSize = FLD_ARRAY_SIZE(s_TextureUniform) - 2;

		// Build the uniform string without allocating memory.
		uint8 index = unit.unit;
		char indexChar = (index + '0');

		s_TextureUniform[s_TextureUniformSize] = indexChar;
		ub->setUniform( s_TextureUniform, (int32) index );
	}
}

//-----------------------------------//

void RenderDevice::unbindTextureUnits(Material* material)
{
	TextureUnitMap& units = material->textureUnits;
	TextureManager* textureManager = activeContext->textureManager;

	TextureUnitMap::const_iterator it;
	for( it = units.begin(); it != units.end(); it++ )
	{
		const TextureUnit& unit = it->second;
		const ImageHandle& handle = unit.image;

		Texture* texture = textureManager->getTexture(handle).get();
		if( !texture ) continue;

		renderBackend->setupTextureUnit(texture, unit);
		renderBackend->unbindTexture(texture);
	}
}

//-----------------------------------//

bool RenderDevice::setupRenderStateMatrix( const RenderState& state )
{
	const Matrix4x3& matModel = state.modelMatrix;
	const Matrix4x3& matView = activeView->viewMatrix;
	const Matrix4x4& matProjection = activeView->projectionMatrix;

	UniformBuffer* ub = state.renderable->getUniformBuffer().get();
	ub->setUniform( "vp_ModelMatrix", matModel );
	ub->setUniform( "vp_ViewMatrix", matView );
	ub->setUniform( "vp_ProjectionMatrix", matProjection );

	return true;
}

//-----------------------------------//

bool RenderDevice::bindBuffers(RenderBatch* renderable)
{
	BufferManager* buffers = activeContext->bufferManager;
	GeometryBuffer* gb = renderable->getGeometryBuffer().get();

	VertexBuffer* vb = buffers->getVertexBuffer(gb).get();
	IndexBuffer* ib = buffers->getIndexBuffer(gb).get();

	if( !vb ) return false;

	if( !vb->isBuilt() || gb->needsRebuild )
	{
		// If the vertex buffer is not built yet, then we build it.
		renderBackend->buildVertexBuffer(vb);
	}

	renderBackend->bindVertexBuffer(vb);

	// If there is no index buffer associated with the geometry, we are done.
	if( !ib ) goto done;

	renderBackend->bindIndexBuffer(ib);

	if( !ib->isBuilt || gb->needsRebuild )
	{
		// If the index buffer is not built, we also need to build it.
		renderBackend->buildIndexBuffer(ib);
	}

done:

	gb->needsRebuild = false;
	return true;
}

//-----------------------------------//

bool RenderDevice::unbindBuffers(RenderBatch* renderable)
{
	BufferManager* buffers = activeContext->bufferManager;
	const GeometryBuffer* gb = renderable->getGeometryBuffer().get();

	VertexBuffer* vb = buffers->getVertexBuffer(gb).get();
	if( !vb ) return false;

	renderBackend->unbindVertexBuffer(vb);

	IndexBuffer* ib = buffers->getIndexBuffer(gb).get();
	if( ib ) renderBackend->unbindIndexBuffer(ib);

	return true;
}

//-----------------------------------//
#if 0
void RenderDevice::updateLightDepth( LightState& state )
{
#if 0
	const LightPtr& light = state.light;
	assert( light->getLightType() == LightType::Directional );

	Texture* shadowDepthTexture;

	if( !shadowDepthBuffer )
	{
		shadowDepthBuffer = createRenderBuffer( Settings(512, 512) );
	}

	if( shadowTextures.find(light) == shadowTextures.end() )
	{
		shadowDepthTexture = shadowDepthBuffer->createRenderTexture();
		shadowTextures[light] = shadowDepthTexture;
	}
	else
	{
		shadowDepthTexture = shadowTextures[light];
	}

	CameraPtr lightCamera( new Camera(*camera) );
	TransformPtr lightTransform( new Transform(*state.transform.get()) );

	EntityPtr lightCameraEntity( new Entity("ShadowCamera") );
	lightCameraEntity->addTransform(); /*Component( lightTransform );*/
	lightCameraEntity->addComponent( lightCamera );

	RenderView* lightView = new View(lightCamera, shadowDepthBuffer);

	if( !shadowDepthBuffer->check() )
		return;

	// TODO: turn off color writes (glColorMask?)
	lightView->update();
	shadowDepthBuffer->unbind();

	Matrix4x4 bias;
	bias.identity();
	bias.m11 = 0.5f;
	bias.m22 = 0.5f;
	bias.m33 = 0.5f;
	bias.tx  = 0.5f;
	bias.ty  = 0.5f;
	bias.tz  = 0.5f;

	const Frustum& frustum = lightCamera->getFrustum();
	const Matrix4x4& matProjection = frustum.projectionMatrix;

	state.projection = lightCamera->getViewMatrix()
		* matProjection * bias;
#endif
}

//-----------------------------------//

bool RenderDevice::setupRenderStateShadow( LightQueue& lights )
{
#if 0
	if( lights.empty() ) return true;

	for( size_t i = 0; i < lights.size(); i++ )
	{
		LightState& state = lights[i];
		const Light* light = state.light;

		if( !light->getCastsShadows() )
			continue;

		updateLightDepth( state );
	}
#endif

	return true;
}

//-----------------------------------//

bool RenderDevice::setupRenderStateLight( const RenderState& state, const LightQueue& lights )
{
#if 0
	const UniformBufferPtr& ub = state.renderable->getUniformBuffer();

	for( size_t i = 0; i < lights.size(); i++ )
	{
		const LightState& lightState = lights[i];
		const Light* light = lightState.light;

		//TexturePtr shadowDepthTexture;
		//shadowDepthTexture = shadowTextures[light];
		//assert( shadowDepthTexture != nullptr );

		std::vector< Color > colors;
		colors.push_back( light->getDiffuseColor() );
		colors.push_back( light->getSpecularColor() );
		colors.push_back( light->getEmissiveColor() );
		colors.push_back( light->getAmbientColor() );

		const Transform* transform = lightState.transform;

		// TODO: fix the lighting stuff
		ub->setUniform( "vp_LightColors", colors );
		ub->setUniform( "vp_LightDirection", transform->getRotationMatrix() );
		//ub->setUniform( "vp_ShadowMap", shadowDepthTexture->id() );
		//ub->setUniform( "vp_CameraProj", state.modelMatrix * lightState.projection );
	}
#endif

	return true;
}
#endif
//-----------------------------------//

bool RenderDevice::setupRenderStateOverlay( const RenderState& state )
{
	Vector2i size = activeTarget->getSettings().getSize();
	Matrix4x4 projection = Matrix4x4::createOrthographic(0, size.x, size.y, 0, -100, 100);

	const UniformBufferPtr& ub = state.renderable->getUniformBuffer();
	ub->setUniform( "vp_ProjectionMatrix", projection );
	ub->setUniform( "vp_ModelMatrix", state.modelMatrix );
	ub->setUniform( "vp_ViewMatrix", Matrix4x4::Identity );
	ub->setUniform( "vp_ModelViewMatrix", state.modelMatrix );

	return true;
}

//-----------------------------------//

void RenderDevice::setActiveView( RenderView* view )
{
	activeView = view;
	if( !activeView ) return;

	setRenderTarget(view->getRenderTarget());
	renderBackend->setupRenderView(view);
}

//-----------------------------------//

void RenderDevice::clearView()
{
	renderBackend->clearRenderView(activeView);
}

//-----------------------------------//

void RenderDevice::setRenderTarget(RenderTarget* target)
{
	activeTarget = target;
	if( !activeTarget ) return;

	//activeTarget->makeCurrent();
	activeContext = activeTarget->getContext();

	renderBackend = activeContext->backend;
}

//-----------------------------------//

bool RenderDevice::isFixedPipeline() const
{
	return pipeline == RenderPipeline::Fixed;
}

//-----------------------------------//

NAMESPACE_GRAPHICS_END

#endif<commit_msg>Fixed bug causing TextureUnits with bad wrap on the first frame.<commit_after>/************************************************************************
*
* Flood Project  (2008-201x)
* Licensed under the simplified BSD license. All rights reserved.
*
************************************************************************/

#include "Graphics/API.h"

#ifdef ENABLE_RENDERER_OPENGL

#include "Graphics/RenderDevice.h"
#include "Graphics/RenderContext.h"
#include "Graphics/RenderBackend.h"
#include "Graphics/RenderBatch.h"
#include "Graphics/RenderView.h"
#include "Graphics/ShaderProgram.h"
#include "Graphics/GeometryBuffer.h"

#include "Graphics/BufferManager.h"
#include "Graphics/ShaderProgramManager.h"
#include "Graphics/TextureManager.h"

#include "Core/Utilities.h"
#include <algorithm>

NAMESPACE_GRAPHICS_BEGIN

//-----------------------------------//

REFLECT_ENUM(RenderPipeline)
	ENUM(Fixed)
	ENUM(ShaderForward)
	ENUM(ShaderDeferred)
REFLECT_ENUM_END()

//-----------------------------------//

static RenderDevice* gs_RenderDevice = nullptr;
RenderDevice* GetRenderDevice() { return gs_RenderDevice; }

RenderDevice::RenderDevice()
	: activeContext(nullptr)
	, activeTarget(nullptr)
	, activeView(nullptr)
	, renderBackend(nullptr)
	//, shadowDepthBuffer(nullptr)
	, pipeline(RenderPipeline::ShaderForward)
{
	gs_RenderDevice = this;
}

//-----------------------------------//

RenderDevice::~RenderDevice()
{
}

//-----------------------------------//

void RenderDevice::updateRenderTargets()
{
}

//-----------------------------------//

static bool RenderStateSorter(const RenderState& lhs, const RenderState& rhs)
{
	int rA = (int) lhs.renderable->getRenderLayer();
	int rB = (int) rhs.renderable->getRenderLayer();
	int pA = lhs.priority;
	int pB = rhs.priority;

	return (rA == rB) ? (pA < pB) : (rA < rB);
}

//-----------------------------------//

void RenderDevice::render( RenderBlock& queue )
{
	#pragma TODO("Sort the render group by depth distance")

	// Sort the renderables by render group.
	std::sort( queue.renderables.begin(), queue.renderables.end(), &RenderStateSorter );

	// Render all the renderables in the queue.
	for( size_t i = 0; i < queue.renderables.size(); i++ )
	{
		const RenderState& state = queue.renderables[i];
		render(state, queue.lights);
	}
}

//-----------------------------------//

void RenderDevice::render( const RenderState& state, const LightQueue& lights )
{
	BufferManager* buffers = activeContext->bufferManager;
	ProgramManager* programs = activeContext->programManager;

	RenderBatch* renderable = state.renderable;
	bindBuffers(renderable);

	const GeometryBuffer* gb = renderable->getGeometryBuffer().get();
	if( gb->data.empty() ) return;

	BufferEntry* bufs = buffers->getBuffer(gb);

	// Setup the vertex buffer format.
	VertexBuffer* vb = bufs->vb.get();
	renderBackend->setupVertexBuffer(vb);

	Material* material = state.material;
	ShaderMaterial* shader = material->getShader().Resolve();

	ShaderProgram* shaderProgram = programs->getProgram(shader);
	if( !shaderProgram ) return;

	if( !shaderProgram->isLinked() && !shaderProgram->link() )
		return;

	shaderProgram->bind();

	renderBackend->setupRenderState(state, true);
	bindTextureUnits(state, true);

	if( !renderable->onPreRender.empty() )
	{
		// Call the user pre render hook.
		renderable->onPreRender(activeView, state);
	}

	RenderLayer stage = renderable->getRenderLayer();

	if( stage != RenderLayer::Overlays )
	{
		if( !setupRenderStateMatrix(state) )
			return;

		//if( !setupRenderStateLight(state, lights) )
		//	return;
	}
	else if( stage == RenderLayer::Overlays )
	{
		if( !setupRenderStateOverlay(state) )
			return;
	}

	UniformBuffer* ub = renderable->getUniformBuffer().get();
	shaderProgram->setUniforms(ub);

	renderBackend->renderBatch(renderable);

	if( !renderable->onPostRender.empty() )
	{
		// Call the user post render hook.
		renderable->onPostRender(activeView, state);
	}

	renderBackend->unsetupRenderState(state);
	unbindTextureUnits(state.material);

	shaderProgram->unbind();

	renderBackend->unbindVertexBuffer(vb);
	unbindBuffers(renderable);
}

//-----------------------------------//

void RenderDevice::bindTextureUnits(const RenderState& state, bool bindUniforms)
{
	TextureUnitMap& units = state.material->textureUnits;
	UniformBuffer* ub = state.renderable->getUniformBuffer().get();

	TextureUnitMap::const_iterator it;
	for( it = units.begin(); it != units.end(); it++ )
	{
		const TextureUnit& unit = it->second;
		const ImageHandle& handle = unit.image;

		Texture* texture = activeContext->textureManager->getTexture(handle).get();
		if( !texture ) continue;

		if( !texture->isUploaded() )
		{
			renderBackend->uploadTexture(texture);
			renderBackend->configureTexture(texture);
		}

		renderBackend->bindTexture(texture);
		renderBackend->setupTextureUnit(texture, unit);

		if( !bindUniforms ) continue;

		char s_TextureUniform[] = "vp_Texture0";
		size_t s_TextureUniformSize = FLD_ARRAY_SIZE(s_TextureUniform) - 2;

		// Build the uniform string without allocating memory.
		uint8 index = unit.unit;
		char indexChar = (index + '0');

		s_TextureUniform[s_TextureUniformSize] = indexChar;
		ub->setUniform( s_TextureUniform, (int32) index );
	}
}

//-----------------------------------//

void RenderDevice::unbindTextureUnits(Material* material)
{
	TextureUnitMap& units = material->textureUnits;
	TextureManager* textureManager = activeContext->textureManager;

	TextureUnitMap::const_iterator it;
	for( it = units.begin(); it != units.end(); it++ )
	{
		const TextureUnit& unit = it->second;
		const ImageHandle& handle = unit.image;

		Texture* texture = textureManager->getTexture(handle).get();
		if( !texture ) continue;

		renderBackend->setupTextureUnit(texture, unit);
		renderBackend->unbindTexture(texture);
	}
}

//-----------------------------------//

bool RenderDevice::setupRenderStateMatrix( const RenderState& state )
{
	const Matrix4x3& matModel = state.modelMatrix;
	const Matrix4x3& matView = activeView->viewMatrix;
	const Matrix4x4& matProjection = activeView->projectionMatrix;

	UniformBuffer* ub = state.renderable->getUniformBuffer().get();
	ub->setUniform( "vp_ModelMatrix", matModel );
	ub->setUniform( "vp_ViewMatrix", matView );
	ub->setUniform( "vp_ProjectionMatrix", matProjection );

	return true;
}

//-----------------------------------//

bool RenderDevice::bindBuffers(RenderBatch* renderable)
{
	BufferManager* buffers = activeContext->bufferManager;
	GeometryBuffer* gb = renderable->getGeometryBuffer().get();

	VertexBuffer* vb = buffers->getVertexBuffer(gb).get();
	IndexBuffer* ib = buffers->getIndexBuffer(gb).get();

	if( !vb ) return false;

	if( !vb->isBuilt() || gb->needsRebuild )
	{
		// If the vertex buffer is not built yet, then we build it.
		renderBackend->buildVertexBuffer(vb);
	}

	renderBackend->bindVertexBuffer(vb);

	// If there is no index buffer associated with the geometry, we are done.
	if( !ib ) goto done;

	renderBackend->bindIndexBuffer(ib);

	if( !ib->isBuilt || gb->needsRebuild )
	{
		// If the index buffer is not built, we also need to build it.
		renderBackend->buildIndexBuffer(ib);
	}

done:

	gb->needsRebuild = false;
	return true;
}

//-----------------------------------//

bool RenderDevice::unbindBuffers(RenderBatch* renderable)
{
	BufferManager* buffers = activeContext->bufferManager;
	const GeometryBuffer* gb = renderable->getGeometryBuffer().get();

	VertexBuffer* vb = buffers->getVertexBuffer(gb).get();
	if( !vb ) return false;

	renderBackend->unbindVertexBuffer(vb);

	IndexBuffer* ib = buffers->getIndexBuffer(gb).get();
	if( ib ) renderBackend->unbindIndexBuffer(ib);

	return true;
}

//-----------------------------------//
#if 0
void RenderDevice::updateLightDepth( LightState& state )
{
#if 0
	const LightPtr& light = state.light;
	assert( light->getLightType() == LightType::Directional );

	Texture* shadowDepthTexture;

	if( !shadowDepthBuffer )
	{
		shadowDepthBuffer = createRenderBuffer( Settings(512, 512) );
	}

	if( shadowTextures.find(light) == shadowTextures.end() )
	{
		shadowDepthTexture = shadowDepthBuffer->createRenderTexture();
		shadowTextures[light] = shadowDepthTexture;
	}
	else
	{
		shadowDepthTexture = shadowTextures[light];
	}

	CameraPtr lightCamera( new Camera(*camera) );
	TransformPtr lightTransform( new Transform(*state.transform.get()) );

	EntityPtr lightCameraEntity( new Entity("ShadowCamera") );
	lightCameraEntity->addTransform(); /*Component( lightTransform );*/
	lightCameraEntity->addComponent( lightCamera );

	RenderView* lightView = new View(lightCamera, shadowDepthBuffer);

	if( !shadowDepthBuffer->check() )
		return;

	// TODO: turn off color writes (glColorMask?)
	lightView->update();
	shadowDepthBuffer->unbind();

	Matrix4x4 bias;
	bias.identity();
	bias.m11 = 0.5f;
	bias.m22 = 0.5f;
	bias.m33 = 0.5f;
	bias.tx  = 0.5f;
	bias.ty  = 0.5f;
	bias.tz  = 0.5f;

	const Frustum& frustum = lightCamera->getFrustum();
	const Matrix4x4& matProjection = frustum.projectionMatrix;

	state.projection = lightCamera->getViewMatrix()
		* matProjection * bias;
#endif
}

//-----------------------------------//

bool RenderDevice::setupRenderStateShadow( LightQueue& lights )
{
#if 0
	if( lights.empty() ) return true;

	for( size_t i = 0; i < lights.size(); i++ )
	{
		LightState& state = lights[i];
		const Light* light = state.light;

		if( !light->getCastsShadows() )
			continue;

		updateLightDepth( state );
	}
#endif

	return true;
}

//-----------------------------------//

bool RenderDevice::setupRenderStateLight( const RenderState& state, const LightQueue& lights )
{
#if 0
	const UniformBufferPtr& ub = state.renderable->getUniformBuffer();

	for( size_t i = 0; i < lights.size(); i++ )
	{
		const LightState& lightState = lights[i];
		const Light* light = lightState.light;

		//TexturePtr shadowDepthTexture;
		//shadowDepthTexture = shadowTextures[light];
		//assert( shadowDepthTexture != nullptr );

		std::vector< Color > colors;
		colors.push_back( light->getDiffuseColor() );
		colors.push_back( light->getSpecularColor() );
		colors.push_back( light->getEmissiveColor() );
		colors.push_back( light->getAmbientColor() );

		const Transform* transform = lightState.transform;

		// TODO: fix the lighting stuff
		ub->setUniform( "vp_LightColors", colors );
		ub->setUniform( "vp_LightDirection", transform->getRotationMatrix() );
		//ub->setUniform( "vp_ShadowMap", shadowDepthTexture->id() );
		//ub->setUniform( "vp_CameraProj", state.modelMatrix * lightState.projection );
	}
#endif

	return true;
}
#endif
//-----------------------------------//

bool RenderDevice::setupRenderStateOverlay( const RenderState& state )
{
	Vector2i size = activeTarget->getSettings().getSize();
	Matrix4x4 projection = Matrix4x4::createOrthographic(0, size.x, size.y, 0, -100, 100);

	const UniformBufferPtr& ub = state.renderable->getUniformBuffer();
	ub->setUniform( "vp_ProjectionMatrix", projection );
	ub->setUniform( "vp_ModelMatrix", state.modelMatrix );
	ub->setUniform( "vp_ViewMatrix", Matrix4x4::Identity );
	ub->setUniform( "vp_ModelViewMatrix", state.modelMatrix );

	return true;
}

//-----------------------------------//

void RenderDevice::setActiveView( RenderView* view )
{
	activeView = view;
	if( !activeView ) return;

	setRenderTarget(view->getRenderTarget());
	renderBackend->setupRenderView(view);
}

//-----------------------------------//

void RenderDevice::clearView()
{
	renderBackend->clearRenderView(activeView);
}

//-----------------------------------//

void RenderDevice::setRenderTarget(RenderTarget* target)
{
	activeTarget = target;
	if( !activeTarget ) return;

	//activeTarget->makeCurrent();
	activeContext = activeTarget->getContext();

	renderBackend = activeContext->backend;
}

//-----------------------------------//

bool RenderDevice::isFixedPipeline() const
{
	return pipeline == RenderPipeline::Fixed;
}

//-----------------------------------//

NAMESPACE_GRAPHICS_END

#endif<|endoftext|>