<commit_before>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

*******************************************************************************/

//==============================================================================
// Editor find/replace widget
//==============================================================================

#include "editorfindreplacewidget.h"

//==============================================================================

#include "ui_editorfindreplacewidget.h"

//==============================================================================

#include <QKeyEvent>
#include <QGridLayout>
#include <QLabel>
#include <QTextEdit>

//==============================================================================

namespace OpenCOR {
namespace Editor {

//==============================================================================

EditorFindReplaceWidget::EditorFindReplaceWidget(QWidget *pParent) :
    Core::Widget(pParent),
    mGui(new Ui::EditorFindReplaceWidget)
{
    // Set up the GUI

    mGui->setupUi(this);

    // Create our contents

    mFindLabel = new QLabel(this);
    mFindEdit = new QTextEdit(this);

    mReplaceLabel = new QLabel(this);
    mReplaceEdit = new QTextEdit(this);

    // Add our contents to our layout

    mGui->layout->addWidget(mFindLabel, 0, 0);
    mGui->layout->addWidget(mFindEdit, 0, 1);

    mGui->layout->addWidget(mReplaceLabel, 1, 0);
    mGui->layout->addWidget(mReplaceEdit, 1, 1);

    // Make our find edit widget our focus proxy

    setFocusProxy(mFindEdit);

    // Retranslate ourselves, so our various widgets are properly set

    retranslateUi();
}

//==============================================================================

void EditorFindReplaceWidget::retranslateUi()
{
    // Retranslate our find/replace widget

    mFindLabel->setText(tr("Find:"));
    mReplaceLabel->setText(tr("Replace:"));
}

//==============================================================================

void EditorFindReplaceWidget::keyPressEvent(QKeyEvent *pEvent)
{
    // Let people know that a key has been pressed

    bool handled = false;

    emit keyPressed(pEvent, handled);

    // Carry on as normal, if the event wasn't handled

    if (handled)
        // Accept the event

        pEvent->accept();
    else
        // Default handling of the event

        QWidget::keyPressEvent(pEvent);
}

//==============================================================================

}   // namespace Editor
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some work towards supporting find/replace in our QScintilla-based widget (#261) [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

*******************************************************************************/

//==============================================================================
// Editor find/replace widget
//==============================================================================

#include "editorfindreplacewidget.h"

//==============================================================================

#include "ui_editorfindreplacewidget.h"

//==============================================================================

#include <QKeyEvent>
#include <QGridLayout>
#include <QLabel>
#include <QTextEdit>

//==============================================================================

namespace OpenCOR {
namespace Editor {

//==============================================================================

EditorFindReplaceWidget::EditorFindReplaceWidget(QWidget *pParent) :
    Core::Widget(pParent),
    mGui(new Ui::EditorFindReplaceWidget)
{
    // Set up the GUI

    mGui->setupUi(this);

    // Create our contents

    mFindLabel = new QLabel(this);
    mFindEdit = new QTextEdit(this);

    mReplaceLabel = new QLabel(this);
    mReplaceEdit = new QTextEdit(this);

    mFindEdit->setTabChangesFocus(true);
    mReplaceEdit->setTabChangesFocus(true);

    // Add our contents to our layout

    mGui->layout->addWidget(mFindLabel, 0, 0);
    mGui->layout->addWidget(mFindEdit, 0, 1);

    mGui->layout->addWidget(mReplaceLabel, 1, 0);
    mGui->layout->addWidget(mReplaceEdit, 1, 1);

    // Make our find edit widget our focus proxy

    setFocusProxy(mFindEdit);

    // Retranslate ourselves, so our various widgets are properly set

    retranslateUi();
}

//==============================================================================

void EditorFindReplaceWidget::retranslateUi()
{
    // Retranslate our find/replace widget

    mFindLabel->setText(tr("Find:"));
    mReplaceLabel->setText(tr("Replace:"));
}

//==============================================================================

void EditorFindReplaceWidget::keyPressEvent(QKeyEvent *pEvent)
{
    // Let people know that a key has been pressed

    bool handled = false;

    emit keyPressed(pEvent, handled);

    // Carry on as normal, if the event wasn't handled

    if (handled)
        // Accept the event

        pEvent->accept();
    else
        // Default handling of the event

        QWidget::keyPressEvent(pEvent);
}

//==============================================================================

}   // namespace Editor
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>/*******************************************************************************
FILE : api/cmiss_function_variable.cpp

LAST MODIFIED : 5 March 2004

DESCRIPTION :
The public interface to the Cmiss_function_variable object.  Variables specify
inputs and/or outputs of functions.  Variables can be evaluated, differentiated
or set to another value.
==============================================================================*/

#include <new>
#include "api/cmiss_function_variable.h"
#include "computed_variable/function_variable.hpp"
#if defined (NOT_DEBUG)
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)
extern "C"
{
#include "general/debug.h"
}

/*
Global functions
----------------
*/
int Cmiss_function_variable_destroy(
	Cmiss_function_variable_id *variable_address)
/*******************************************************************************
LAST MODIFIED : 25 February 2004

DESCRIPTION :
Destroys the variable.  Returns a non-zero if successful and zero otherwise.
==============================================================================*/
{
	int return_code;
	Function_variable_handle **variable_handle_address_address;

	return_code=0;
	if ((variable_handle_address_address=
		reinterpret_cast<Function_variable_handle **>(variable_address))&&
		(*variable_handle_address_address))
	{
		// call the destructor for the object pointed to by
		//   *variable_handle_address_address (a Function_variable_handle which is
		//   a smart pointer) and then free the memory pointed to by
		//   *variable_handle_address_address
		delete *variable_handle_address_address;
		*variable_handle_address_address=0;
		return_code=1;
	}

	return (return_code);
}
#if defined (NOT_DEBUG)
int Cmiss_function_variable_destroy(
	Cmiss_function_variable_id *)
/*******************************************************************************
LAST MODIFIED : 25 February 2004

DESCRIPTION :
Destroys the variable.  Returns a non-zero if successful and zero otherwise.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

int Cmiss_function_variable_get_string_representation(
	Cmiss_function_variable_id variable,char **result)
/*******************************************************************************
LAST MODIFIED : 25 February 2004

DESCRIPTION :
Creates a string representation of the <variable> useful for output.  Returns a
non-zero if successful and zero otherwise.  If successful <*result> contains an
ALLOCATED string, it is up to the calling function to DEALLOCATE the string when
it is no longer required.
==============================================================================*/
{
	const char *result_c_string;
	int return_code;
	std::string *result_string;
	Function_variable_handle *variable_handle_address;

	return_code=0;
	if ((variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable))&&(*variable_handle_address))
	{
		if (result_string=((*variable_handle_address)->get_string_representation)())
		{
			if (result_c_string=result_string->c_str())
			{
				if (ALLOCATE(*result,char,strlen(result_c_string)+1))
				{
					strcpy(*result,result_c_string);
					return_code=1;
				}
			}
			delete result_string;
		}
	}

	return (return_code);
}
#if defined (NOT_DEBUG)
int Cmiss_function_variable_get_string_representation(
	Cmiss_function_variable_id,char **)
/*******************************************************************************
LAST MODIFIED : 25 February 2004

DESCRIPTION :
Creates a string representation of the <variable> useful for output.  Returns a
non-zero if successful and zero otherwise.  If successful <*result> contains an
ALLOCATED string, it is up to the calling function to DEALLOCATE the string when
it is no longer required.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

Cmiss_function_id Cmiss_function_variable_evaluate(
	Cmiss_function_variable_id variable,Cmiss_function_variable_id input,
	Cmiss_function_id value)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	Cmiss_function_id result;
	Function_handle *value_handle_address;
	Function_variable_handle *input_handle_address,*variable_handle_address;

	result=0;
	if ((variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable))&&(*variable_handle_address))
	{
		input_handle_address=reinterpret_cast<Function_variable_handle *>(input);
		value_handle_address=reinterpret_cast<Function_handle *>(value);
		if (input_handle_address&&value_handle_address)
		{
			result=reinterpret_cast<Cmiss_function_id>(
				new Function_handle(((*variable_handle_address)->evaluate)(
				*input_handle_address,*value_handle_address)));
		}
		else
		{
			result=reinterpret_cast<Cmiss_function_id>(
				new Function_handle(((*variable_handle_address)->evaluate)()));
		}
	}

	return (result);
}
#if defined (NOT_DEBUG)
Cmiss_function_id Cmiss_function_variable_evaluate(
	Cmiss_function_variable_id,Cmiss_function_variable_id,
	Cmiss_function_id)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	Cmiss_function_id result;

	result=0;

	return (result);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

Cmiss_function_id Cmiss_function_variable_evaluate_derivative(
	Cmiss_function_variable_id variable,
	Cmiss_function_variable_list_id independent_variables,
	Cmiss_function_variable_id input,Cmiss_function_id value)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	Cmiss_function_id result;
	Function_handle *value_handle_address;
	Function_variable_handle *input_handle_address,*variable_handle_address;
	std::list<Function_variable_handle> *independent_variables_address;

	result=0;
	if ((variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable))&&(*variable_handle_address)&&
		(independent_variables_address=reinterpret_cast<std::list<
		Function_variable_handle> *>(independent_variables)))
	{
		input_handle_address=reinterpret_cast<Function_variable_handle *>(input);
		value_handle_address=reinterpret_cast<Function_handle *>(value);
		if (input_handle_address&&value_handle_address)
		{
			result=reinterpret_cast<Cmiss_function_id>(
				new Function_handle(((*variable_handle_address)->
				evaluate_derivative)(*independent_variables_address,
				*input_handle_address,*value_handle_address)));
		}
		else
		{
			result=reinterpret_cast<Cmiss_function_id>(
				new Function_handle(((*variable_handle_address)->
				evaluate_derivative)(*independent_variables_address)));
		}
	}

	return (result);
}
#if defined (NOT_DEBUG)
Cmiss_function_id Cmiss_function_variable_evaluate_derivative(
	Cmiss_function_variable_id,
	Cmiss_function_variable_list_id,
	Cmiss_function_variable_id,Cmiss_function_id)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	Cmiss_function_id result;

	result=0;

	return (result);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

#if defined (NOT_DEBUG)
int Cmiss_function_variable_set_value(Cmiss_function_variable_id variable,
	Cmiss_function_id value)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	int return_code;
	Function_handle *value_handle_address;
	Function_variable_handle *variable_handle_address;

	return_code=0;
	if ((variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable))&&(*variable_handle_address)&&
		(value_handle_address=reinterpret_cast<Function_handle *>(value)))
	{
		if (((*variable_handle_address)->set_value)(*value_handle_address))
		{
			return_code=1;
		}
	}

	return (return_code);
}
#else // defined (NOT_DEBUG)
int Cmiss_function_variable_set_value(Cmiss_function_variable_id,
	Cmiss_function_id)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#endif // defined (NOT_DEBUG)

Cmiss_function_variable_list_id Cmiss_function_variable_list_create(void)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Creates an variable list.
==============================================================================*/
{
#if defined (NOT_DEBUG)
	return (reinterpret_cast<Cmiss_function_variable_list_id>(
		new std::list<Function_variable_handle>));
#else // defined (NOT_DEBUG)
	return (reinterpret_cast<Cmiss_function_variable_list_id>(0));
#endif // defined (NOT_DEBUG)
}

#if defined (NOT_DEBUG)
int Cmiss_function_variable_list_destroy(
	Cmiss_function_variable_list_id *list_address)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Destroys an variable list.
==============================================================================*/
{
	int return_code;
	std::list<Function_variable_handle> **handle_list_address_address;

	return_code=0;
	if (handle_list_address_address=
		reinterpret_cast<std::list<Function_variable_handle> **>(list_address))
	{
		// call the destructor for the object pointed to by
		//   *handle_list_address_address (a Function_variable_handle list) and then
		//   free the memory pointed to by *handle_list_address_address
		delete *handle_list_address_address;
		*handle_list_address_address=0;
		return_code=1;
	}

	return (return_code);
}
#else // defined (NOT_DEBUG)
int Cmiss_function_variable_list_destroy(
	Cmiss_function_variable_list_id *)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Destroys an variable list.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#endif // defined (NOT_DEBUG)

#if defined (NOT_DEBUG)
int Cmiss_function_variable_list_add(Cmiss_function_variable_list_id list,
	Cmiss_function_variable_id variable)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Adds a <variable> to a <list>.
==============================================================================*/
{
	int return_code;
	std::list<Function_variable_handle> *list_address;
	Function_variable_handle *variable_handle_address;

	return_code=0;
	if ((list_address=reinterpret_cast<std::list<Function_variable_handle> *>(
		list))&&
		(variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable)))
	{
		(list_address->push_back)(*variable_handle_address);
		return_code=1;
	}

	return (return_code);
}
#else // defined (NOT_DEBUG)
int Cmiss_function_variable_list_add(Cmiss_function_variable_list_id,
	Cmiss_function_variable_id)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Adds a <variable> to a <list>.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#endif // defined (NOT_DEBUG)
<commit_msg>Looking for C++ prelinker: error: bad instantiation request file problem 8<commit_after>/*******************************************************************************
FILE : api/cmiss_function_variable.cpp

LAST MODIFIED : 5 March 2004

DESCRIPTION :
The public interface to the Cmiss_function_variable object.  Variables specify
inputs and/or outputs of functions.  Variables can be evaluated, differentiated
or set to another value.
==============================================================================*/

#include <new>
#include "api/cmiss_function_variable.h"
#include "computed_variable/function_variable.hpp"
#if defined (NOT_DEBUG)
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)
extern "C"
{
#include "general/debug.h"
}

/*
Global functions
----------------
*/
int Cmiss_function_variable_destroy(
	Cmiss_function_variable_id *variable_address)
/*******************************************************************************
LAST MODIFIED : 25 February 2004

DESCRIPTION :
Destroys the variable.  Returns a non-zero if successful and zero otherwise.
==============================================================================*/
{
	int return_code;
	Function_variable_handle **variable_handle_address_address;

	return_code=0;
	if ((variable_handle_address_address=
		reinterpret_cast<Function_variable_handle **>(variable_address))&&
		(*variable_handle_address_address))
	{
		// call the destructor for the object pointed to by
		//   *variable_handle_address_address (a Function_variable_handle which is
		//   a smart pointer) and then free the memory pointed to by
		//   *variable_handle_address_address
		delete *variable_handle_address_address;
		*variable_handle_address_address=0;
		return_code=1;
	}

	return (return_code);
}
#if defined (NOT_DEBUG)
int Cmiss_function_variable_destroy(
	Cmiss_function_variable_id *)
/*******************************************************************************
LAST MODIFIED : 25 February 2004

DESCRIPTION :
Destroys the variable.  Returns a non-zero if successful and zero otherwise.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

int Cmiss_function_variable_get_string_representation(
	Cmiss_function_variable_id variable,char **result)
/*******************************************************************************
LAST MODIFIED : 25 February 2004

DESCRIPTION :
Creates a string representation of the <variable> useful for output.  Returns a
non-zero if successful and zero otherwise.  If successful <*result> contains an
ALLOCATED string, it is up to the calling function to DEALLOCATE the string when
it is no longer required.
==============================================================================*/
{
	const char *result_c_string;
	int return_code;
	std::string *result_string;
	Function_variable_handle *variable_handle_address;

	return_code=0;
	if ((variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable))&&(*variable_handle_address))
	{
		if (result_string=((*variable_handle_address)->get_string_representation)())
		{
			if (result_c_string=result_string->c_str())
			{
				if (ALLOCATE(*result,char,strlen(result_c_string)+1))
				{
					strcpy(*result,result_c_string);
					return_code=1;
				}
			}
			delete result_string;
		}
	}

	return (return_code);
}
#if defined (NOT_DEBUG)
int Cmiss_function_variable_get_string_representation(
	Cmiss_function_variable_id,char **)
/*******************************************************************************
LAST MODIFIED : 25 February 2004

DESCRIPTION :
Creates a string representation of the <variable> useful for output.  Returns a
non-zero if successful and zero otherwise.  If successful <*result> contains an
ALLOCATED string, it is up to the calling function to DEALLOCATE the string when
it is no longer required.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

Cmiss_function_id Cmiss_function_variable_evaluate(
	Cmiss_function_variable_id variable,Cmiss_function_variable_id input,
	Cmiss_function_id value)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	Cmiss_function_id result;
	Function_handle *value_handle_address;
	Function_variable_handle *input_handle_address,*variable_handle_address;

	result=0;
	if ((variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable))&&(*variable_handle_address))
	{
		input_handle_address=reinterpret_cast<Function_variable_handle *>(input);
		value_handle_address=reinterpret_cast<Function_handle *>(value);
		if (input_handle_address&&value_handle_address)
		{
			result=reinterpret_cast<Cmiss_function_id>(
				new Function_handle(((*variable_handle_address)->evaluate)(
				*input_handle_address,*value_handle_address)));
		}
		else
		{
			result=reinterpret_cast<Cmiss_function_id>(
				new Function_handle(((*variable_handle_address)->evaluate)()));
		}
	}

	return (result);
}
#if defined (NOT_DEBUG)
Cmiss_function_id Cmiss_function_variable_evaluate(
	Cmiss_function_variable_id,Cmiss_function_variable_id,
	Cmiss_function_id)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	Cmiss_function_id result;

	result=0;

	return (result);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

Cmiss_function_id Cmiss_function_variable_evaluate_derivative(
	Cmiss_function_variable_id variable,
	Cmiss_function_variable_list_id independent_variables,
	Cmiss_function_variable_id input,Cmiss_function_id value)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	Cmiss_function_id result;
	Function_handle *value_handle_address;
	Function_variable_handle *input_handle_address,*variable_handle_address;
	std::list<Function_variable_handle> *independent_variables_address;

	result=0;
	if ((variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable))&&(*variable_handle_address)&&
		(independent_variables_address=reinterpret_cast<std::list<
		Function_variable_handle> *>(independent_variables)))
	{
		input_handle_address=reinterpret_cast<Function_variable_handle *>(input);
		value_handle_address=reinterpret_cast<Function_handle *>(value);
		if (input_handle_address&&value_handle_address)
		{
			result=reinterpret_cast<Cmiss_function_id>(
				new Function_handle(((*variable_handle_address)->
				evaluate_derivative)(*independent_variables_address,
				*input_handle_address,*value_handle_address)));
		}
		else
		{
			result=reinterpret_cast<Cmiss_function_id>(
				new Function_handle(((*variable_handle_address)->
				evaluate_derivative)(*independent_variables_address)));
		}
	}

	return (result);
}
#if defined (NOT_DEBUG)
Cmiss_function_id Cmiss_function_variable_evaluate_derivative(
	Cmiss_function_variable_id,
	Cmiss_function_variable_list_id,
	Cmiss_function_variable_id,Cmiss_function_id)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	Cmiss_function_id result;

	result=0;

	return (result);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

int Cmiss_function_variable_set_value(Cmiss_function_variable_id variable,
	Cmiss_function_id value)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	int return_code;
	Function_handle *value_handle_address;
	Function_variable_handle *variable_handle_address;

	return_code=0;
	if ((variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable))&&(*variable_handle_address)&&
		(value_handle_address=reinterpret_cast<Function_handle *>(value)))
	{
		if (((*variable_handle_address)->set_value)(*value_handle_address))
		{
			return_code=1;
		}
	}

	return (return_code);
}
#if defined (NOT_DEBUG)
int Cmiss_function_variable_set_value(Cmiss_function_variable_id,
	Cmiss_function_id)
/*******************************************************************************
LAST MODIFIED : 5 March 2004

DESCRIPTION :
See the include file.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#else // defined (NOT_DEBUG)
#endif // defined (NOT_DEBUG)

Cmiss_function_variable_list_id Cmiss_function_variable_list_create(void)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Creates an variable list.
==============================================================================*/
{
#if defined (NOT_DEBUG)
	return (reinterpret_cast<Cmiss_function_variable_list_id>(
		new std::list<Function_variable_handle>));
#else // defined (NOT_DEBUG)
	return (reinterpret_cast<Cmiss_function_variable_list_id>(0));
#endif // defined (NOT_DEBUG)
}

#if defined (NOT_DEBUG)
int Cmiss_function_variable_list_destroy(
	Cmiss_function_variable_list_id *list_address)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Destroys an variable list.
==============================================================================*/
{
	int return_code;
	std::list<Function_variable_handle> **handle_list_address_address;

	return_code=0;
	if (handle_list_address_address=
		reinterpret_cast<std::list<Function_variable_handle> **>(list_address))
	{
		// call the destructor for the object pointed to by
		//   *handle_list_address_address (a Function_variable_handle list) and then
		//   free the memory pointed to by *handle_list_address_address
		delete *handle_list_address_address;
		*handle_list_address_address=0;
		return_code=1;
	}

	return (return_code);
}
#else // defined (NOT_DEBUG)
int Cmiss_function_variable_list_destroy(
	Cmiss_function_variable_list_id *)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Destroys an variable list.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#endif // defined (NOT_DEBUG)

#if defined (NOT_DEBUG)
int Cmiss_function_variable_list_add(Cmiss_function_variable_list_id list,
	Cmiss_function_variable_id variable)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Adds a <variable> to a <list>.
==============================================================================*/
{
	int return_code;
	std::list<Function_variable_handle> *list_address;
	Function_variable_handle *variable_handle_address;

	return_code=0;
	if ((list_address=reinterpret_cast<std::list<Function_variable_handle> *>(
		list))&&
		(variable_handle_address=reinterpret_cast<Function_variable_handle *>(
		variable)))
	{
		(list_address->push_back)(*variable_handle_address);
		return_code=1;
	}

	return (return_code);
}
#else // defined (NOT_DEBUG)
int Cmiss_function_variable_list_add(Cmiss_function_variable_list_id,
	Cmiss_function_variable_id)
/*******************************************************************************
LAST MODIFIED : 23 February 2004

DESCRIPTION :
Adds a <variable> to a <list>.
==============================================================================*/
{
	int return_code;

	return_code=0;

	return (return_code);
}
#endif // defined (NOT_DEBUG)
<|endoftext|>


<commit_before>//
// Macro to run the ProofSimple selector.
// This macro uses an existing PROOF session or starts one at the indicated URL.
// In the case non existing PROOF session is found and no URL is given, the macro
// tries to start a local PROOF session.
//
// To run the macro:
//
//   root[] .L proof/runProof.C+
//   root[] runProof("<analysis>")
//
//   Currently available analysis are:
//
//   1. "simple"
//
//      root[] runProof("simple")
//
//      This will create a local PROOF session and run an analysis filling 100 histos
//      with 100000 gaussian random numbers, and displaying them in a canvas with 100
//      pads (10x10).
//      The number of entries and the number of histograms can be passed as 'arguments'
//      to 'simple': e.g. to fill 16 histos with 1000000 entries use
//
//      root[] runProof("simple(nevt=1000000,nhist=16)")
//
//   2. "h1"
//
//      root[] runProof("h1")
//
//      This runs the 'famous' H1 analysis from $ROOTSYS/tree/h1analysis.C,.h .
//      The data are read from the HTTP server at root.cern.ch .
//
//   In all cases, to run in non blocking mode the option 'asyn' is available, e.g.
//
//   root[] runProof("h1(asyn)")
//
//   In all cases, to run on a remote Proof cluster, the master URL must be passed as
//   second argument; e.g.
//
//   root[] runProof("simple","master.domain")
//
//   In the case of local running it is possible to specify the number of workers to
//   start as third argument (the default is the number of cores of the machine), e.g.
//
//   root[] runProof("simple",0,4)
//
//   will start 4 workers. Note that the real number of workers is changed only the
//   first time you call runProof into a ROOT session; following calls can reduce the
//   number of active workers, but not increase it. For example, in the same session of
//   the call above starting 4 workers, this
//
//   root[] runProof("simple",0,8)
//
//   will still use 4 workers, while this
//
//   root[] runProof("simple",0,2)
//
//   will disable 2 workers and use the other 2.
//

#include "TChain.h"
#include "TEnv.h"
#include "TProof.h"
#include "TString.h"
#include "TDrawFeedback.h"
#include "TList.h"

// By default we start a cluster on the local machine
const char *refloc = "proof://localhost";

#include "getProof.C"

void runProof(const char *what = "simple",
              const char *url = "proof://localhost:11093",
              Int_t nwrks = -1)
{
   gEnv->SetValue("Proof.StatsHist",1);

   // Temp dir for PROOF tutorials
   TString tutdir = Form("%s/.proof-tutorial", gSystem->TempDirectory());
   if (gSystem->AccessPathName(tutdir)) {
      Printf("runProof: creating the temporary directory"
                " for the tutorial (%s) ... ", tutdir.Data());
      if (gSystem->mkdir(tutdir, kTRUE) != 0) {
         Printf("runProof: could not assert / create the temporary directory"
                " for the tutorial (%s)", tutdir.Data());
         return;
      }
   }

   // Get the PROOF Session
   TProof *proof = getProof(url, nwrks, tutdir.Data(), "ask");
   if (!proof) {
      Printf("runProof: could not start/attach a PROOF session");
      return;
   }
   TString proofsessions(Form("%s/sessions",tutdir.Data()));
   // Save tag of the used session
   FILE *fs = fopen(proofsessions.Data(), "a");
   if (!fs) {
      Printf("runProof: could not create files for sessions tags");
   } else {
      fprintf(fs,"session-%s\n", proof->GetSessionTag());
      fclose(fs);
   }
   if (!proof) {
      Printf("runProof: could not start/attach a PROOF session");
      return;
   }

   // Set the number of workers (may only reduce the number of active workers
   // in the session)
   if (nwrks > 0)
      proof->SetParallel(nwrks);

   // Where is the code to run
   char *rootbin = gSystem->Which(gSystem->Getenv("PATH"), "root.exe", kExecutePermission);
   if (!rootbin) {
      Printf("runProof: root.exe not found: please check the environment!");
      return;
   }
   TString rootsys(gSystem->DirName(rootbin));
   rootsys = gSystem->DirName(rootsys);
   TString tutorials(Form("%s/tutorials", rootsys.Data()));
   delete[] rootbin;

   // Create feedback displayer
   TDrawFeedback fb(proof);

   // Number of events per worker
   proof->AddFeedback("PROOF_EventsHist");

   // Have constant progress reporting based on estimated info
   proof->SetParameter("PROOF_RateEstimation", "average");

   // Parse 'what'; it is in the form 'analysis(arg1,arg2,...)'
   TString args(what);
   args.ReplaceAll("("," ");
   args.ReplaceAll(")"," ");
   args.ReplaceAll(","," ");
   Ssiz_t from = 0;
   TString act, tok;
   if (!args.Tokenize(act, from, " ")) {
      // Cannot continue
      Printf("runProof: action not found: check your arguments (%s)", what);
      return;
   }

   // Action
   if (act == "simple") {
      // ProofSimple is an example of non-data driven analysis; it
      // creates and fills with random numbers a given number of histos
      TString aNevt, aNhist, opt;
      while (args.Tokenize(tok, from, " ")) {
         // Number of events
         if (tok.BeginsWith("nevt=")) {
            aNevt = tok;
            aNevt.ReplaceAll("nevt=","");
            if (!aNevt.IsDigit()) {
               Printf("runProof: error parsing the 'nevt=' option (%s) - ignoring", tok.Data());
               aNevt = "";
            }
         }
         // Number of histos
         if (tok.BeginsWith("nhist=")) {
            aNhist = tok;
            aNhist.ReplaceAll("nhist=","");
            if (!aNhist.IsDigit()) {
               Printf("runProof: error parsing the 'nhist=' option (%s) - ignoring", tok.Data());
               aNhist = "";
            }
         }
         // Sync or async ?
         if (tok.BeginsWith("asyn"))
            opt = "ASYN";
      }
      Long64_t nevt = (aNevt.IsNull()) ? 100000 : aNevt.Atoi();
      Int_t nhist = (aNhist.IsNull()) ? 100 : aNhist.Atoi();
      Printf("\nrunProof: running \"simple\" with nhist= %d and nevt= %d\n", nhist, nevt);

      // The number of histograms is added as parameter in the input list
      proof->SetParameter("ProofSimple_NHist", (Long_t)nhist);
      // The selector string
      TString sel = Form("%s/proof/ProofSimple.C+", tutorials.Data());
      //
      // Run it for nevt times
      proof->Process(sel.Data(), nevt, opt);

   } else if (act == "h1") {
      // This is the famous 'h1' example analysis run on Proof reading the
      // data from the ROOT http server.
      TString opt;
      while (args.Tokenize(tok, from, " ")) {
         // Sync or async ?
         if (tok.BeginsWith("asyn"))
            opt = "ASYN";
      }

      // Create the chain
      TChain *chain = new TChain("h42");
      chain->Add("http://root.cern.ch/files/h1/dstarmb.root");
      chain->Add("http://root.cern.ch/files/h1/dstarp1a.root");
      chain->Add("http://root.cern.ch/files/h1/dstarp1b.root");
      chain->Add("http://root.cern.ch/files/h1/dstarp2.root");
      // We run on Proof
      chain->SetProof();
      // The selector
      TString sel = Form("%s/tree/h1analysis.C+", tutorials.Data());
      // Run it for 10000 times
      Printf("\nrunProof: running \"h1\"\n");
      chain->Process(sel.Data(),opt);
   } else {
      // Do not know what to run
      Printf("runProof: unknown tutorial: %s", what);
   }
}
<commit_msg>Do not define the unused variable refloc (defined and used by getProof.C)<commit_after>//
// Macro to run examples of analysis on PROOF.
// This macro uses an existing PROOF session or starts one at the indicated URL.
// In the case non existing PROOF session is found and no URL is given, the macro
// tries to start a local PROOF session.
//
// To run the macro:
//
//   root[] .L proof/runProof.C+
//   root[] runProof("<analysis>")
//
//   Currently available analysis are:
//
//   1. "simple"
//
//      root[] runProof("simple")
//
//      This will create a local PROOF session and run an analysis filling 100 histos
//      with 100000 gaussian random numbers, and displaying them in a canvas with 100
//      pads (10x10).
//      The number of entries and the number of histograms can be passed as 'arguments'
//      to 'simple': e.g. to fill 16 histos with 1000000 entries use
//
//      root[] runProof("simple(nevt=1000000,nhist=16)")
//
//   2. "h1"
//
//      root[] runProof("h1")
//
//      This runs the 'famous' H1 analysis from $ROOTSYS/tree/h1analysis.C,.h .
//      The data are read from the HTTP server at root.cern.ch .
//
//   In all cases, to run in non blocking mode the option 'asyn' is available, e.g.
//
//   root[] runProof("h1(asyn)")
//
//   In all cases, to run on a remote Proof cluster, the master URL must be passed as
//   second argument; e.g.
//
//   root[] runProof("simple","master.domain")
//
//   In the case of local running it is possible to specify the number of workers to
//   start as third argument (the default is the number of cores of the machine), e.g.
//
//   root[] runProof("simple",0,4)
//
//   will start 4 workers. Note that the real number of workers is changed only the
//   first time you call runProof into a ROOT session; following calls can reduce the
//   number of active workers, but not increase it. For example, in the same session of
//   the call above starting 4 workers, this
//
//   root[] runProof("simple",0,8)
//
//   will still use 4 workers, while this
//
//   root[] runProof("simple",0,2)
//
//   will disable 2 workers and use the other 2.
//

#include "TChain.h"
#include "TEnv.h"
#include "TProof.h"
#include "TString.h"
#include "TDrawFeedback.h"
#include "TList.h"

#include "getProof.C"

void runProof(const char *what = "simple",
              const char *url = "proof://localhost:11093",
              Int_t nwrks = -1)
{
   gEnv->SetValue("Proof.StatsHist",1);

   // Temp dir for PROOF tutorials
   TString tutdir = Form("%s/.proof-tutorial", gSystem->TempDirectory());
   if (gSystem->AccessPathName(tutdir)) {
      Printf("runProof: creating the temporary directory"
                " for the tutorial (%s) ... ", tutdir.Data());
      if (gSystem->mkdir(tutdir, kTRUE) != 0) {
         Printf("runProof: could not assert / create the temporary directory"
                " for the tutorial (%s)", tutdir.Data());
         return;
      }
   }

   // Get the PROOF Session
   TProof *proof = getProof(url, nwrks, tutdir.Data(), "ask");
   if (!proof) {
      Printf("runProof: could not start/attach a PROOF session");
      return;
   }
   TString proofsessions(Form("%s/sessions",tutdir.Data()));
   // Save tag of the used session
   FILE *fs = fopen(proofsessions.Data(), "a");
   if (!fs) {
      Printf("runProof: could not create files for sessions tags");
   } else {
      fprintf(fs,"session-%s\n", proof->GetSessionTag());
      fclose(fs);
   }
   if (!proof) {
      Printf("runProof: could not start/attach a PROOF session");
      return;
   }

   // Set the number of workers (may only reduce the number of active workers
   // in the session)
   if (nwrks > 0)
      proof->SetParallel(nwrks);

   // Where is the code to run
   char *rootbin = gSystem->Which(gSystem->Getenv("PATH"), "root.exe", kExecutePermission);
   if (!rootbin) {
      Printf("runProof: root.exe not found: please check the environment!");
      return;
   }
   TString rootsys(gSystem->DirName(rootbin));
   rootsys = gSystem->DirName(rootsys);
   TString tutorials(Form("%s/tutorials", rootsys.Data()));
   delete[] rootbin;

   // Create feedback displayer
   TDrawFeedback fb(proof);

   // Number of events per worker
   proof->AddFeedback("PROOF_EventsHist");

   // Have constant progress reporting based on estimated info
   proof->SetParameter("PROOF_RateEstimation", "average");

   // Parse 'what'; it is in the form 'analysis(arg1,arg2,...)'
   TString args(what);
   args.ReplaceAll("("," ");
   args.ReplaceAll(")"," ");
   args.ReplaceAll(","," ");
   Ssiz_t from = 0;
   TString act, tok;
   if (!args.Tokenize(act, from, " ")) {
      // Cannot continue
      Printf("runProof: action not found: check your arguments (%s)", what);
      return;
   }

   // Action
   if (act == "simple") {
      // ProofSimple is an example of non-data driven analysis; it
      // creates and fills with random numbers a given number of histos
      TString aNevt, aNhist, opt;
      while (args.Tokenize(tok, from, " ")) {
         // Number of events
         if (tok.BeginsWith("nevt=")) {
            aNevt = tok;
            aNevt.ReplaceAll("nevt=","");
            if (!aNevt.IsDigit()) {
               Printf("runProof: error parsing the 'nevt=' option (%s) - ignoring", tok.Data());
               aNevt = "";
            }
         }
         // Number of histos
         if (tok.BeginsWith("nhist=")) {
            aNhist = tok;
            aNhist.ReplaceAll("nhist=","");
            if (!aNhist.IsDigit()) {
               Printf("runProof: error parsing the 'nhist=' option (%s) - ignoring", tok.Data());
               aNhist = "";
            }
         }
         // Sync or async ?
         if (tok.BeginsWith("asyn"))
            opt = "ASYN";
      }
      Long64_t nevt = (aNevt.IsNull()) ? 100000 : aNevt.Atoi();
      Int_t nhist = (aNhist.IsNull()) ? 100 : aNhist.Atoi();
      Printf("\nrunProof: running \"simple\" with nhist= %d and nevt= %d\n", nhist, nevt);

      // The number of histograms is added as parameter in the input list
      proof->SetParameter("ProofSimple_NHist", (Long_t)nhist);
      // The selector string
      TString sel = Form("%s/proof/ProofSimple.C+", tutorials.Data());
      //
      // Run it for nevt times
      proof->Process(sel.Data(), nevt, opt);

   } else if (act == "h1") {
      // This is the famous 'h1' example analysis run on Proof reading the
      // data from the ROOT http server.
      TString opt;
      while (args.Tokenize(tok, from, " ")) {
         // Sync or async ?
         if (tok.BeginsWith("asyn"))
            opt = "ASYN";
      }

      // Create the chain
      TChain *chain = new TChain("h42");
      chain->Add("http://root.cern.ch/files/h1/dstarmb.root");
      chain->Add("http://root.cern.ch/files/h1/dstarp1a.root");
      chain->Add("http://root.cern.ch/files/h1/dstarp1b.root");
      chain->Add("http://root.cern.ch/files/h1/dstarp2.root");
      // We run on Proof
      chain->SetProof();
      // The selector
      TString sel = Form("%s/tree/h1analysis.C+", tutorials.Data());
      // Run it for 10000 times
      Printf("\nrunProof: running \"h1\"\n");
      chain->Process(sel.Data(),opt);
   } else {
      // Do not know what to run
      Printf("runProof: unknown tutorial: %s", what);
   }
}
<|endoftext|>


<commit_before>// pythia8 basic example
//Author: Andreas Morsch
//
// to run, do
//  root > .x pythia8.C
//
// Note that before executing this script,
//   -the env variable PYTHIA8 must point to the pythia8100 (or newer) directory
//   -the env variable PYTHIA8DATA must be defined and it must point to $PYTHIA8/xmldoc
//
void pythia8(Int_t nev  = 100, Int_t ndeb = 1) {

   char* path = gSystem->ExpandPathName("$PYTHIA8DATA");
   if (gSystem->AccessPathName(path)) {
      Warning("pythia8.C",
              "Environment variable PYTHIA8DATA must contain path to pythi8100/xmldoc directory !");
      return;
   }

// Load libraries
   gSystem->Load("$PYTHIA8/lib/libpythia8");
   gSystem->Load("libEG");
   gSystem->Load("libEGPythia8");
// Histograms
   TH1F* etaH = new TH1F("etaH", "Pseudorapidity", 120, -12., 12.);
   TH1F* ptH  = new TH1F("ptH",  "pt",              50,   0., 10.);

// Array of particles
   TClonesArray* particles = new TClonesArray("TParticle", 1000);
// Create pythia8 object
   TPythia8* pythia8 = new TPythia8();

// Configure
   pythia8->ReadString("SoftQCD:minBias = on");
   pythia8->ReadString("SoftQCD:singleDiffractive = on");
   pythia8->ReadString("SoftQCD:doubleDiffractive = on");

// Initialize

   pythia8->Initialize(2212 /* p */, 2212 /* p */, 14000. /* TeV */);

// Event loop
   for (Int_t iev = 0; iev < nev; iev++) {
      pythia8->GenerateEvent();
      if (iev < ndeb) pythia8->EventListing();
      pythia8->ImportParticles(particles,"All");
      Int_t np = particles->GetEntriesFast();
// Particle loop
      for (Int_t ip = 0; ip < np; ip++) {
         TParticle* part = (TParticle*) particles->At(ip);
         Int_t ist = part->GetStatusCode();
         // Positive codes are final particles.
         if (ist <= 0) continue;
         Int_t pdg = part->GetPdgCode();
         Float_t charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
         if (charge == 0.) continue;
         Float_t eta = part->Eta();
         Float_t pt  = part->Pt();

         etaH->Fill(eta);
         if (pt > 0.) ptH->Fill(pt, 1./(2. * pt));
      }
   }

   pythia8->PrintStatistics();

   TCanvas* c1 = new TCanvas("c1","Pythia8 test example",800,800);
   c1->Divide(1, 2);
   c1->cd(1);
   etaH->Scale(5./Float_t(nev));
   etaH->Draw();
   etaH->SetXTitle("#eta");
   etaH->SetYTitle("dN/d#eta");

   c1->cd(2);
   gPad->SetLogy();
   ptH->Scale(5./Float_t(nev));
   ptH->Draw();
   ptH->SetXTitle("p_{t} [GeV/c]");
   ptH->SetYTitle("dN/dp_{t}^{2} [GeV/c]^{-2}");
 }
<commit_msg>if PYTHIA8 is defined and not PYTHIA8DATA then create PYTHIA8DATA based on PYTHIA8.<commit_after>// pythia8 basic example
//Author: Andreas Morsch
//
// to run, do
//  root > .x pythia8.C
//
// Note that before executing this script,
//   -the env variable PYTHIA8 must point to the pythia8100 (or newer) directory
//   -the env variable PYTHIA8DATA must be defined and it must point to $PYTHIA8/xmldoc
//
void pythia8(Int_t nev  = 100, Int_t ndeb = 1)
{
   char *p8dataenv = gSystem->Getenv("PYTHIA8DATA");
   if (!p8dataenv) {
      char *p8env = gSystem->Getenv("PYTHIA8");
      if (!p8env) {
         Error("pythia8.C",
               "Environment variable PYTHIA8 must contain path to pythi8 directory !");
         return;
      }
      TString p8d = gSystem->Getenv("PYTHIA8");
      p8d += "/xmldoc";
      gSystem->Setenv("PYTHIA8DATA", p8d);
   }

   char* path = gSystem->ExpandPathName("$PYTHIA8DATA");
   if (gSystem->AccessPathName(path)) {
         Error("pythia8.C",
               "Environment variable PYTHIA8DATA must contain path to pythi8/xmldoc directory !");
      return;
   }

// Load libraries
   gSystem->Load("$PYTHIA8/lib/libpythia8");
   gSystem->Load("libEG");
   gSystem->Load("libEGPythia8");
// Histograms
   TH1F* etaH = new TH1F("etaH", "Pseudorapidity", 120, -12., 12.);
   TH1F* ptH  = new TH1F("ptH",  "pt",              50,   0., 10.);

// Array of particles
   TClonesArray* particles = new TClonesArray("TParticle", 1000);
// Create pythia8 object
   TPythia8* pythia8 = new TPythia8();

// Configure
   pythia8->ReadString("SoftQCD:minBias = on");
   pythia8->ReadString("SoftQCD:singleDiffractive = on");
   pythia8->ReadString("SoftQCD:doubleDiffractive = on");

// Initialize

   pythia8->Initialize(2212 /* p */, 2212 /* p */, 14000. /* TeV */);

// Event loop
   for (Int_t iev = 0; iev < nev; iev++) {
      pythia8->GenerateEvent();
      if (iev < ndeb) pythia8->EventListing();
      pythia8->ImportParticles(particles,"All");
      Int_t np = particles->GetEntriesFast();
// Particle loop
      for (Int_t ip = 0; ip < np; ip++) {
         TParticle* part = (TParticle*) particles->At(ip);
         Int_t ist = part->GetStatusCode();
         // Positive codes are final particles.
         if (ist <= 0) continue;
         Int_t pdg = part->GetPdgCode();
         Float_t charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
         if (charge == 0.) continue;
         Float_t eta = part->Eta();
         Float_t pt  = part->Pt();

         etaH->Fill(eta);
         if (pt > 0.) ptH->Fill(pt, 1./(2. * pt));
      }
   }

   pythia8->PrintStatistics();

   TCanvas* c1 = new TCanvas("c1","Pythia8 test example",800,800);
   c1->Divide(1, 2);
   c1->cd(1);
   etaH->Scale(5./Float_t(nev));
   etaH->Draw();
   etaH->SetXTitle("#eta");
   etaH->SetYTitle("dN/d#eta");

   c1->cd(2);
   gPad->SetLogy();
   ptH->Scale(5./Float_t(nev));
   ptH->Draw();
   ptH->SetXTitle("p_{t} [GeV/c]");
   ptH->SetYTitle("dN/dp_{t}^{2} [GeV/c]^{-2}");
 }
<|endoftext|>


<commit_before>//+ Example of a simple script creating 3 threads.
// This script can only be executed via ACliC: .x threads.C++.
// Before executing the script, load the Thread library with:
//   gSystem->Load("libThread");
// This is not needed anymore due to the rootmap facility which
// automatically loads the needed libraries.
//Author: Victor Perevovchikov

#include "TThread.h"
#include <Riostream.h>
#include "TROOT.h"

TObject gObject;

class ClassA {
   int arrat[20];
};

TObject *myfunction () {
   static TObject obj[1024];
   return &obj[0];
}

void *handle(void *ptr)
{
   long nr = (long) ptr;

   long size = nr * 10000;
   void *addr = malloc(sizeof(ClassA)*size);
   TThread::Printf("Here I am before the loop for thread: %ld, an address on the stack: %p on the heap: %p as a global %p and a local function static: %p", nr, &nr, addr, &gObject, myfunction());

   for (int i = 0; i < 10; i++) {
      //TThread::Lock();
      //printf("Here I am loop index: %3d , thread: %d\n",i,nr);
      //TThread::UnLock();

      TThread::Printf("Here I am loop index: %d , thread: %ld", i, nr);
      gSystem->Sleep(1000);
   }

   return 0;
}

void threads()
{
#ifdef __CINT__
   printf("This script can only be executed via ACliC: .x threads.C++\n");
   return;
#endif

   gDebug = 1;

   int nr = gDebug;
   TObject *addr = new TObject;
   TThread::Printf("Main thread an address on the stack: %p on the heap: %p as a global %p and a function static: %p", &nr, addr, &gObject, gROOT);
   delete addr;

   printf("Starting Thread 1\n");
   TThread *h1 = new TThread("h1", handle, (void*) 1);
   h1->Run();
   printf("Starting Thread 2\n");
   TThread *h2 = new TThread("h2", handle, (void*) 2);
   h2->Run();
   printf("Starting Thread 3\n");
   TThread *h3 = new TThread("h3", handle, (void*) 3);
   h3->Run();

   TThread::Ps();

   h1->Join();
   TThread::Ps();
   h2->Join();
   h3->Join();
   TThread::Ps();
}
<commit_msg>revert unintended part of 44001<commit_after>//+ Example of a simple script creating 3 threads.
// This script can only be executed via ACliC: .x threads.C++.
// Before executing the script, load the Thread library with:
//   gSystem->Load("libThread");
// This is not needed anymore due to the rootmap facility which
// automatically loads the needed libraries.
//Author: Victor Perevovchikov

#include "TThread.h"
#include <Riostream.h>

void *handle(void *ptr)
{
   long nr = (long) ptr;

   for (int i = 0; i < 10; i++) {
      //TThread::Lock();
      //printf("Here I am loop index: %3d , thread: %d\n",i,nr);
      //TThread::UnLock();

      TThread::Printf("Here I am loop index: %d , thread: %ld", i, nr);
      gSystem->Sleep(1000);
   }
   return 0;
}

void threads()
{
#ifdef __CINT__
   printf("This script can only be executed via ACliC: .x threads.C++\n");
   return;
#endif

   gDebug = 1;

   printf("Starting Thread 1\n");
   TThread *h1 = new TThread("h1", handle, (void*) 1);
   h1->Run();
   printf("Starting Thread 2\n");
   TThread *h2 = new TThread("h2", handle, (void*) 2);
   h2->Run();
   printf("Starting Thread 3\n");
   TThread *h3 = new TThread("h3", handle, (void*) 3);
   h3->Run();

   TThread::Ps();

   h1->Join();
   TThread::Ps();
   h2->Join();
   h3->Join();
   TThread::Ps();
}
<|endoftext|>


<commit_before>/* Copyright 2020 Google LLC

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 "utils.hpp"

#include <math.h>
#include <torch/torch.h>

#include <iomanip>
#include <random>
#include <sstream>

torch::Tensor brownian_bridge(float t, float t0, float t1, torch::Tensor w0,
                              torch::Tensor w1) {
  auto mean = ((t1 - t) * w0 + (t - t0) * w1) / (t1 - t0);
  auto std = std::sqrt((t1 - t) * (t - t0) / (t1 - t0));
  return mean + torch::randn_like(mean) * std;
}

std::string format_float(float t, int precision) {
  std::stringstream stream;
  stream << std::fixed << std::setprecision(precision) << t;
  return stream.str();
}

torch::Tensor brownian_bridge_with_seed(double t, double t0, double t1,
                                        torch::Tensor w0, torch::Tensor w1,
                                        std::uint64_t seed) {
  // TODO: Make this also work for CUDA. Related issue:
  // https://github.com/pytorch/pytorch/issues/35078.
  std::shared_ptr<at::CPUGenerator> curr = at::detail::createCPUGenerator(seed);
  torch::Tensor mean = ((t1 - t) * w0 + (t - t0) * w1) / (t1 - t0);
  double std = std::sqrt((t1 - t) * (t - t0) / (t1 - t0));
  torch::Tensor bridge_point = at::normal(mean, std, curr.get());
  curr.reset();
  return bridge_point;
}

torch::Tensor binary_search_with_seed(double t, double t0, double t1,
                                      torch::Tensor w0, torch::Tensor w1,
                                      std::uint64_t parent, double tol) {
  std::seed_seq seq({parent});
  std::vector<std::uint64_t> seeds(3);
  seq.generate(seeds.begin(), seeds.end());

  std::uint64_t seedv = seeds[0];
  std::uint64_t seedl = seeds[1];
  std::uint64_t seedr = seeds[2];

  auto t_mid = (t0 + t1) / 2;
  auto w_mid = brownian_bridge_with_seed(t_mid, t0, t1, w0, w1, seedv);

  while (std::abs(t - t_mid) > tol) {
    if (t < t_mid) {
      t1 = t_mid;
      w1 = w_mid;
      parent = seedl;
    } else {
      t0 = t_mid;
      w0 = w_mid;
      parent = seedr;
    }

    std::seed_seq seq({parent});
    seq.generate(seeds.begin(), seeds.end());
    seedv = seeds[0];
    seedl = seeds[1];
    seedr = seeds[2];

    t_mid = (t0 + t1) / 2;
    w_mid = brownian_bridge_with_seed(t_mid, t0, t1, w0, w1, seedv);
  }
  return w_mid;
}
<commit_msg>Hack the CUDA case.<commit_after>/* Copyright 2020 Google LLC

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 "utils.hpp"

#include <math.h>
#include <torch/torch.h>

#include <iomanip>
#include <random>
#include <sstream>

torch::Tensor brownian_bridge(float t, float t0, float t1, torch::Tensor w0,
                              torch::Tensor w1) {
  auto mean = ((t1 - t) * w0 + (t - t0) * w1) / (t1 - t0);
  auto std = std::sqrt((t1 - t) * (t - t0) / (t1 - t0));
  return mean + torch::randn_like(mean) * std;
}

std::string format_float(float t, int precision) {
  std::stringstream stream;
  stream << std::fixed << std::setprecision(precision) << t;
  return stream.str();
}

torch::Tensor brownian_bridge_with_seed(double t, double t0, double t1,
                                        torch::Tensor w0, torch::Tensor w1,
                                        std::uint64_t seed) {
  // TODO: Make this also work for CUDA. Related issue:
  // https://github.com/pytorch/pytorch/issues/35078.
  std::shared_ptr<at::CPUGenerator> curr = at::detail::createCPUGenerator(seed);
  torch::Tensor mean = ((t1 - t) * w0 + (t - t0) * w1) / (t1 - t0);
  double std = std::sqrt((t1 - t) * (t - t0) / (t1 - t0));
  torch::Tensor bridge_point = at::normal(mean.cpu(), std, curr.get()).to(mean);
  curr.reset();
  return bridge_point;
}

torch::Tensor binary_search_with_seed(double t, double t0, double t1,
                                      torch::Tensor w0, torch::Tensor w1,
                                      std::uint64_t parent, double tol) {
  std::seed_seq seq({parent});
  std::vector<std::uint64_t> seeds(3);
  seq.generate(seeds.begin(), seeds.end());

  std::uint64_t seedv = seeds[0];
  std::uint64_t seedl = seeds[1];
  std::uint64_t seedr = seeds[2];

  auto t_mid = (t0 + t1) / 2;
  auto w_mid = brownian_bridge_with_seed(t_mid, t0, t1, w0, w1, seedv);

  while (std::abs(t - t_mid) > tol) {
    if (t < t_mid) {
      t1 = t_mid;
      w1 = w_mid;
      parent = seedl;
    } else {
      t0 = t_mid;
      w0 = w_mid;
      parent = seedr;
    }

    std::seed_seq seq({parent});
    seq.generate(seeds.begin(), seeds.end());
    seedv = seeds[0];
    seedl = seeds[1];
    seedr = seeds[2];

    t_mid = (t0 + t1) / 2;
    w_mid = brownian_bridge_with_seed(t_mid, t0, t1, w0, w1, seedv);
  }
  return w_mid;
}
<|endoftext|>


<commit_before>#include <boost/gil/gil_all.hpp>
#include <boost/gil/extension/io/png_io.hpp>

#include <util/Logger.h>
#include <util/helpers.hpp>
#include <gui/OpenGl.h>
#include <gui/ContextSettings.h>
#include <gui/Keys.h>
#include "Window.h"

using std::cout;
using std::endl;
using namespace boost::gil;

using namespace logger;

namespace gui {

LogChannel winlog("winlog", "[Window] ");

Window::Window(
		string caption,
		const WindowMode& mode) :
	WindowType(caption, mode),
	_region(0, 0, mode.size.x, mode.size.y),
	_resolution(mode.size.x, mode.size.y),
	_saveFrameRequest(false),
	_frameNumber(0),
	_frameBuffer(0),
	_clear_r(0.5),
	_clear_g(0.5),
	_clear_b(0.5) {

	registerInput(_painter, "painter");

	// register backward signals
	_painter.registerBackwardSlot(_resize);
	_painter.registerBackwardSlot(_keyDown);
	_painter.registerBackwardSlot(_keyUp);
	_painter.registerBackwardSlot(_mouseMove);
	_painter.registerBackwardSlot(_mouseDown);
	_painter.registerBackwardSlot(_mouseUp);

	// register backward callbacks
	_painter.registerBackwardCallback(&Window::onInputAdded, this);
	_painter.registerBackwardCallback(&Window::onModified, this);
	_painter.registerBackwardCallback(&Window::onSizeChanged, this);

	// initiate first redraw
	setDirty();
}

Window::~Window() {

	LOG_DEBUG(winlog) << "[" << getCaption() << "] destructing..." << endl;

	deleteFrameBuffer();

	LOG_DEBUG(winlog) << "[" << getCaption() << "] destructed" << endl;
}

void
Window::createFrameBuffer() {

	deleteFrameBuffer();

	_frameBuffer = new unsigned char[(int)_resolution.x*(int)_resolution.y*3];
}

void
Window::deleteFrameBuffer() {

	if (_frameBuffer) {

		delete[] _frameBuffer;
		_frameBuffer = 0;
	}
}

void
Window::configureViewport() {

	// we want to draw everywhere
	glViewport(0, 0, _resolution.x, _resolution.y);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// OpenGl units = pixels
	glOrtho(0, _resolution.x, _resolution.y, 0, -1000, 1000); // x left, x right, y bottom, y top, z min, z max

	glMatrixMode(GL_MODELVIEW);

	LOG_ALL(winlog) << "[" << getCaption() << "] set drawing area to "
	                << "(0, 0, " << _resolution.x << ", " << _resolution.y << ")"
	                << std::endl;

	GL_ASSERT;
}

const point<double>&
Window::getResolution() {

	return _resolution;
}

void
Window::processResizeEvent(int width, int height) {

	_region.maxX = width;
	_region.maxY = height;
	_resolution.x = width;
	_resolution.y = height;

	{
		// ensure that our context is active
		OpenGl::Guard guard(this);

		configureViewport();
		createFrameBuffer();
	}
}

void
Window::processKeyUpEvent(const keys::Key& key, const Modifiers& modifiers) {

	KeyUp signal(key, modifiers);
	_keyUp(signal);
}

void
Window::processKeyDownEvent(const keys::Key& key, const Modifiers& modifiers) {

	KeyDown signal(key, modifiers);
	_keyDown(signal);
}

bool
Window::processButtonUpEvent(
		const buttons::Button&     button,
		const util::point<double>& position,
		const Modifiers&           modifiers) {

	MouseUp signal(button, position, modifiers);
	_mouseUp(signal);
}

bool
Window::processButtonDownEvent(
		const buttons::Button&     button,
		const util::point<double>& position,
		const Modifiers&           modifiers) {

	LOG_ALL(winlog) << "[Window (" << getCaption() << ")] "
	                << "a mouse button was pressed" << std::endl;

	MouseDown signal(button, position, modifiers);
	_mouseDown(signal);
}

bool
Window::processMouseMoveEvent(
		const util::point<double>& position,
		const Modifiers&           modifiers) {

	MouseMove signal(position, modifiers);
	_mouseMove(signal);
}

GlContext*
Window::createGlContext() {

	LOG_ALL(winlog) << "[" << getCaption() << "] creating a new GlContext" << std::endl;

	GlContext* globalContext = OpenGl::getGlobalContext();
	globalContext->activate();

	ContextSettings settings;

	// create the context
	GlContext* glContext = new GlContext(this, settings, globalContext);

	// activate it
	glContext->activate();

	configureViewport();

	// return it
	return glContext;
}

void
Window::redraw() {

	// They say OpenGl is thread safe. They are wrong.
	boost::mutex::scoped_lock lock(OpenGl::getMutex());

	// prepare painters
	_resize(_region);

	// ensure that our context is active
	OpenGl::Guard guard(this);

	clear();

	LOG_ALL(winlog) << "[" << getCaption() << "] redrawing my content" << endl;

	if (_painter) {

		// make sure the painter is up-to-date
		updateInputs();

		// draw the updated painter
		_painter->draw(_region, point<double>(1.0, 1.0));

	} else {

		LOG_ALL(winlog) << "[" << getCaption() << "] no content so far..." << endl;
	}

	GL_ASSERT;

	flush();

	GL_ASSERT;
}

void
Window::clear() {

	glClearColor(_clear_r, _clear_g, _clear_b, 0.0);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	GL_ASSERT;
}

void
Window::flush() {

	OpenGl::flush();
}

void
Window::requestFrameSave() {

	_saveFrameRequest = true;
}

void
Window::saveFrame() {

	if (closed())
		return;

	// ensure that our context is active
	OpenGl::Guard guard(this);

	glReadPixels(
			0, 0,
			_resolution.x, _resolution.y,
			GL_RGB, GL_UNSIGNED_BYTE,
			_frameBuffer);
	GL_ASSERT;

	rgb8c_view_t frameView =
			interleaved_view(
					_resolution.x, _resolution.y,
					(const rgb8_pixel_t*)_frameBuffer,
					_resolution.x*3);

	png_write_view(
			"./shots/" + getCaption() + to_string_with_leading_zeros(_frameNumber, 8) + ".png",
			flipped_up_down_view(frameView));

	_frameNumber++;
}

void
Window::onInputAdded(const pipeline::InputAdded<gui::Painter>& signal) {

	setDirty();
}

void
Window::onModified(const pipeline::Modified& signal) {

	setDirty();
}

void
Window::onSizeChanged(const SizeChanged& signal) {

	// TODO:
	// Here, we could resize the window to fit the view. However, this should be
	// an optional feature.

	setDirty();
}

void
Window::processCloseEvent(){

	LOG_DEBUG(winlog) << "[" << getCaption() << "] invalidating my GlContext" << endl;

	// ensure that our context is destructed
	OpenGl::Guard guard(0);

	LOG_DEBUG(winlog) << "[" << getCaption() << "] closing window now" << endl;

	close();
}

} // namespace gui
<commit_msg>removed global lock on Window::redraw<commit_after>#include <boost/gil/gil_all.hpp>
#include <boost/gil/extension/io/png_io.hpp>

#include <util/Logger.h>
#include <util/helpers.hpp>
#include <gui/OpenGl.h>
#include <gui/ContextSettings.h>
#include <gui/Keys.h>
#include "Window.h"

using std::cout;
using std::endl;
using namespace boost::gil;

using namespace logger;

namespace gui {

LogChannel winlog("winlog", "[Window] ");

Window::Window(
		string caption,
		const WindowMode& mode) :
	WindowType(caption, mode),
	_region(0, 0, mode.size.x, mode.size.y),
	_resolution(mode.size.x, mode.size.y),
	_saveFrameRequest(false),
	_frameNumber(0),
	_frameBuffer(0),
	_clear_r(0.5),
	_clear_g(0.5),
	_clear_b(0.5) {

	registerInput(_painter, "painter");

	// register backward signals
	_painter.registerBackwardSlot(_resize);
	_painter.registerBackwardSlot(_keyDown);
	_painter.registerBackwardSlot(_keyUp);
	_painter.registerBackwardSlot(_mouseMove);
	_painter.registerBackwardSlot(_mouseDown);
	_painter.registerBackwardSlot(_mouseUp);

	// register backward callbacks
	_painter.registerBackwardCallback(&Window::onInputAdded, this);
	_painter.registerBackwardCallback(&Window::onModified, this);
	_painter.registerBackwardCallback(&Window::onSizeChanged, this);

	// initiate first redraw
	setDirty();
}

Window::~Window() {

	LOG_DEBUG(winlog) << "[" << getCaption() << "] destructing..." << endl;

	deleteFrameBuffer();

	LOG_DEBUG(winlog) << "[" << getCaption() << "] destructed" << endl;
}

void
Window::createFrameBuffer() {

	deleteFrameBuffer();

	_frameBuffer = new unsigned char[(int)_resolution.x*(int)_resolution.y*3];
}

void
Window::deleteFrameBuffer() {

	if (_frameBuffer) {

		delete[] _frameBuffer;
		_frameBuffer = 0;
	}
}

void
Window::configureViewport() {

	// we want to draw everywhere
	glViewport(0, 0, _resolution.x, _resolution.y);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// OpenGl units = pixels
	glOrtho(0, _resolution.x, _resolution.y, 0, -1000, 1000); // x left, x right, y bottom, y top, z min, z max

	glMatrixMode(GL_MODELVIEW);

	LOG_ALL(winlog) << "[" << getCaption() << "] set drawing area to "
	                << "(0, 0, " << _resolution.x << ", " << _resolution.y << ")"
	                << std::endl;

	GL_ASSERT;
}

const point<double>&
Window::getResolution() {

	return _resolution;
}

void
Window::processResizeEvent(int width, int height) {

	_region.maxX = width;
	_region.maxY = height;
	_resolution.x = width;
	_resolution.y = height;

	{
		// ensure that our context is active
		OpenGl::Guard guard(this);

		configureViewport();
		createFrameBuffer();
	}
}

void
Window::processKeyUpEvent(const keys::Key& key, const Modifiers& modifiers) {

	KeyUp signal(key, modifiers);
	_keyUp(signal);
}

void
Window::processKeyDownEvent(const keys::Key& key, const Modifiers& modifiers) {

	KeyDown signal(key, modifiers);
	_keyDown(signal);
}

bool
Window::processButtonUpEvent(
		const buttons::Button&     button,
		const util::point<double>& position,
		const Modifiers&           modifiers) {

	MouseUp signal(button, position, modifiers);
	_mouseUp(signal);
}

bool
Window::processButtonDownEvent(
		const buttons::Button&     button,
		const util::point<double>& position,
		const Modifiers&           modifiers) {

	LOG_ALL(winlog) << "[Window (" << getCaption() << ")] "
	                << "a mouse button was pressed" << std::endl;

	MouseDown signal(button, position, modifiers);
	_mouseDown(signal);
}

bool
Window::processMouseMoveEvent(
		const util::point<double>& position,
		const Modifiers&           modifiers) {

	MouseMove signal(position, modifiers);
	_mouseMove(signal);
}

GlContext*
Window::createGlContext() {

	LOG_ALL(winlog) << "[" << getCaption() << "] creating a new GlContext" << std::endl;

	GlContext* globalContext = OpenGl::getGlobalContext();
	globalContext->activate();

	ContextSettings settings;

	// create the context
	GlContext* glContext = new GlContext(this, settings, globalContext);

	// activate it
	glContext->activate();

	configureViewport();

	// return it
	return glContext;
}

void
Window::redraw() {

	// They say OpenGl is thread safe. They are wrong.
	//boost::mutex::scoped_lock lock(OpenGl::getMutex());

	// prepare painters
	_resize(_region);

	// ensure that our context is active
	OpenGl::Guard guard(this);

	clear();

	LOG_ALL(winlog) << "[" << getCaption() << "] redrawing my content" << endl;

	if (_painter) {

		// make sure the painter is up-to-date
		updateInputs();

		// draw the updated painter
		_painter->draw(_region, point<double>(1.0, 1.0));

	} else {

		LOG_ALL(winlog) << "[" << getCaption() << "] no content so far..." << endl;
	}

	GL_ASSERT;

	flush();

	GL_ASSERT;
}

void
Window::clear() {

	glClearColor(_clear_r, _clear_g, _clear_b, 0.0);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	GL_ASSERT;
}

void
Window::flush() {

	OpenGl::flush();
}

void
Window::requestFrameSave() {

	_saveFrameRequest = true;
}

void
Window::saveFrame() {

	if (closed())
		return;

	// ensure that our context is active
	OpenGl::Guard guard(this);

	glReadPixels(
			0, 0,
			_resolution.x, _resolution.y,
			GL_RGB, GL_UNSIGNED_BYTE,
			_frameBuffer);
	GL_ASSERT;

	rgb8c_view_t frameView =
			interleaved_view(
					_resolution.x, _resolution.y,
					(const rgb8_pixel_t*)_frameBuffer,
					_resolution.x*3);

	png_write_view(
			"./shots/" + getCaption() + to_string_with_leading_zeros(_frameNumber, 8) + ".png",
			flipped_up_down_view(frameView));

	_frameNumber++;
}

void
Window::onInputAdded(const pipeline::InputAdded<gui::Painter>& signal) {

	setDirty();
}

void
Window::onModified(const pipeline::Modified& signal) {

	setDirty();
}

void
Window::onSizeChanged(const SizeChanged& signal) {

	// TODO:
	// Here, we could resize the window to fit the view. However, this should be
	// an optional feature.

	setDirty();
}

void
Window::processCloseEvent(){

	LOG_DEBUG(winlog) << "[" << getCaption() << "] invalidating my GlContext" << endl;

	// ensure that our context is destructed
	OpenGl::Guard guard(0);

	LOG_DEBUG(winlog) << "[" << getCaption() << "] closing window now" << endl;

	close();
}

} // namespace gui
<|endoftext|>


<commit_before>#include "Serialization.h"

#include "tarch/Assertions.h"

Serialization::Block::Block(size_t blocksize, unsigned char * const block_ptr)
:   blocksize(blocksize),
    block_ptr(block_ptr),
    position(0)
{

}

Serialization::Block::~Block() {

}

void Serialization::Block::pack(size_t count, const unsigned char* buffer) {
    // TODO: assertion: position < blocksize
    memcpy(block_ptr+position, buffer, count);
    position += count;
}

void Serialization::Block::unpack(size_t count, unsigned char* buffer) {
    // TODO: assertion: position < blocksize
    memcpy(buffer, block_ptr+position, count);
    position += count;
}

/////////////////////////////////////////////////////////////////

// stack = true: put size at end of block
// stack = false: put size at beginning of block
Serialization::SendBuffer::SendBuffer(bool stack)
    : stack(stack)
{
    reset();
}

Serialization::SendBuffer::~SendBuffer() {

}

// every section is built of payload data + size information
Serialization::Block Serialization::SendBuffer::reserveBlock(size_t blocksize) {
    const size_t total_blocksize = blocksize + sizeof(size_t);
    const size_t current_storageSize = storage.size();
    const size_t required_storageSize = position + total_blocksize;
    if (required_storageSize > current_storageSize) {
        storage.resize(required_storageSize);
    }

    unsigned char* const totalblock_ptr = storage.data() + position;
    unsigned char* result_ptr;
    size_t* size_ptr;

    if (stack) {
      result_ptr = totalblock_ptr;
      size_ptr = reinterpret_cast<size_t*>(totalblock_ptr + blocksize);
    } else {
      assertionFail("No stack.");
      size_ptr = reinterpret_cast<size_t*>(totalblock_ptr);
      result_ptr = totalblock_ptr + sizeof(size_t);
    }
    *size_ptr = blocksize;

    position += total_blocksize;
    return Serialization::Block(blocksize, result_ptr);
}

void Serialization::SendBuffer::reset() {
    position = 0;
    storage.clear();
}

bool Serialization::SendBuffer::verifyBlocks() const {
  if(stack) {
    size_t pos = position;
    while(pos > 0) {
      //TODO unterweg debug
//      std::cout << "pos=" << pos << " storage.size=" << storage.size() << std::endl;
      size_t blockSize = *(reinterpret_cast<const size_t*>(storage.data() + pos - sizeof(size_t)));
      assertion3(blockSize > 0, blockSize, pos, size());
//      std::cout << "\tblockSize=" << blockSize << std::endl;
      pos -= (blockSize + sizeof(size_t));
    }
    assertionEquals(pos, 0);
    return pos == 0;
  } else {
    assertionFail("Not implemented...");
    return false;
  }
}

/////////////////////////////////////////////////////////////////

Serialization::ReceiveBuffer::ReceiveBuffer(bool stack)
    : stack(stack),
      position(0)
{
}

Serialization::ReceiveBuffer::~ReceiveBuffer() {

}

bool Serialization::ReceiveBuffer::isBlockAvailable() {
    bool result = !storage.empty();
    if (stack) {
        result &= (position != 0);
    } else {
        result &= (position != size());
    }
    return result;
}

Serialization::Block Serialization::ReceiveBuffer::nextBlock() {
    unsigned char * const totalblock_ptr = storage.data() + position;
    size_t* size_ptr;
    unsigned char* result_ptr;

    size_t blocksize = 0;
    if (stack) {
        size_ptr = reinterpret_cast<size_t*>(totalblock_ptr - sizeof(size_t));
        blocksize = *size_ptr;
        result_ptr = totalblock_ptr - (sizeof(size_t) + blocksize);

        position -= (sizeof(size_t) + blocksize);
    } else {
        assertionFail("No stack.");
        size_ptr = reinterpret_cast<size_t*>(totalblock_ptr);
        blocksize = *size_ptr;
        result_ptr = totalblock_ptr + sizeof(size_t);

        position += (sizeof(size_t) + blocksize);
    }
    return Serialization::Block(blocksize, result_ptr);
}

void Serialization::ReceiveBuffer::reset(size_t storageSize) {
    storage.clear();
    storage.resize(storageSize);

    if (stack) {
        position = size();
    } else {
        position = 0;
    }
}

bool Serialization::ReceiveBuffer::verifyBlocks() const {
  if(stack) {
    size_t pos = storage.size();
    while(pos > 0) {
      //TODO unterweg debug
//      std::cout << "pos=" << pos << " storage.size=" << storage.size() << std::endl;
      size_t blockSize = *(reinterpret_cast<const size_t*>(storage.data() + pos - sizeof(size_t)));
      assertion3(blockSize > 0, blockSize, pos, size());
//      std::cout << "\tblockSize=" << blockSize << std::endl;
      pos -= (blockSize + sizeof(size_t));
    }
    assertionEquals(pos, 0);
    return pos == 0;
  } else {
    assertionFail("Not implemented...");
    return false;
  }
}

<commit_msg>added assertions<commit_after>#include "Serialization.h"

#include "tarch/Assertions.h"

Serialization::Block::Block(size_t blocksize, unsigned char * const block_ptr)
:   blocksize(blocksize),
    block_ptr(block_ptr),
    position(0)
{

}

Serialization::Block::~Block() {

}

void Serialization::Block::pack(size_t count, const unsigned char* buffer) {
    // TODO: assertion: position < blocksize
    memcpy(block_ptr+position, buffer, count);
    position += count;
}

void Serialization::Block::unpack(size_t count, unsigned char* buffer) {
    // TODO: assertion: position < blocksize
    memcpy(buffer, block_ptr+position, count);
    position += count;
}

/////////////////////////////////////////////////////////////////

// stack = true: put size at end of block
// stack = false: put size at beginning of block
Serialization::SendBuffer::SendBuffer(bool stack)
    : stack(stack)
{
    reset();
}

Serialization::SendBuffer::~SendBuffer() {

}

// every section is built of payload data + size information
Serialization::Block Serialization::SendBuffer::reserveBlock(size_t blocksize) {
    const size_t total_blocksize = blocksize + sizeof(size_t);
    const size_t current_storageSize = storage.size();
    const size_t required_storageSize = position + total_blocksize;
    if (required_storageSize > current_storageSize) {
        storage.resize(required_storageSize);
    }

    unsigned char* const totalblock_ptr = storage.data() + position;
    unsigned char* result_ptr;
    size_t* size_ptr;

    if (stack) {
      result_ptr = totalblock_ptr;
      size_ptr = reinterpret_cast<size_t*>(totalblock_ptr + blocksize);
    } else {
      assertionFail("No stack.");
      size_ptr = reinterpret_cast<size_t*>(totalblock_ptr);
      result_ptr = totalblock_ptr + sizeof(size_t);
    }
    *size_ptr = blocksize;

    position += total_blocksize;
    return Serialization::Block(blocksize, result_ptr);
}

void Serialization::SendBuffer::reset() {
    position = 0;
    storage.clear();
}

bool Serialization::SendBuffer::verifyBlocks() const {
  if(stack) {
    size_t pos = position;
    while(pos > sizeof(size_t)) {
      //TODO unterweg debug
//      std::cout << "pos=" << pos << " storage.size=" << storage.size() << std::endl;
      assertion3(pos <= position, pos, position, size());
      size_t blockSize = *(reinterpret_cast<const size_t*>(storage.data() + pos - sizeof(size_t)));
//      std::cout << "\tblockSize=" << blockSize << std::endl;
      pos -= (blockSize + sizeof(size_t));
    }
    assertionEquals(pos, 0);
    return pos == 0;
  } else {
    assertionFail("Not implemented...");
    return false;
  }
}

/////////////////////////////////////////////////////////////////

Serialization::ReceiveBuffer::ReceiveBuffer(bool stack)
    : stack(stack),
      position(0)
{
}

Serialization::ReceiveBuffer::~ReceiveBuffer() {

}

bool Serialization::ReceiveBuffer::isBlockAvailable() {
    bool result = !storage.empty();
    if (stack) {
        result &= (position != 0);
    } else {
        result &= (position != size());
    }
    return result;
}

Serialization::Block Serialization::ReceiveBuffer::nextBlock() {
    unsigned char * const totalblock_ptr = storage.data() + position;
    size_t* size_ptr;
    unsigned char* result_ptr;

    size_t blocksize = 0;
    if (stack) {
        size_ptr = reinterpret_cast<size_t*>(totalblock_ptr - sizeof(size_t));
        blocksize = *size_ptr;
        result_ptr = totalblock_ptr - (sizeof(size_t) + blocksize);

        position -= (sizeof(size_t) + blocksize);
    } else {
        assertionFail("No stack.");
        size_ptr = reinterpret_cast<size_t*>(totalblock_ptr);
        blocksize = *size_ptr;
        result_ptr = totalblock_ptr + sizeof(size_t);

        position += (sizeof(size_t) + blocksize);
    }
    return Serialization::Block(blocksize, result_ptr);
}

void Serialization::ReceiveBuffer::reset(size_t storageSize) {
    storage.clear();
    storage.resize(storageSize);

    if (stack) {
        position = size();
    } else {
        position = 0;
    }
}

bool Serialization::ReceiveBuffer::verifyBlocks() const {
  if(stack) {
    size_t pos = size();
    while(pos > sizeof(size_t)) {
      //TODO unterweg debug
//      std::cout << "pos=" << pos << " storage.size=" << storage.size() << std::endl;
      assertion2(pos <= size(), pos, size());
      size_t blockSize = *(reinterpret_cast<const size_t*>(storage.data() + pos - sizeof(size_t)));
      assertion3(blockSize > 0, blockSize, pos, size());
//      std::cout << "\tblockSize=" << blockSize << std::endl;
      pos -= (blockSize + sizeof(size_t));
    }
    assertionEquals(pos, 0);
    return pos == 0;
  } else {
    assertionFail("Not implemented...");
    return false;
  }
}

<|endoftext|>


<commit_before>#include "MasyuField.h"
#include "MasyuProblem.h"

namespace Penciloid
{
MasyuField::MasyuField()
{
	height = 0;
	width = 0;

	hints = nullptr;
}

MasyuField::~MasyuField()
{
	if (hints) delete[] hints;
}

void MasyuField::Init(int height_t, int width_t)
{
	height = height_t;
	width = width_t;

	if (hints) delete[] hints;
	hints = new int[height * width];

	for (int i = 0; i < height * width; ++i) hints[i] = HINT_NONE;

	auxiliary.Init(this);
	grid.SetAuxiliarySolver(&auxiliary);
	grid.Init(height - 1, width - 1);
}

void MasyuField::Init(MasyuProblem &prob)
{
	Init(prob.GetHeight(), prob.GetWidth());

	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			int hint = prob.GetHint(i, j);

			if (hint != HINT_NONE) SetHint(i, j, hint);
		}
	}
}

int MasyuField::SetHint(int y, int x, int hint)
{
	int id = VertexId(y, x);

	if (hints[id] != HINT_NONE) {
		if (hints[id] != hint) {
			return grid.UpdateStatus(SolverStatus::INCONSISTENT);
		}
		return grid.UpdateStatus(0);
	}

	hints[id] = hint;
	CheckTheorem(y * 2, x * 2);
	CheckVertex(y * 2, x * 2);

	return grid.GetStatus();
}

void MasyuField::CheckTheorem(int y, int x)
{
	// TODO: implement appropriately
}

void MasyuField::CheckVertex(int y, int x)
{
	int hint = hints[VertexId(y/ 2, x / 2)];

	if (hint == HINT_WHITE) {
		// TODO: faster checker
		int neighborhood_segment_style[16];

		for (int i = 0; i < 16; ++i) {
			neighborhood_segment_style[i] = grid.GetSegmentStyleSafe(
				y + GridConstant::GRID_DY[i / 4] * 2 + GridConstant::GRID_DY[i % 4],
				x + GridConstant::GRID_DX[i / 4] * 2 + GridConstant::GRID_DX[i % 4]
				);
		}

		int segment_line_candidate = (1 << 16) - 1;
		int segment_blank_candidate = (1 << 16) - 1;

		do {
			if (neighborhood_segment_style[2] == LOOP_BLANK) break;
			if (neighborhood_segment_style[8] == LOOP_BLANK) break;
			if (neighborhood_segment_style[7] == LOOP_LINE) break;
			if (neighborhood_segment_style[13] == LOOP_LINE) break;

			int end1[] = { 0, 1, 3 };
			int end2[] = { 10, 9, 11 };

			for (int i = 0; i < 3; ++i) {
				for (int j = 0; j < 3; ++j) {
					if (i == 0 && j == 0) continue;

					if (neighborhood_segment_style[end1[i]] == LOOP_BLANK) continue;
					if (neighborhood_segment_style[end2[j]] == LOOP_BLANK) continue;
					if (neighborhood_segment_style[end1[(i + 1) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end2[(j + 1) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end1[(i + 2) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end2[(j + 2) % 3]] == LOOP_LINE) continue;

					int line_location = (1 << 2) | (1 << 8) | (1 << end1[i]) | (1 << end2[j]);
					int blank_location = ((15 << 0) | (15 << 8)) ^ line_location;

					segment_line_candidate &= line_location;
					segment_blank_candidate &= blank_location;
				}
			}
		} while (false);

		do {
			if (neighborhood_segment_style[7] == LOOP_BLANK) break;
			if (neighborhood_segment_style[13] == LOOP_BLANK) break;
			if (neighborhood_segment_style[2] == LOOP_LINE) break;
			if (neighborhood_segment_style[8] == LOOP_LINE) break;

			int end1[] = { 5, 4, 6 };
			int end2[] = { 15, 12, 14 };

			for (int i = 0; i < 3; ++i) {
				for (int j = 0; j < 3; ++j) {
					if (i == 0 && j == 0) continue;

					if (neighborhood_segment_style[end1[i]] == LOOP_BLANK) continue;
					if (neighborhood_segment_style[end2[j]] == LOOP_BLANK) continue;
					if (neighborhood_segment_style[end1[(i + 1) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end2[(j + 1) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end1[(i + 2) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end2[(j + 2) % 3]] == LOOP_LINE) continue;

					int line_location = (1 << 7) | (1 << 13) | (1 << end1[i]) | (1 << end2[j]);
					int blank_location = ((15 << 4) | (15 << 12)) ^ line_location;

					segment_line_candidate &= line_location;
					segment_blank_candidate &= blank_location;
				}
			}
		} while (false);

		for (int i = 0; i < 16; ++i) {
			if (segment_line_candidate & (1 << i)) {
				grid.DetermineLine(
					y + GridConstant::GRID_DY[i / 4] * 2 + GridConstant::GRID_DY[i % 4],
					x + GridConstant::GRID_DX[i / 4] * 2 + GridConstant::GRID_DX[i % 4]
					);
			}

			if (segment_blank_candidate & (1 << i)) {
				grid.DetermineBlank(
					y + GridConstant::GRID_DY[i / 4] * 2 + GridConstant::GRID_DY[i % 4],
					x + GridConstant::GRID_DX[i / 4] * 2 + GridConstant::GRID_DX[i % 4]
					);
			}
		}

	} else if (hint == HINT_BLACK) {
		int line_direction_candidate = 15;

		for (int i = 0; i < 4; ++i) {
			int dy1 = GridConstant::GRID_DY[i], dx1 = GridConstant::GRID_DX[i];
			int dy2 = GridConstant::GRID_DY[(i + 1) & 3], dx2 = GridConstant::GRID_DX[(i + 1) & 3];

			if (grid.GetSegmentStyleSafe(y + dy1, x + dx1) == LOOP_BLANK) continue;
			if (grid.GetSegmentStyleSafe(y + dy1 * 3, x + dx1 * 3) == LOOP_BLANK) continue;
			if (grid.GetSegmentStyleSafe(y + dy2, x + dx2) == LOOP_BLANK) continue;
			if (grid.GetSegmentStyleSafe(y + dy2 * 3, x + dx2 * 3) == LOOP_BLANK) continue;
			if (grid.GetSegmentStyleSafe(y + dy1 * 2 + dy2, x + dx1 * 2 + dx2) == LOOP_LINE) continue;
			if (grid.GetSegmentStyleSafe(y + dy1 * 2 - dy2, x + dx1 * 2 - dx2) == LOOP_LINE) continue;
			if (grid.GetSegmentStyleSafe(y + dy2 * 2 + dy1, x + dx2 * 2 + dx1) == LOOP_LINE) continue;
			if (grid.GetSegmentStyleSafe(y + dy2 * 2 - dy1, x + dx2 * 2 - dx1) == LOOP_LINE) continue;

			line_direction_candidate &= ((1 << i) | (1 << ((i + 1) & 3)));
		}

		for (int i = 0; i < 4; ++i) if (line_direction_candidate & (1 << i)) {
			int dy = GridConstant::GRID_DY[i], dx = GridConstant::GRID_DX[i];
			grid.DetermineLine(y + dy, x + dx);
			grid.DetermineLine(y + dy * 3, x + dx * 3);
			grid.DetermineBlank(y - dy, x - dx);
		}
	}
}

void MasyuField::Debug()
{
	for (int i = 0; i <= (height - 1) * 2; ++i) {
		for (int j = 0; j <= (width - 1) * 2; ++j) {
			if (i % 2 == 0 && j % 2 == 0) {
				int hint = hints[VertexId(i / 2, j / 2)];

				if (hint == HINT_NONE) fprintf(stderr, "+");
				else if (hint == HINT_WHITE) fprintf(stderr, "O");
				else if (hint == HINT_BLACK) fprintf(stderr, "#");
			} else if (i % 2 == 0 && j % 2 == 1) {
				int style = GetSegmentStyle(i, j);
				if (style == LOOP_UNDECIDED) fprintf(stderr, "   ");
				if (style == LOOP_LINE) fprintf(stderr, "---");
				if (style == LOOP_BLANK) fprintf(stderr, " X ");
			} else if (i % 2 == 1 && j % 2 == 0) {
				int style = GetSegmentStyle(i, j);
				if (style == LOOP_UNDECIDED) fprintf(stderr, " ");
				if (style == LOOP_LINE) fprintf(stderr, "|");
				if (style == LOOP_BLANK) fprintf(stderr, "X");
			} else if (i % 2 == 1 && j % 2 == 1) {
				fprintf(stderr, "   ");
			}
		}
		fprintf(stderr, "\n");
	}
}

}<commit_msg>Add a theorem in MasyuField<commit_after>#include "MasyuField.h"
#include "MasyuProblem.h"

namespace Penciloid
{
MasyuField::MasyuField()
{
	height = 0;
	width = 0;

	hints = nullptr;
}

MasyuField::~MasyuField()
{
	if (hints) delete[] hints;
}

void MasyuField::Init(int height_t, int width_t)
{
	height = height_t;
	width = width_t;

	if (hints) delete[] hints;
	hints = new int[height * width];

	for (int i = 0; i < height * width; ++i) hints[i] = HINT_NONE;

	auxiliary.Init(this);
	grid.SetAuxiliarySolver(&auxiliary);
	grid.Init(height - 1, width - 1);
}

void MasyuField::Init(MasyuProblem &prob)
{
	Init(prob.GetHeight(), prob.GetWidth());

	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			int hint = prob.GetHint(i, j);

			if (hint != HINT_NONE) SetHint(i, j, hint);
		}
	}
}

int MasyuField::SetHint(int y, int x, int hint)
{
	int id = VertexId(y, x);

	if (hints[id] != HINT_NONE) {
		if (hints[id] != hint) {
			return grid.UpdateStatus(SolverStatus::INCONSISTENT);
		}
		return grid.UpdateStatus(0);
	}

	hints[id] = hint;
	CheckTheorem(y * 2, x * 2);
	CheckVertex(y * 2, x * 2);

	return grid.GetStatus();
}

void MasyuField::CheckTheorem(int y, int x)
{
	// TODO: implement appropriately

	int hint = hints[VertexId(y / 2, x / 2)];

	if (hint == HINT_WHITE) {
		for (int i = 0; i < 2; ++i) {
			int dy = GridConstant::GRID_DY[i], dx = GridConstant::GRID_DX[i];

			for (int j = 0; j <= 2; ++j) {
				if    (GetHintSafe(y / 2 + (j - 2) * dy, x / 2 + (j - 2) * dx) == HINT_WHITE
					&& GetHintSafe(y / 2 + (j - 1) * dy, x / 2 + (j - 1) * dx) == HINT_WHITE
					&& GetHintSafe(y / 2 + (j - 0) * dy, x / 2 + (j - 0) * dx) == HINT_WHITE) {
					grid.DetermineLine(y + 2 * (j - 2) * dy + dx, x + 2 * (j - 2) * dx + dy);
					grid.DetermineLine(y + 2 * (j - 2) * dy - dx, x + 2 * (j - 2) * dx - dy);
					grid.DetermineLine(y + 2 * (j - 1) * dy + dx, x + 2 * (j - 1) * dx + dy);
					grid.DetermineLine(y + 2 * (j - 1) * dy - dx, x + 2 * (j - 1) * dx - dy);
					grid.DetermineLine(y + 2 * (j - 0) * dy + dx, x + 2 * (j - 0) * dx + dy);
					grid.DetermineLine(y + 2 * (j - 0) * dy - dx, x + 2 * (j - 0) * dx - dy);
				}
			}
		}
	}
}

void MasyuField::CheckVertex(int y, int x)
{
	int hint = hints[VertexId(y / 2, x / 2)];

	if (hint == HINT_WHITE) {
		// TODO: faster checker
		int neighborhood_segment_style[16];

		for (int i = 0; i < 16; ++i) {
			neighborhood_segment_style[i] = grid.GetSegmentStyleSafe(
				y + GridConstant::GRID_DY[i / 4] * 2 + GridConstant::GRID_DY[i % 4],
				x + GridConstant::GRID_DX[i / 4] * 2 + GridConstant::GRID_DX[i % 4]
				);
		}

		int segment_line_candidate = (1 << 16) - 1;
		int segment_blank_candidate = (1 << 16) - 1;

		do {
			if (neighborhood_segment_style[2] == LOOP_BLANK) break;
			if (neighborhood_segment_style[8] == LOOP_BLANK) break;
			if (neighborhood_segment_style[7] == LOOP_LINE) break;
			if (neighborhood_segment_style[13] == LOOP_LINE) break;

			int end1[] = { 0, 1, 3 };
			int end2[] = { 10, 9, 11 };

			for (int i = 0; i < 3; ++i) {
				for (int j = 0; j < 3; ++j) {
					if (i == 0 && j == 0) continue;

					if (neighborhood_segment_style[end1[i]] == LOOP_BLANK) continue;
					if (neighborhood_segment_style[end2[j]] == LOOP_BLANK) continue;
					if (neighborhood_segment_style[end1[(i + 1) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end2[(j + 1) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end1[(i + 2) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end2[(j + 2) % 3]] == LOOP_LINE) continue;

					int line_location = (1 << 2) | (1 << 8) | (1 << end1[i]) | (1 << end2[j]);
					int blank_location = ((15 << 0) | (15 << 8)) ^ line_location;

					segment_line_candidate &= line_location;
					segment_blank_candidate &= blank_location;
				}
			}
		} while (false);

		do {
			if (neighborhood_segment_style[7] == LOOP_BLANK) break;
			if (neighborhood_segment_style[13] == LOOP_BLANK) break;
			if (neighborhood_segment_style[2] == LOOP_LINE) break;
			if (neighborhood_segment_style[8] == LOOP_LINE) break;

			int end1[] = { 5, 4, 6 };
			int end2[] = { 15, 12, 14 };

			for (int i = 0; i < 3; ++i) {
				for (int j = 0; j < 3; ++j) {
					if (i == 0 && j == 0) continue;

					if (neighborhood_segment_style[end1[i]] == LOOP_BLANK) continue;
					if (neighborhood_segment_style[end2[j]] == LOOP_BLANK) continue;
					if (neighborhood_segment_style[end1[(i + 1) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end2[(j + 1) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end1[(i + 2) % 3]] == LOOP_LINE) continue;
					if (neighborhood_segment_style[end2[(j + 2) % 3]] == LOOP_LINE) continue;

					int line_location = (1 << 7) | (1 << 13) | (1 << end1[i]) | (1 << end2[j]);
					int blank_location = ((15 << 4) | (15 << 12)) ^ line_location;

					segment_line_candidate &= line_location;
					segment_blank_candidate &= blank_location;
				}
			}
		} while (false);

		for (int i = 0; i < 16; ++i) {
			if (segment_line_candidate & (1 << i)) {
				grid.DetermineLine(
					y + GridConstant::GRID_DY[i / 4] * 2 + GridConstant::GRID_DY[i % 4],
					x + GridConstant::GRID_DX[i / 4] * 2 + GridConstant::GRID_DX[i % 4]
					);
			}

			if (segment_blank_candidate & (1 << i)) {
				grid.DetermineBlank(
					y + GridConstant::GRID_DY[i / 4] * 2 + GridConstant::GRID_DY[i % 4],
					x + GridConstant::GRID_DX[i / 4] * 2 + GridConstant::GRID_DX[i % 4]
					);
			}
		}

	} else if (hint == HINT_BLACK) {
		int line_direction_candidate = 15;

		for (int i = 0; i < 4; ++i) {
			int dy1 = GridConstant::GRID_DY[i], dx1 = GridConstant::GRID_DX[i];
			int dy2 = GridConstant::GRID_DY[(i + 1) & 3], dx2 = GridConstant::GRID_DX[(i + 1) & 3];

			if (grid.GetSegmentStyleSafe(y + dy1, x + dx1) == LOOP_BLANK) continue;
			if (grid.GetSegmentStyleSafe(y + dy1 * 3, x + dx1 * 3) == LOOP_BLANK) continue;
			if (grid.GetSegmentStyleSafe(y + dy2, x + dx2) == LOOP_BLANK) continue;
			if (grid.GetSegmentStyleSafe(y + dy2 * 3, x + dx2 * 3) == LOOP_BLANK) continue;
			if (grid.GetSegmentStyleSafe(y + dy1 * 2 + dy2, x + dx1 * 2 + dx2) == LOOP_LINE) continue;
			if (grid.GetSegmentStyleSafe(y + dy1 * 2 - dy2, x + dx1 * 2 - dx2) == LOOP_LINE) continue;
			if (grid.GetSegmentStyleSafe(y + dy2 * 2 + dy1, x + dx2 * 2 + dx1) == LOOP_LINE) continue;
			if (grid.GetSegmentStyleSafe(y + dy2 * 2 - dy1, x + dx2 * 2 - dx1) == LOOP_LINE) continue;

			line_direction_candidate &= ((1 << i) | (1 << ((i + 1) & 3)));
		}

		for (int i = 0; i < 4; ++i) if (line_direction_candidate & (1 << i)) {
			int dy = GridConstant::GRID_DY[i], dx = GridConstant::GRID_DX[i];
			grid.DetermineLine(y + dy, x + dx);
			grid.DetermineLine(y + dy * 3, x + dx * 3);
			grid.DetermineBlank(y - dy, x - dx);
		}
	}
}

void MasyuField::Debug()
{
	for (int i = 0; i <= (height - 1) * 2; ++i) {
		for (int j = 0; j <= (width - 1) * 2; ++j) {
			if (i % 2 == 0 && j % 2 == 0) {
				int hint = hints[VertexId(i / 2, j / 2)];

				if (hint == HINT_NONE) fprintf(stderr, "+");
				else if (hint == HINT_WHITE) fprintf(stderr, "O");
				else if (hint == HINT_BLACK) fprintf(stderr, "#");
			} else if (i % 2 == 0 && j % 2 == 1) {
				int style = GetSegmentStyle(i, j);
				if (style == LOOP_UNDECIDED) fprintf(stderr, "   ");
				if (style == LOOP_LINE) fprintf(stderr, "---");
				if (style == LOOP_BLANK) fprintf(stderr, " X ");
			} else if (i % 2 == 1 && j % 2 == 0) {
				int style = GetSegmentStyle(i, j);
				if (style == LOOP_UNDECIDED) fprintf(stderr, " ");
				if (style == LOOP_LINE) fprintf(stderr, "|");
				if (style == LOOP_BLANK) fprintf(stderr, "X");
			} else if (i % 2 == 1 && j % 2 == 1) {
				fprintf(stderr, "   ");
			}
		}
		fprintf(stderr, "\n");
	}
}

}<|endoftext|>