code:
#include "scriptmgr.h"
#include "gamemgr.h"
#include "gameobj.h"
#include <iostream>  // cout
#include <stdio.h>  // fopen, fclose
#include <string.h> // strcmp
#include <assert.h>
#include "../../../add_on/scriptstdstring/scriptstdstring.h"
#include "../../../add_on/scriptbuilder/scriptbuilder.h"
#include "../../../add_on/weakref/weakref.h"

using namespace std;

CScriptMgr::CScriptMgr()
{
	engine           = 0;
	hasCompileErrors = false;
}

CScriptMgr::~CScriptMgr()
{
	for( unsigned int n = 0; n < controllers.size(); n++ )
		delete controllers[n];

	for( unsigned int n = 0; n < contexts.size(); n++ )
		contexts[n]->Release();

	if( engine )
		engine->ShutDownAndRelease();
}

int CScriptMgr::Init()
{
	int r;

	engine = asCreateScriptEngine();

	// Set the message callback to print the human readable messages that the engine gives in case of errors
	r = engine->SetMessageCallback(asMETHOD(CScriptMgr, MessageCallback), this, asCALL_THISCALL); assert( r >= 0 );

	// Register the string type
	RegisterStdString(engine);

	// Register the generic handle type, called 'ref' in the script
	RegisterScriptHandle(engine);

	// Register the weak ref template type
	RegisterScriptWeakRef(engine);

	// Register the game object. The scripts cannot create these directly, so there is no factory function.
	r = engine->RegisterObjectType("CGameObj", 0, asOBJ_REF); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("CGameObj", asBEHAVE_ADDREF, "void f()", asMETHOD(CGameObj, AddRef), asCALL_THISCALL); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("CGameObj", asBEHAVE_RELEASE, "void f()", asMETHOD(CGameObj, Release), asCALL_THISCALL); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("CGameObj", asBEHAVE_GET_WEAKREF_FLAG, "int &f()", asMETHOD(CGameObj, GetWeakRefFlag), asCALL_THISCALL); assert( r >= 0 );

	// The object's position is read-only to the script. The position is updated with the Move method
	r = engine->RegisterObjectMethod("CGameObj", "int get_x() const property", asMETHOD(CGameObj, GetX), asCALL_THISCALL); assert( r >= 0 );
	r = engine->RegisterObjectMethod("CGameObj", "int get_y() const property", asMETHOD(CGameObj, GetY), asCALL_THISCALL); assert( r >= 0 );
	r = engine->RegisterObjectMethod("CGameObj", "bool Move(int dx, int dy)", asMETHOD(CGameObj, Move), asCALL_THISCALL); assert( r >= 0 );

	// The script can kill the owning object
	r = engine->RegisterObjectMethod("CGameObj", "void Kill()", asMETHOD(CGameObj, Kill), asCALL_THISCALL); assert( r >= 0 );

	// The script can send a message to the other object through this method
	// Observe the autohandle @+ to tell AngelScript to automatically release the handle after the call
	// The generic handle type is used to allow the script to pass any object to
	// the other script without the application having to know anything about it
	r = engine->RegisterObjectMethod("CGameObj", "void Send(ref msg, const CGameObj @+ to)", asMETHOD(CGameObj, Send), asCALL_THISCALL); assert( r >= 0 );

	// The game engine will determine the class that represents the controller
	// by checking if the class implements the IController interface. No methods
	// are registered for this interface, as the script shouldn't be required to
	// implement the methods. This will allow the game engine to avoid calling
	// methods that doesn't do anything, thus improving performance.
	r = engine->RegisterInterface("IController"); assert( r >= 0 );

	// Register the game manager as a singleton. The script will access it through the global property
	r = engine->RegisterObjectType("CGameMgr", 0, asOBJ_REF | asOBJ_NOHANDLE); assert( r >= 0 );

	// Register the game manager's methods
	r = engine->RegisterGlobalProperty("CGameMgr game", gameMgr); assert( r >= 0 );

	// The script can determine what the user wants to do through the actionStates
	r = engine->RegisterObjectMethod("CGameMgr", "bool get_actionState(int idx) property", asMETHOD(CGameMgr, GetActionState), asCALL_THISCALL); assert( r >= 0 );

	// The script can call this method to end the game
	r = engine->RegisterObjectMethod("CGameMgr", "void EndGame(bool win)", asMETHOD(CGameMgr, EndGame), asCALL_THISCALL); assert( r >= 0 );

	// Register a method that will allow the script to find an object by its name.
	// This returns the object as const handle, as the script should only be
	// allow to directly modify its owner object.
	// Observe the @+ that tells AngelScript to automatically increase the refcount
	r = engine->RegisterObjectMethod("CGameMgr", "const CGameObj @+ FindObjByName(const string &in name)", asMETHOD(CGameMgr, FindGameObjByName), asCALL_THISCALL); assert( r >= 0 );

	return 0;
}

void CScriptMgr::MessageCallback(const asSMessageInfo &msg)
{
	const char *type = "ERR ";
	if( msg.type == asMSGTYPE_WARNING )
		type = "WARN";
	else if( msg.type == asMSGTYPE_INFORMATION )
		type = "INFO";

	cout << msg.section << " (" << msg.row << ", " << msg.col << ") : " << type << " : " << msg.message << endl;

	if( msg.type == asMSGTYPE_ERROR )
		hasCompileErrors = true;
}

CScriptMgr::SController *CScriptMgr::GetControllerScript(const string &script)
{
	int r;

	// Find the cached controller
	for( unsigned int n = 0; n < controllers.size(); n++ )
	{
		if( controllers[n]->module == script )
			return controllers[n];
	}

	// No controller, check if the script has already been loaded
	asIScriptModule *mod = engine->GetModule(script.c_str(), asGM_ONLY_IF_EXISTS);
	if( mod )
	{
		// We've already attempted loading the script before, but there is no controller
		return 0;
	}

	// Compile the script into the module
	CScriptBuilder builder;
	r = builder.StartNewModule(engine, script.c_str());
	if( r < 0 )
		return 0;

	// If the script file doesn't exist, then there is no script controller for this type
	FILE *f;
	if( (f = fopen((script + ".as").c_str(), "r")) == 0 )
		return 0;
	fclose(f);

	// Let the builder load the script, and do the necessary pre-processing (include files, etc)
	r = builder.AddSectionFromFile((script + ".as").c_str());
	if( r < 0 )
		return 0;

	r = builder.BuildModule();
	if( r < 0 )
		return 0;

	// Cache the functions and methods that will be used
	SController *ctrl = new SController;
	controllers.push_back(ctrl);
	ctrl->module = script;

	// Find the class that implements the IController interface
	mod = engine->GetModule(script.c_str(), asGM_ONLY_IF_EXISTS);
	asITypeInfo *type = 0;
	int tc = mod->GetObjectTypeCount();
	for( int n = 0; n < tc; n++ )
	{
		bool found = false;
		type = mod->GetObjectTypeByIndex(n);
		int ic = type->GetInterfaceCount();
		for( int i = 0; i < ic; i++ )
		{
			if( strcmp(type->GetInterface(i)->GetName(), "IController") == 0 )
			{
				found = true;
				break;
			}
		}

		if( found == true )
		{
			ctrl->type = type;
			break;
		}
	}

	if( ctrl->type == 0 )
	{
		cout << "Couldn't find the controller class for the type '" << script << "'" << endl;
		controllers.pop_back();
		delete ctrl;
		return 0;
	}

	// Find the factory function
	// The game engine will pass in the owning CGameObj to the controller for storage
	string s = string(type->GetName()) + "@ " + string(type->GetName()) + "(CGameObj @)";
	ctrl->factoryFunc = type->GetFactoryByDecl(s.c_str());
	if( ctrl->factoryFunc == 0 )
	{
		cout << "Couldn't find the appropriate factory for the type '" << script << "'" << endl;
		controllers.pop_back();
		delete ctrl;
		return 0;
	}

	// Find the optional event handlers
	ctrl->onThinkMethod     = type->GetMethodByDecl("void OnThink()");
	ctrl->onMessageMethod   = type->GetMethodByDecl("void OnMessage(ref @msg, const CGameObj @sender)");

	// Add the cache as user data to the type for quick access
	type->SetUserData(ctrl);

	return ctrl;
}

asIScriptObject *CScriptMgr::CreateController(const string &script, CGameObj *gameObj)
{
	int r;
	asIScriptObject *obj = 0;

	SController *ctrl = GetControllerScript(script);
	if( ctrl == 0 ) return 0;

	// Create the object using the factory function
	asIScriptContext *ctx = PrepareContextFromPool(ctrl->factoryFunc);

	// Pass the object pointer to the script function. With this call the
	// context will automatically increase the reference count for the object.
	ctx->SetArgObject(0, gameObj);

	// Make the call and take care of any errors that may happen
	r = ExecuteCall(ctx);
	if( r == asEXECUTION_FINISHED )
	{
		// Get the newly created object
		obj = *((asIScriptObject**)ctx->GetAddressOfReturnValue());

		// Since a reference will be kept to this object
		// it is necessary to increase the ref count
		obj->AddRef();
	}

	// Return the context to the pool so it can be reused
	ReturnContextToPool(ctx);

	return obj;
}

void CScriptMgr::CallOnThink(asIScriptObject *object)
{
	// Find the cached onThink method id
	SController *ctrl = reinterpret_cast<SController*>(object->GetObjectType()->GetUserData());

	// Call the method using the shared context
	if( ctrl->onThinkMethod != 0 )
	{
		asIScriptContext *ctx = PrepareContextFromPool(ctrl->onThinkMethod);
		ctx->SetObject(object);
		ExecuteCall(ctx);
		ReturnContextToPool(ctx);
	}
}

void CScriptMgr::CallOnMessage(asIScriptObject *object, CScriptHandle &msg, CGameObj *caller)
{
	// Find the cached onMessage method id
	SController *ctrl = reinterpret_cast<SController*>(object->GetObjectType()->GetUserData());

	// Call the method using the shared context
	if( ctrl->onMessageMethod != 0 )
	{
		asIScriptContext *ctx = PrepareContextFromPool(ctrl->onMessageMethod);
		ctx->SetObject(object);
		ctx->SetArgObject(0, &msg);
		ctx->SetArgObject(1, caller);
		ExecuteCall(ctx);
		ReturnContextToPool(ctx);
	}
}

int CScriptMgr::ExecuteCall(asIScriptContext *ctx)
{
	int r = ctx->Execute();
	if( r != asEXECUTION_FINISHED )
	{
		if( r == asEXECUTION_EXCEPTION )
		{
			cout << "Exception: " << ctx->GetExceptionString() << endl;
			cout << "Function: " << ctx->GetExceptionFunction()->GetDeclaration() << endl;
			cout << "Line: " << ctx->GetExceptionLineNumber() << endl;

			// It is possible to print more information about the location of the
			// exception, for example the call stack, values of variables, etc if
			// that is of interest.
		}
	}

	return r;
}

asIScriptContext *CScriptMgr::PrepareContextFromPool(asIScriptFunction *func)
{
	asIScriptContext *ctx = 0;
	if( contexts.size() )
	{
		ctx = *contexts.rbegin();
		contexts.pop_back();
	}
	else
		ctx = engine->CreateContext();

	int r = ctx->Prepare(func); assert( r >= 0 );

	return ctx;
}

void CScriptMgr::ReturnContextToPool(asIScriptContext *ctx)
{
	contexts.push_back(ctx);

	// Unprepare the context to free any objects that might be held
	// as we don't know when the context will be used again.
	ctx->Unprepare();
}


code:
#ifndef SCRIPTMGR_H
#define SCRIPTMGR_H

#include <string>
#include <vector>
#include <angelscript.h>
#include "../../../add_on/scripthandle/scripthandle.h"

class CGameObj;

class CScriptMgr
{
public:
	CScriptMgr();
	~CScriptMgr();

	int Init();

	asIScriptObject *CreateController(const std::string &type, CGameObj *obj);
	void CallOnThink(asIScriptObject *object);
	void CallOnMessage(asIScriptObject *object, CScriptHandle &msg, CGameObj *caller);

	bool hasCompileErrors;

protected:
	void MessageCallback(const asSMessageInfo &msg);
	asIScriptContext *PrepareContextFromPool(asIScriptFunction *func);
	void ReturnContextToPool(asIScriptContext *ctx);
	int ExecuteCall(asIScriptContext *ctx);

	struct SController
	{
		SController() : type(0), factoryFunc(0), onThinkMethod(0), onMessageMethod(0) {}
		std::string        module;
		asITypeInfo       *type;
		asIScriptFunction *factoryFunc;
		asIScriptFunction *onThinkMethod;
		asIScriptFunction *onMessageMethod;
	};

	SController *GetControllerScript(const std::string &type);

	asIScriptEngine  *engine;

	// Our pool of script contexts. This is used to avoid allocating
	// the context objects all the time. The context objects are quite
	// heavy weight and should be shared between function calls.
	std::vector<asIScriptContext *> contexts;

	// This is the cache of function ids etc that we use to avoid having
	// to search for the function ids everytime we need to call a function.
	// The search is quite time consuming and should only be done once.
	std::vector<SController *> controllers;
};

extern CScriptMgr *scriptMgr;

#endif

repo_name: Antidote/openrpgeditor

license: mit


code:
# Tutoral GCC Makefile

CXX = g++
CXXFLAGS = -ggdb -I../../../../angelscript/include
SRCDIR = ../../source
OBJDIR = obj

SRCNAMES =   main.cpp

OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.o))) obj/scriptstdstring.o obj/scriptbuilder.o
BIN = ../../bin/include
DELETER = rm -f

all: $(BIN)

$(BIN): $(OBJ)
	$(CXX) -o $(BIN) $(OBJ) -static -langelscript -dynamic -L ../../../../angelscript/lib -lpthread
	@echo -------------------------------------------------------------------
	@echo Done.

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
	$(CXX) $(CXXFLAGS) -o $@ -c $<

obj/scriptstdstring.o: ../../../../add_on/scriptstdstring/scriptstdstring.cpp
	$(CXX) $(CXXFLAGS) -o $@ -c $<

obj/scriptbuilder.o: ../../../../add_on/scriptbuilder/scriptbuilder.cpp
	$(CXX) $(CXXFLAGS) -o $@ -c $<

clean:
	$(DELETER) $(OBJ) $(BIN)

.PHONY: all clean


code:
# Microsoft Developer Studio Project File - Name="msvc6" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=msvc6 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "msvc6.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "msvc6.mak" CFG="msvc6 - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "msvc6 - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "msvc6 - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe

!IF  "$(CFG)" == "msvc6 - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../../angelscript/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 ../../../../angelscript/lib/angelscript.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/include.exe"

!ELSEIF  "$(CFG)" == "msvc6 - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../angelscript/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ../../../../angelscript/lib/angelscriptd.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/include.exe" /pdbtype:sept

!ENDIF

# Begin Target

# Name "msvc6 - Win32 Release"
# Name "msvc6 - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=..\..\source\main.cpp
# End Source File
# Begin Source File

SOURCE=..\..\..\..\add_on\scriptbuilder\scriptbuilder.cpp
# End Source File
# Begin Source File

SOURCE=..\..\..\..\add_on\scriptstdstring\scriptstdstring.cpp
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File

SOURCE=..\..\..\..\angelscript\include\angelscript.h
# End Source File
# Begin Source File

SOURCE=..\..\..\..\add_on\scriptbuilder\scriptbuilder.h
# End Source File
# Begin Source File

SOURCE=..\..\..\..\add_on\scriptstdstring\scriptstdstring.h
# End Source File
# End Group
# Begin Group "Resource Files"

# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project


code:
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="7.10"
	Name="msvc7"
	SccProjectName=""
	SccLocalPath="">
	<Platforms>
		<Platform
			Name="Win32"/>
	</Platforms>
	<Configurations>
		<Configuration
			Name="Release|Win32"
			OutputDirectory=".\Release"
			IntermediateDirectory=".\Release"
			ConfigurationType="1"
			UseOfMFC="0"
			ATLMinimizesCRunTimeLibraryUsage="FALSE"
			CharacterSet="2">
			<Tool
				Name="VCCLCompilerTool"
				Optimization="2"
				InlineFunctionExpansion="1"
				AdditionalIncludeDirectories="../../../../angelscript/include"
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
				StringPooling="TRUE"
				RuntimeLibrary="2"
				EnableFunctionLevelLinking="TRUE"
				UsePrecompiledHeader="2"
				PrecompiledHeaderFile=".\Release/msvc6.pch"
				AssemblerListingLocation=".\Release/"
				ObjectFile=".\Release/"
				ProgramDataBaseFileName=".\Release/"
				WarningLevel="3"
				SuppressStartupBanner="TRUE"
				CompileAs="0"/>
			<Tool
				Name="VCCustomBuildTool"/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscript.lib winmm.lib odbc32.lib odbccp32.lib"
				OutputFile="../../bin/include.exe"
				LinkIncremental="1"
				SuppressStartupBanner="TRUE"
				ProgramDatabaseFile=".\Release/include.pdb"
				SubSystem="1"
				TargetMachine="1"/>
			<Tool
				Name="VCMIDLTool"
				TypeLibraryName=".\Release/msvc6.tlb"
				HeaderFileName=""/>
			<Tool
				Name="VCPostBuildEventTool"/>
			<Tool
				Name="VCPreBuildEventTool"/>
			<Tool
				Name="VCPreLinkEventTool"/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG"
				Culture="1033"/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"/>
			<Tool
				Name="VCXMLDataGeneratorTool"/>
			<Tool
				Name="VCWebDeploymentTool"/>
			<Tool
				Name="VCManagedWrapperGeneratorTool"/>
			<Tool
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
		</Configuration>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory=".\Debug"
			IntermediateDirectory=".\Debug"
			ConfigurationType="1"
			UseOfMFC="0"
			ATLMinimizesCRunTimeLibraryUsage="FALSE"
			CharacterSet="2">
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				AdditionalIncludeDirectories="../../../../angelscript/include"
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
				BasicRuntimeChecks="3"
				RuntimeLibrary="3"
				UsePrecompiledHeader="2"
				PrecompiledHeaderFile=".\Debug/msvc6.pch"
				AssemblerListingLocation=".\Debug/"
				ObjectFile=".\Debug/"
				ProgramDataBaseFileName=".\Debug/"
				WarningLevel="3"
				SuppressStartupBanner="TRUE"
				DebugInformationFormat="4"
				CompileAs="0"/>
			<Tool
				Name="VCCustomBuildTool"/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscriptd.lib winmm.lib odbc32.lib odbccp32.lib"
				OutputFile="../../bin/include.exe"
				LinkIncremental="1"
				SuppressStartupBanner="TRUE"
				GenerateDebugInformation="TRUE"
				ProgramDatabaseFile=".\Debug/include.pdb"
				SubSystem="1"
				TargetMachine="1"/>
			<Tool
				Name="VCMIDLTool"
				TypeLibraryName=".\Debug/msvc6.tlb"
				HeaderFileName=""/>
			<Tool
				Name="VCPostBuildEventTool"/>
			<Tool
				Name="VCPreBuildEventTool"/>
			<Tool
				Name="VCPreLinkEventTool"/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG"
				Culture="1033"/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"/>
			<Tool
				Name="VCXMLDataGeneratorTool"/>
			<Tool
				Name="VCWebDeploymentTool"/>
			<Tool
				Name="VCManagedWrapperGeneratorTool"/>
			<Tool
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
			<File
				RelativePath="..\..\source\main.cpp">
				<FileConfiguration
					Name="Release|Win32">
					<Tool
						Name="VCCLCompilerTool"
						Optimization="2"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32">
					<Tool
						Name="VCCLCompilerTool"
						Optimization="0"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
						BasicRuntimeChecks="3"/>
				</FileConfiguration>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptbuilder\scriptbuilder.cpp">
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.cpp">
				<FileConfiguration
					Name="Release|Win32">
					<Tool
						Name="VCCLCompilerTool"
						Optimization="2"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32">
					<Tool
						Name="VCCLCompilerTool"
						Optimization="0"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
						BasicRuntimeChecks="3"/>
				</FileConfiguration>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl">
			<File
				RelativePath="..\..\..\..\angelscript\include\angelscript.h">
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptbuilder\scriptbuilder.h">
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.h">
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>


code:
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="9,00"
	Name="msvc9"
	ProjectGUID="{DBC00E73-0B55-42C6-B9F0-750083588841}"
	TargetFrameworkVersion="131072"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Release|Win32"
			OutputDirectory=".\Release"
			IntermediateDirectory=".\Release"
			ConfigurationType="1"
			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
			UseOfMFC="0"
			ATLMinimizesCRunTimeLibraryUsage="false"
			CharacterSet="2"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TypeLibraryName=".\Release/msvc6.tlb"
				HeaderFileName=""
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="2"
				InlineFunctionExpansion="1"
				AdditionalIncludeDirectories="../../../../angelscript/include"
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
				StringPooling="true"
				RuntimeLibrary="0"
				EnableFunctionLevelLinking="true"
				UsePrecompiledHeader="0"
				PrecompiledHeaderFile=".\Release/msvc6.pch"
				AssemblerListingLocation=".\Release/"
				ObjectFile=".\Release/"
				ProgramDataBaseFileName=".\Release/"
				WarningLevel="3"
				SuppressStartupBanner="true"
				CompileAs="0"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG"
				Culture="1033"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscript.lib winmm.lib odbc32.lib odbccp32.lib"
				OutputFile="../../bin/include.exe"
				LinkIncremental="1"
				SuppressStartupBanner="true"
				ProgramDatabaseFile=".\Release/include.pdb"
				SubSystem="1"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory=".\Debug"
			IntermediateDirectory=".\Debug"
			ConfigurationType="1"
			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
			UseOfMFC="0"
			ATLMinimizesCRunTimeLibraryUsage="false"
			CharacterSet="2"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TypeLibraryName=".\Debug/msvc6.tlb"
				HeaderFileName=""
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				AdditionalIncludeDirectories="../../../../angelscript/include"
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
				BasicRuntimeChecks="3"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				PrecompiledHeaderFile=".\Debug/msvc6.pch"
				AssemblerListingLocation=".\Debug/"
				ObjectFile=".\Debug/"
				ProgramDataBaseFileName=".\Debug/"
				WarningLevel="3"
				SuppressStartupBanner="true"
				DebugInformationFormat="4"
				CompileAs="0"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG"
				Culture="1033"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscriptd.lib winmm.lib odbc32.lib odbccp32.lib"
				OutputFile="../../bin/include.exe"
				LinkIncremental="1"
				SuppressStartupBanner="true"
				GenerateDebugInformation="true"
				ProgramDatabaseFile=".\Debug/include.pdb"
				SubSystem="1"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
			>
			<File
				RelativePath="..\..\source\main.cpp"
				>
				<FileConfiguration
					Name="Release|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						Optimization="2"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						Optimization="0"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
						BasicRuntimeChecks="3"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptbuilder\scriptbuilder.cpp"
				>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.cpp"
				>
				<FileConfiguration
					Name="Release|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						Optimization="2"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						Optimization="0"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
						BasicRuntimeChecks="3"
					/>
				</FileConfiguration>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl"
			>
			<File
				RelativePath="..\..\..\..\angelscript\include\angelscript.h"
				>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptbuilder\scriptbuilder.h"
				>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.h"
				>
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
			>
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>


code:
TEMPLATE = app

SOURCES += ../../source/main.cpp

DESTDIR = ../../bin

INCLUDEPATH += ../../../../angelscript/include

LIBS += -L../../../../angelscript/lib -langelscript

win32: LIBS += -lwinmm

CONFIG -= debug debug_and_release release app_bundle qt dll

CONFIG += console thread release

DEFINES += _CRT_SECURE_NO_WARNINGS


code:
#ifdef _MSC_VER
#pragma warning(disable:4786) // disable warnings about truncated symbol names
#endif

#include <iostream>  // cout
#include <assert.h>  // assert()
#include <string.h>  // strstr()
#ifdef __linux__
	#include <sys/time.h>
	#include <stdio.h>
	#include <termios.h>
	#include <unistd.h>
#else
	#include <conio.h>   // kbhit(), getch()
	#include <windows.h> // timeGetTime()
#endif
#include <set>
#include <angelscript.h>

#include "../../../add_on/scriptstdstring/scriptstdstring.h"
#include "../../../add_on/scriptbuilder/scriptbuilder.h"

using namespace std;

#ifdef __linux__

#define UINT unsigned int
typedef unsigned int DWORD;

// Linux doesn't have timeGetTime(), this essentially does the same
// thing, except this is milliseconds since Epoch (Jan 1st 1970) instead
// of system start. It will work the same though...
DWORD timeGetTime()
{
	timeval time;
	gettimeofday(&time, NULL);
	return time.tv_sec*1000 + time.tv_usec/1000;
}

// Linux does have a getch() function in the curses library, but it doesn't
// work like it does on DOS. So this does the same thing, without the need
// of the curses library.
int getch()
{
	struct termios oldt, newt;
	int ch;

	tcgetattr(STDIN_FILENO, &oldt);
	newt = oldt;
	newt.c_lflag &= ~( ICANON | ECHO );
	tcsetattr( STDIN_FILENO, TCSANOW, &newt );

	ch = getchar();

	tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
	return ch;
}

#endif

// Function prototypes
int  RunApplication();
void ConfigureEngine(asIScriptEngine *engine);
int  CompileScript(asIScriptEngine *engine);
void PrintString(string &str);
void PrintString_Generic(asIScriptGeneric *gen);
void timeGetTime_Generic(asIScriptGeneric *gen);
void LineCallback(asIScriptContext *ctx, DWORD *timeOut);

int main(int argc, char **argv)
{
	RunApplication();

	// Wait until the user presses a key
	cout << endl << "Press any key to quit." << endl;
	while(!getch());

	return 0;
}

void MessageCallback(const asSMessageInfo *msg, void *param)
{
	const char *type = "ERR ";
	if( msg->type == asMSGTYPE_WARNING )
		type = "WARN";
	else if( msg->type == asMSGTYPE_INFORMATION )
		type = "INFO";

	printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}

int RunApplication()
{
	int r;

	// Create the script engine
	asIScriptEngine *engine = asCreateScriptEngine();
	if( engine == 0 )
	{
		cout << "Failed to create script engine." << endl;
		return -1;
	}

	// The script compiler will write any compiler messages to the callback.
	engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);

	// Configure the script engine with all the functions,
	// and variables that the script should be able to use.
	ConfigureEngine(engine);

	// Compile the script code
	r = CompileScript(engine);
	if( r < 0 )
	{
		engine->Release();
		return -1;
	}

	// Create a context that will execute the script.
	asIScriptContext *ctx = engine->CreateContext();
	if( ctx == 0 )
	{
		cout << "Failed to create the context." << endl;
		engine->Release();
		return -1;
	}

	// We don't want to allow the script to hang the application, e.g. with an
	// infinite loop, so we'll use the line callback function to set a timeout
	// that will abort the script after a certain time. Before executing the
	// script the timeOut variable will be set to the time when the script must
	// stop executing.
	DWORD timeOut;
	r = ctx->SetLineCallback(asFUNCTION(LineCallback), &timeOut, asCALL_CDECL);
	if( r < 0 )
	{
		cout << "Failed to set the line callback function." << endl;
		ctx->Release();
		engine->Release();
		return -1;
	}

	// Find the function for the function we want to execute.
	asIScriptFunction *func = engine->GetModule(0)->GetFunctionByDecl("void main()");
	if( func == 0 )
	{
		cout << "The function 'void main()' was not found." << endl;
		ctx->Release();
		engine->Release();
		return -1;
	}

	// Prepare the script context with the function we wish to execute. Prepare()
	// must be called on the context before each new script function that will be
	// executed. Note, that if you intend to execute the same function several
	// times, it might be a good idea to store the function returned by
	// GetFunctionByDecl(), so that this relatively slow call can be skipped.
	r = ctx->Prepare(func);
	if( r < 0 )
	{
		cout << "Failed to prepare the context." << endl;
		ctx->Release();
		engine->Release();
		return -1;
	}

	// Set the timeout before executing the function. Give the function 1 sec
	// to return before we'll abort it.
	timeOut = timeGetTime() + 1000;

	// Execute the function
	cout << "Executing the script." << endl;
	cout << "---" << endl;
	r = ctx->Execute();
	cout << "---" << endl;
	if( r != asEXECUTION_FINISHED )
	{
		// The execution didn't finish as we had planned. Determine why.
		if( r == asEXECUTION_ABORTED )
			cout << "The script was aborted before it could finish. Probably it timed out." << endl;
		else if( r == asEXECUTION_EXCEPTION )
		{
			cout << "The script ended with an exception." << endl;

			// Write some information about the script exception
			asIScriptFunction *func = ctx->GetExceptionFunction();
			cout << "func: " << func->GetDeclaration() << endl;
			cout << "modl: " << func->GetModuleName() << endl;
			cout << "sect: " << func->GetScriptSectionName() << endl;
			cout << "line: " << ctx->GetExceptionLineNumber() << endl;
			cout << "desc: " << ctx->GetExceptionString() << endl;
		}
		else
			cout << "The script ended for some unforeseen reason (" << r << ")." << endl;
	}
	else
	{
		cout << "The script finished successfully." << endl;
	}

	// We must release the contexts when no longer using them
	ctx->Release();

	// Shut down the engine
	engine->ShutDownAndRelease();

	return 0;
}

void ConfigureEngine(asIScriptEngine *engine)
{
	int r;

	// Register the script string type
	// Look at the implementation for this function for more information
	// on how to register a custom string type, and other object types.
	RegisterStdString(engine);

	if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		// Register the functions that the scripts will be allowed to use.
		// Note how the return code is validated with an assert(). This helps
		// us discover where a problem occurs, and doesn't pollute the code
		// with a lot of if's. If an error occurs in release mode it will
		// be caught when a script is being built, so it is not necessary
		// to do the verification here as well.
		r = engine->RegisterGlobalFunction("void print(string &in)", asFUNCTION(PrintString), asCALL_CDECL); assert( r >= 0 );
	}
	else
	{
		// Notice how the registration is almost identical to the above.
		r = engine->RegisterGlobalFunction("void print(string &in)", asFUNCTION(PrintString_Generic), asCALL_GENERIC); assert( r >= 0 );
	}

	// It is possible to register the functions, properties, and types in
	// configuration groups as well. When compiling the scripts it then
	// be defined which configuration groups should be available for that
	// script. If necessary a configuration group can also be removed from
	// the engine, so that the engine configuration could be changed
	// without having to recompile all the scripts.
}

int CompileScript(asIScriptEngine *engine)
{
	int r;

	// The builder is a helper class that will load the script file,
	// search for #include directives, and load any included files as
	// well.
	CScriptBuilder builder;

	// Build the script. If there are any compiler messages they will
	// be written to the message stream that we set right after creating the
	// script engine. If there are no errors, and no warnings, nothing will
	// be written to the stream.
	r = builder.StartNewModule(engine, 0);
	if( r < 0 )
	{
		cout << "Failed to start new module" << endl;
		return r;
	}
	r = builder.AddSectionFromFile("script.as");
	if( r < 0 )
	{
		cout << "Failed to add script file" << endl;
		return r;
	}
	r = builder.BuildModule();
	if( r < 0 )
	{
		cout << "Failed to build the module" << endl;
		return r;
	}

	// The engine doesn't keep a copy of the script sections after Build() has
	// returned. So if the script needs to be recompiled, then all the script
	// sections must be added again.

	// If we want to have several scripts executing at different times but
	// that have no direct relation with each other, then we can compile them
	// into separate script modules. Each module use their own namespace and
	// scope, so function names, and global variables will not conflict with
	// each other.

	return 0;
}

void LineCallback(asIScriptContext *ctx, DWORD *timeOut)
{
	// If the time out is reached we abort the script
	if( *timeOut < timeGetTime() )
		ctx->Abort();

	// It would also be possible to only suspend the script,
	// instead of aborting it. That would allow the application
	// to resume the execution where it left of at a later
	// time, by simply calling Execute() again.
}

// Function implementation with native calling convention
void PrintString(string &str)
{
	cout << str;
}

// Function implementation with generic script interface
void PrintString_Generic(asIScriptGeneric *gen)
{
	string *str = (string*)gen->GetArgAddress(0);
	cout << *str;
}


code:
# Tutoral GCC Makefile

CXX = g++
CXXFLAGS = -ggdb -I../../../../angelscript/include
SRCDIR = ../../source
OBJDIR = obj

SRCNAMES = \
  main.cpp

OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.o))) obj/scriptstdstring.o
BIN = ../../bin/tutorial
DELETER = rm -f

all: $(BIN)

$(BIN): $(OBJ)
	$(CXX) -o $(BIN) $(OBJ) -static -langelscript -dynamic -L ../../../../angelscript/lib -lpthread
	@echo -------------------------------------------------------------------
	@echo Done.

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
	$(CXX) $(CXXFLAGS) -o $@ -c $<

obj/scriptstdstring.o: ../../../../add_on/scriptstdstring/scriptstdstring.cpp
	$(CXX) $(CXXFLAGS) -o $@ -c $<

clean:
	$(DELETER) $(OBJ) $(BIN)

.PHONY: all clean


code:
# Microsoft Developer Studio Project File - Name="msvc6" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=msvc6 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "msvc6.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "msvc6.mak" CFG="msvc6 - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "msvc6 - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "msvc6 - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe

!IF  "$(CFG)" == "msvc6 - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../../angelscript/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 ../../../../angelscript/lib/angelscript.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/tutorial.exe"

!ELSEIF  "$(CFG)" == "msvc6 - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../angelscript/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ../../../../angelscript/lib/angelscriptd.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/tutorial.exe" /pdbtype:sept

!ENDIF

# Begin Target

# Name "msvc6 - Win32 Release"
# Name "msvc6 - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=..\..\source\main.cpp
# End Source File
# Begin Source File

SOURCE=..\..\..\..\add_on\scriptstdstring\scriptstdstring.cpp
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File

SOURCE=..\..\..\..\angelscript\include\angelscript.h
# End Source File
# Begin Source File

SOURCE=..\..\..\..\add_on\scriptstdstring\scriptstdstring.h
# End Source File
# End Group
# Begin Group "Resource Files"

# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project


code:
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="7.10"
	Name="msvc7"
	SccProjectName=""
	SccLocalPath="">
	<Platforms>
		<Platform
			Name="Win32"/>
	</Platforms>
	<Configurations>
		<Configuration
			Name="Release|Win32"
			OutputDirectory=".\Release"
			IntermediateDirectory=".\Release"
			ConfigurationType="1"
			UseOfMFC="0"
			ATLMinimizesCRunTimeLibraryUsage="FALSE"
			CharacterSet="2">
			<Tool
				Name="VCCLCompilerTool"
				Optimization="2"
				InlineFunctionExpansion="1"
				AdditionalIncludeDirectories="../../../../angelscript/include"
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
				StringPooling="TRUE"
				RuntimeLibrary="2"
				EnableFunctionLevelLinking="TRUE"
				UsePrecompiledHeader="2"
				PrecompiledHeaderFile=".\Release/msvc6.pch"
				AssemblerListingLocation=".\Release/"
				ObjectFile=".\Release/"
				ProgramDataBaseFileName=".\Release/"
				WarningLevel="3"
				SuppressStartupBanner="TRUE"
				CompileAs="0"/>
			<Tool
				Name="VCCustomBuildTool"/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscript.lib winmm.lib odbc32.lib odbccp32.lib"
				OutputFile="../../bin/tutorial.exe"
				LinkIncremental="1"
				SuppressStartupBanner="TRUE"
				ProgramDatabaseFile=".\Release/tutorial.pdb"
				SubSystem="1"
				TargetMachine="1"/>
			<Tool
				Name="VCMIDLTool"
				TypeLibraryName=".\Release/msvc6.tlb"
				HeaderFileName=""/>
			<Tool
				Name="VCPostBuildEventTool"/>
			<Tool
				Name="VCPreBuildEventTool"/>
			<Tool
				Name="VCPreLinkEventTool"/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG"
				Culture="1033"/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"/>
			<Tool
				Name="VCXMLDataGeneratorTool"/>
			<Tool
				Name="VCWebDeploymentTool"/>
			<Tool
				Name="VCManagedWrapperGeneratorTool"/>
			<Tool
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
		</Configuration>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory=".\Debug"
			IntermediateDirectory=".\Debug"
			ConfigurationType="1"
			UseOfMFC="0"
			ATLMinimizesCRunTimeLibraryUsage="FALSE"
			CharacterSet="2">
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				AdditionalIncludeDirectories="../../../../angelscript/include"
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
				BasicRuntimeChecks="3"
				RuntimeLibrary="3"
				UsePrecompiledHeader="2"
				PrecompiledHeaderFile=".\Debug/msvc6.pch"
				AssemblerListingLocation=".\Debug/"
				ObjectFile=".\Debug/"
				ProgramDataBaseFileName=".\Debug/"
				WarningLevel="3"
				SuppressStartupBanner="TRUE"
				DebugInformationFormat="4"
				CompileAs="0"/>
			<Tool
				Name="VCCustomBuildTool"/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscriptd.lib winmm.lib odbc32.lib odbccp32.lib"
				OutputFile="../../bin/tutorial.exe"
				LinkIncremental="1"
				SuppressStartupBanner="TRUE"
				GenerateDebugInformation="TRUE"
				ProgramDatabaseFile=".\Debug/tutorial.pdb"
				SubSystem="1"
				TargetMachine="1"/>
			<Tool
				Name="VCMIDLTool"
				TypeLibraryName=".\Debug/msvc6.tlb"
				HeaderFileName=""/>
			<Tool
				Name="VCPostBuildEventTool"/>
			<Tool
				Name="VCPreBuildEventTool"/>
			<Tool
				Name="VCPreLinkEventTool"/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG"
				Culture="1033"/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"/>
			<Tool
				Name="VCXMLDataGeneratorTool"/>
			<Tool
				Name="VCWebDeploymentTool"/>
			<Tool
				Name="VCManagedWrapperGeneratorTool"/>
			<Tool
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
			<File
				RelativePath="..\..\source\main.cpp">
				<FileConfiguration
					Name="Release|Win32">
					<Tool
						Name="VCCLCompilerTool"
						Optimization="2"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32">
					<Tool
						Name="VCCLCompilerTool"
						Optimization="0"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
						BasicRuntimeChecks="3"/>
				</FileConfiguration>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.cpp">
				<FileConfiguration
					Name="Release|Win32">
					<Tool
						Name="VCCLCompilerTool"
						Optimization="2"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32">
					<Tool
						Name="VCCLCompilerTool"
						Optimization="0"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
						BasicRuntimeChecks="3"/>
				</FileConfiguration>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl">
			<File
				RelativePath="..\..\..\..\angelscript\include\angelscript.h">
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.h">
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>


code:
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="8,00"
	Name="msvc8"
	ProjectGUID="{7EB00638-4ACA-4BEC-9A77-FAFFE8EC5E6F}"
	RootNamespace="msvc8"
	Keyword="Win32Proj"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="..\..\bin"
			IntermediateDirectory="$(ConfigurationName)"
			ConfigurationType="1"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				AdditionalIncludeDirectories="..\..\..\..\angelscript\include"
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
				MinimalRebuild="true"
				BasicRuntimeChecks="3"
				RuntimeLibrary="3"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				Detect64BitPortabilityProblems="true"
				DebugInformationFormat="4"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscriptd.lib winmm.lib"
				LinkIncremental="2"
				GenerateDebugInformation="true"
				SubSystem="1"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
			IntermediateDirectory="$(ConfigurationName)"
			ConfigurationType="1"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
				RuntimeLibrary="2"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				Detect64BitPortabilityProblems="true"
				DebugInformationFormat="3"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				SubSystem="1"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
			>
			<File
				RelativePath="..\..\source\main.cpp"
				>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.cpp"
				>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
			>
			<File
				RelativePath="..\..\..\..\angelscript\include\angelscript.h"
				>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.h"
				>
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
			>
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>


code:
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="9,00"
	Name="msvc7"
	ProjectGUID="{93FE3A09-8CFF-4C50-A9C1-AB86B01FDD57}"
	TargetFrameworkVersion="131072"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Release|Win32"
			OutputDirectory=".\Release"
			IntermediateDirectory=".\Release"
			ConfigurationType="1"
			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
			UseOfMFC="0"
			ATLMinimizesCRunTimeLibraryUsage="false"
			CharacterSet="2"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TypeLibraryName=".\Release/msvc6.tlb"
				HeaderFileName=""
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="2"
				InlineFunctionExpansion="1"
				AdditionalIncludeDirectories="../../../../angelscript/include"
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
				StringPooling="true"
				RuntimeLibrary="0"
				EnableFunctionLevelLinking="true"
				UsePrecompiledHeader="0"
				PrecompiledHeaderFile=".\Release/msvc6.pch"
				AssemblerListingLocation=".\Release/"
				ObjectFile=".\Release/"
				ProgramDataBaseFileName=".\Release/"
				WarningLevel="3"
				SuppressStartupBanner="true"
				CompileAs="0"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG"
				Culture="1033"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscript.lib winmm.lib odbc32.lib odbccp32.lib"
				OutputFile="../../bin/tutorial.exe"
				LinkIncremental="1"
				SuppressStartupBanner="true"
				ProgramDatabaseFile=".\Release/tutorial.pdb"
				SubSystem="1"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory=".\Debug"
			IntermediateDirectory=".\Debug"
			ConfigurationType="1"
			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
			UseOfMFC="0"
			ATLMinimizesCRunTimeLibraryUsage="false"
			CharacterSet="2"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TypeLibraryName=".\Debug/msvc6.tlb"
				HeaderFileName=""
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				AdditionalIncludeDirectories="../../../../angelscript/include"
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
				BasicRuntimeChecks="3"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				PrecompiledHeaderFile=".\Debug/msvc6.pch"
				AssemblerListingLocation=".\Debug/"
				ObjectFile=".\Debug/"
				ProgramDataBaseFileName=".\Debug/"
				WarningLevel="3"
				SuppressStartupBanner="true"
				DebugInformationFormat="4"
				CompileAs="0"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG"
				Culture="1033"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="../../../../angelscript/lib/angelscriptd.lib winmm.lib odbc32.lib odbccp32.lib"
				OutputFile="../../bin/tutorial.exe"
				LinkIncremental="1"
				SuppressStartupBanner="true"
				GenerateDebugInformation="true"
				ProgramDatabaseFile=".\Debug/tutorial.pdb"
				SubSystem="1"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
			>
			<File
				RelativePath="..\..\source\main.cpp"
				>
				<FileConfiguration
					Name="Release|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						Optimization="2"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						Optimization="0"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
						BasicRuntimeChecks="3"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.cpp"
				>
				<FileConfiguration
					Name="Release|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						Optimization="2"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						Optimization="0"
						AdditionalIncludeDirectories=""
						PreprocessorDefinitions=""
						BasicRuntimeChecks="3"
					/>
				</FileConfiguration>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl"
			>
			<File
				RelativePath="..\..\..\..\angelscript\include\angelscript.h"
				>
			</File>
			<File
				RelativePath="..\..\..\..\add_on\scriptstdstring\scriptstdstring.h"
				>
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
			>
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>


code:
#include <iostream>  // cout
#include <assert.h>  // assert()
#include <string.h>  // strstr()
#ifdef __linux__
	#include <sys/time.h>
	#include <stdio.h>
	#include <termios.h>
	#include <unistd.h>
#else
	#include <conio.h>   // kbhit(), getch()
	#include <windows.h> // timeGetTime()
#endif
#include <angelscript.h>
#include "../../../add_on/scriptstdstring/scriptstdstring.h"

using namespace std;

#ifdef __linux__

#define UINT unsigned int
typedef unsigned int DWORD;

// Linux doesn't have timeGetTime(), this essentially does the same
// thing, except this is milliseconds since Epoch (Jan 1st 1970) instead
// of system start. It will work the same though...
DWORD timeGetTime()
{
	timeval time;
	gettimeofday(&time, NULL);
	return time.tv_sec*1000 + time.tv_usec/1000;
}

// Linux does have a getch() function in the curses library, but it doesn't
// work like it does on DOS. So this does the same thing, with out the need
// of the curses library.
int getch()
{
	struct termios oldt, newt;
	int ch;

	tcgetattr(STDIN_FILENO, &oldt);
	newt = oldt;
	newt.c_lflag &= ~( ICANON | ECHO );
	tcsetattr( STDIN_FILENO, TCSANOW, &newt );

	ch = getchar();

	tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
	return ch;
}

#endif

// Function prototypes
int  RunApplication();
void ConfigureEngine(asIScriptEngine *engine);
int  CompileScript(asIScriptEngine *engine);
void PrintString(string &str);
void PrintString_Generic(asIScriptGeneric *gen);
void timeGetTime_Generic(asIScriptGeneric *gen);
void LineCallback(asIScriptContext *ctx, DWORD *timeOut);

int main(int argc, char **argv)
{
	RunApplication();

	// Wait until the user presses a key
	cout << endl << "Press any key to quit." << endl;
	while(!getch());

	return 0;
}

void MessageCallback(const asSMessageInfo *msg, void *param)
{
	const char *type = "ERR ";
	if( msg->type == asMSGTYPE_WARNING )
		type = "WARN";
	else if( msg->type == asMSGTYPE_INFORMATION )
		type = "INFO";

	printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}

int RunApplication()
{
	int r;

	// Create the script engine
	asIScriptEngine *engine = asCreateScriptEngine();
	if( engine == 0 )
	{
		cout << "Failed to create script engine." << endl;
		return -1;
	}

	// The script compiler will write any compiler messages to the callback.
	engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);

	// Configure the script engine with all the functions,
	// and variables that the script should be able to use.
	ConfigureEngine(engine);

	// Compile the script code
	r = CompileScript(engine);
	if( r < 0 )
	{
		engine->Release();
		return -1;
	}

	// Create a context that will execute the script.
	asIScriptContext *ctx = engine->CreateContext();
	if( ctx == 0 )
	{
		cout << "Failed to create the context." << endl;
		engine->Release();
		return -1;
	}

	// We don't want to allow the script to hang the application, e.g. with an
	// infinite loop, so we'll use the line callback function to set a timeout
	// that will abort the script after a certain time. Before executing the
	// script the timeOut variable will be set to the time when the script must
	// stop executing.
	DWORD timeOut;
	r = ctx->SetLineCallback(asFUNCTION(LineCallback), &timeOut, asCALL_CDECL);
	if( r < 0 )
	{
		cout << "Failed to set the line callback function." << endl;
		ctx->Release();
		engine->Release();
		return -1;
	}

	// Find the function for the function we want to execute.
	asIScriptFunction *func = engine->GetModule(0)->GetFunctionByDecl("float calc(float, float)");
	if( func == 0 )
	{
		cout << "The function 'float calc(float, float)' was not found." << endl;
		ctx->Release();
		engine->Release();
		return -1;
	}

	// Prepare the script context with the function we wish to execute. Prepare()
	// must be called on the context before each new script function that will be
	// executed. Note, that if you intend to execute the same function several
	// times, it might be a good idea to store the function returned by
	// GetFunctionByDecl(), so that this relatively slow call can be skipped.
	r = ctx->Prepare(func);
	if( r < 0 )
	{
		cout << "Failed to prepare the context." << endl;
		ctx->Release();
		engine->Release();
		return -1;
	}

	// Now we need to pass the parameters to the script function.
	ctx->SetArgFloat(0, 3.14159265359f);
	ctx->SetArgFloat(1, 2.71828182846f);

	// Set the timeout before executing the function. Give the function 1 sec
	// to return before we'll abort it.
	timeOut = timeGetTime() + 1000;

	// Execute the function
	cout << "Executing the script." << endl;
	cout << "---" << endl;
	r = ctx->Execute();
	cout << "---" << endl;
	if( r != asEXECUTION_FINISHED )
	{
		// The execution didn't finish as we had planned. Determine why.
		if( r == asEXECUTION_ABORTED )
			cout << "The script was aborted before it could finish. Probably it timed out." << endl;
		else if( r == asEXECUTION_EXCEPTION )
		{
			cout << "The script ended with an exception." << endl;

			// Write some information about the script exception
			asIScriptFunction *func = ctx->GetExceptionFunction();
			cout << "func: " << func->GetDeclaration() << endl;
			cout << "modl: " << func->GetModuleName() << endl;
			cout << "sect: " << func->GetScriptSectionName() << endl;
			cout << "line: " << ctx->GetExceptionLineNumber() << endl;
			cout << "desc: " << ctx->GetExceptionString() << endl;
		}
		else
			cout << "The script ended for some unforeseen reason (" << r << ")." << endl;
	}
	else
	{
		// Retrieve the return value from the context
		float returnValue = ctx->GetReturnFloat();
		cout << "The script function returned: " << returnValue << endl;
	}

	// We must release the contexts when no longer using them
	ctx->Release();

	// Shut down the engine
	engine->ShutDownAndRelease();

	return 0;
}

void ConfigureEngine(asIScriptEngine *engine)
{
	int r;

	// Register the script string type
	// Look at the implementation for this function for more information
	// on how to register a custom string type, and other object types.
	RegisterStdString(engine);

	if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		// Register the functions that the scripts will be allowed to use.
		// Note how the return code is validated with an assert(). This helps
		// us discover where a problem occurs, and doesn't pollute the code
		// with a lot of if's. If an error occurs in release mode it will
		// be caught when a script is being built, so it is not necessary
		// to do the verification here as well.
		r = engine->RegisterGlobalFunction("void Print(string &in)", asFUNCTION(PrintString), asCALL_CDECL); assert( r >= 0 );
		r = engine->RegisterGlobalFunction("uint GetSystemTime()", asFUNCTION(timeGetTime), asCALL_STDCALL); assert( r >= 0 );
	}
	else
	{
		// Notice how the registration is almost identical to the above.
		r = engine->RegisterGlobalFunction("void Print(string &in)", asFUNCTION(PrintString_Generic), asCALL_GENERIC); assert( r >= 0 );
		r = engine->RegisterGlobalFunction("uint GetSystemTime()", asFUNCTION(timeGetTime_Generic), asCALL_GENERIC); assert( r >= 0 );
	}

	// It is possible to register the functions, properties, and types in
	// configuration groups as well. When compiling the scripts it then
	// be defined which configuration groups should be available for that
	// script. If necessary a configuration group can also be removed from
	// the engine, so that the engine configuration could be changed
	// without having to recompile all the scripts.
}

int CompileScript(asIScriptEngine *engine)
{
	int r;

	// We will load the script from a file on the disk.
	FILE *f = fopen("script.as", "rb");
	if( f == 0 )
	{
		cout << "Failed to open the script file 'script.as'." << endl;
		return -1;
	}

	// Determine the size of the file
	fseek(f, 0, SEEK_END);
	int len = ftell(f);
	fseek(f, 0, SEEK_SET);

	// On Win32 it is possible to do the following instead
	// int len = _filelength(_fileno(f));

	// Read the entire file
	string script;
	script.resize(len);
	size_t c = fread(&script[0], len, 1, f);
	fclose(f);

	if( c == 0 )
	{
		cout << "Failed to load script file." << endl;
		return -1;
	}

	// Add the script sections that will be compiled into executable code.
	// If we want to combine more than one file into the same script, then
	// we can call AddScriptSection() several times for the same module and
	// the script engine will treat them all as if they were one. The script
	// section name, will allow us to localize any errors in the script code.
	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	r = mod->AddScriptSection("script", &script[0], len);
	if( r < 0 )
	{
		cout << "AddScriptSection() failed" << endl;
		return -1;
	}

	// Compile the script. If there are any compiler messages they will
	// be written to the message stream that we set right after creating the
	// script engine. If there are no errors, and no warnings, nothing will
	// be written to the stream.
	r = mod->Build();
	if( r < 0 )
	{
		cout << "Build() failed" << endl;
		return -1;
	}

	// The engine doesn't keep a copy of the script sections after Build() has
	// returned. So if the script needs to be recompiled, then all the script
	// sections must be added again.

	// If we want to have several scripts executing at different times but
	// that have no direct relation with each other, then we can compile them
	// into separate script modules. Each module use their own namespace and
	// scope, so function names, and global variables will not conflict with
	// each other.

	return 0;
}

void LineCallback(asIScriptContext *ctx, DWORD *timeOut)
{
	// If the time out is reached we abort the script
	if( *timeOut < timeGetTime() )
		ctx->Abort();

	// It would also be possible to only suspend the script,
	// instead of aborting it. That would allow the application
	// to resume the execution where it left of at a later
	// time, by simply calling Execute() again.
}

// Function implementation with native calling convention
void PrintString(string &str)
{
	cout << str;
}

// Function implementation with generic script interface
void PrintString_Generic(asIScriptGeneric *gen)
{
	string *str = (string*)gen->GetArgAddress(0);
	cout << *str;
}

// Function wrapper is needed when native calling conventions are not supported
void timeGetTime_Generic(asIScriptGeneric *gen)
{
	gen->SetReturnDWord(timeGetTime());
}


code:
add_library(angelscript_addons STATIC
        ../angelscript/add_on/contextmgr/contextmgr.h
        ../angelscript/add_on/contextmgr/contextmgr.cpp
        ../angelscript/add_on/datetime/datetime.h
        ../angelscript/add_on/datetime/datetime.cpp
        ../angelscript/add_on/debugger/debugger.h
        ../angelscript/add_on/debugger/debugger.cpp
        ../angelscript/add_on/scriptany/scriptany.h
        ../angelscript/add_on/scriptany/scriptany.cpp
        ../angelscript/add_on/scriptarray/scriptarray.h
        ../angelscript/add_on/scriptarray/scriptarray.cpp
        ../angelscript/add_on/scriptbuilder/scriptbuilder.cpp
        ../angelscript/add_on/scriptbuilder/scriptbuilder.h
        ../angelscript/add_on/scriptdictionary/scriptdictionary.cpp
        ../angelscript/add_on/scriptdictionary/scriptdictionary.h
        ../angelscript/add_on/scriptfile/scriptfile.cpp
        ../angelscript/add_on/scriptfile/scriptfile.h
        ../angelscript/add_on/scriptgrid/scriptgrid.cpp
        ../angelscript/add_on/scriptgrid/scriptgrid.h
        ../angelscript/add_on/scripthandle/scripthandle.cpp
        ../angelscript/add_on/scripthandle/scripthandle.h
        ../angelscript/add_on/scriptmath/scriptmath.h
        ../angelscript/add_on/scriptmath/scriptmath.cpp
        ../angelscript/add_on/scriptmath/scriptmathcomplex.h
        ../angelscript/add_on/scriptmath/scriptmathcomplex.cpp
        ../angelscript/add_on/scriptstdstring/scriptstdstring.h
        ../angelscript/add_on/scriptstdstring/scriptstdstring.cpp
        ../angelscript/add_on/scriptstdstring/scriptstdstring_utils.cpp
        ../angelscript/add_on/scriptjson/scriptjson.h
        ../angelscript/add_on/scriptjson/scriptjson.cpp
        ../angelscript/add_on/serializer/serializer.h
        ../angelscript/add_on/serializer/serializer.cpp
        ../angelscript/add_on/weakref/weakref.cpp
        ../angelscript/add_on/weakref/weakref.h
)

target_include_directories(
        angelscript_addons PUBLIC
        ../angelscript/angelscript/include
        ../angelscript/add_on
)

target_link_libraries(
        angelscript_addons PUBLIC
        angelscript
        nlohmann_json::nlohmann_json
)


code:
add_library(inih STATIC
        ini.c
        ini.h
)


code:
/* inih -- simple .INI file parser

SPDX-License-Identifier: BSD-3-Clause

Copyright (C) 2009-2020, Ben Hoyt

inih is released under the New BSD license (see LICENSE.txt). Go to the project
home page for more info:

https://github.com/benhoyt/inih

*/

#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define INI_CALL_HANDLER_ON_NEW_SECTION 1
#include "ini.h"

#if !INI_USE_STACK
#if INI_CUSTOM_ALLOCATOR
#include <stddef.h>
void* ini_malloc(size_t size);
void ini_free(void* ptr);
void* ini_realloc(void* ptr, size_t size);
#else
#include <stdlib.h>
#define ini_malloc malloc
#define ini_free free
#define ini_realloc realloc
#endif
#endif

#define MAX_SECTION 50
#define MAX_NAME 50

/* Used by ini_parse_string() to keep track of string parsing state. */
typedef struct {
    const char* ptr;
    size_t num_left;
} ini_parse_string_ctx;

/* Strip whitespace chars off end of given string, in place. Return s. */
static char* ini_rstrip(char* s)
{
    char* p = s + strlen(s);
    while (p > s && isspace((unsigned char)(*--p)))
        *p = '\0';
    return s;
}

/* Return pointer to first non-whitespace char in given string. */
static char* ini_lskip(const char* s)
{
    while (*s && isspace((unsigned char)(*s)))
        s++;
    return (char*)s;
}

/* Return pointer to first char (of chars) or inline comment in given string,
   or pointer to NUL at end of string if neither found. Inline comment must
   be prefixed by a whitespace character to register as a comment. */
static char* ini_find_chars_or_comment(const char* s, const char* chars)
{
#if INI_ALLOW_INLINE_COMMENTS
    int was_space = 0;
    while (*s && (!chars || !strchr(chars, *s)) &&
           !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
        was_space = isspace((unsigned char)(*s));
        s++;
    }
#else
    while (*s && (!chars || !strchr(chars, *s))) {
        s++;
    }
#endif
    return (char*)s;
}

/* Similar to strncpy, but ensures dest (size bytes) is
   NUL-terminated, and doesn't pad with NULs. */
static char* ini_strncpy0(char* dest, const char* src, size_t size)
{
    /* Could use strncpy internally, but it causes gcc warnings (see issue #91) */
    size_t i;
    for (i = 0; i < size - 1 && src[i]; i++)
        dest[i] = src[i];
    dest[i] = '\0';
    return dest;
}

/* See documentation in header file. */
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
                     void* user)
{
    /* Uses a fair bit of stack (use heap instead if you need to) */
#if INI_USE_STACK
    char line[INI_MAX_LINE];
    size_t max_line = INI_MAX_LINE;
#else
    char* line;
    size_t max_line = INI_INITIAL_ALLOC;
#endif
#if INI_ALLOW_REALLOC && !INI_USE_STACK
    char* new_line;
#endif
    char section[MAX_SECTION] = "";
#if INI_ALLOW_MULTILINE
    char prev_name[MAX_NAME] = "";
#endif

    size_t offset;
    char* start;
    char* end;
    char* name;
    char* value;
    int lineno = 0;
    int error = 0;
    char abyss[16];  /* Used to consume input when a line is too long. */

#if !INI_USE_STACK
    line = (char*)ini_malloc(INI_INITIAL_ALLOC);
    if (!line) {
        return -2;
    }
#endif

#if INI_HANDLER_LINENO
#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
#else
#define HANDLER(u, s, n, v) handler(u, s, n, v)
#endif

    /* Scan through stream line by line */
    while (reader(line, (int)max_line, stream) != NULL) {
        offset = strlen(line);

#if INI_ALLOW_REALLOC && !INI_USE_STACK
        while (offset == max_line - 1 && line[offset - 1] != '\n') {
            max_line *= 2;
            if (max_line > INI_MAX_LINE)
                max_line = INI_MAX_LINE;
            new_line = ini_realloc(line, max_line);
            if (!new_line) {
                ini_free(line);
                return -2;
            }
            line = new_line;
            if (reader(line + offset, (int)(max_line - offset), stream) == NULL)
                break;
            offset += strlen(line + offset);
            if (max_line >= INI_MAX_LINE)
                break;
        }
#endif

        lineno++;

        /* If line exceeded INI_MAX_LINE bytes, discard till end of line. */
        if (offset == max_line - 1 && line[offset - 1] != '\n') {
            while (reader(abyss, sizeof(abyss), stream) != NULL) {
                if (!error)
                    error = lineno;
                if (abyss[strlen(abyss) - 1] == '\n')
                    break;
            }
        }

        start = line;
#if INI_ALLOW_BOM
        if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
                           (unsigned char)start[1] == 0xBB &&
                           (unsigned char)start[2] == 0xBF) {
            start += 3;
        }
#endif
        start = ini_rstrip(ini_lskip(start));

        if (strchr(INI_START_COMMENT_PREFIXES, *start)) {
            /* Start-of-line comment */
        }
#if INI_ALLOW_MULTILINE
        else if (*prev_name && *start && start > line) {
#if INI_ALLOW_INLINE_COMMENTS
            end = ini_find_chars_or_comment(start, NULL);
            if (*end)
                *end = '\0';
            ini_rstrip(start);
#endif
            /* Non-blank line with leading whitespace, treat as continuation
               of previous name's value (as per Python configparser). */
            if (!HANDLER(user, section, prev_name, start) && !error)
                error = lineno;
        }
#endif
        else if (*start == '[') {
            /* A "[section]" line */
            end = ini_find_chars_or_comment(start + 1, "]");
            if (*end == ']') {
                *end = '\0';
                ini_strncpy0(section, start + 1, sizeof(section));
#if INI_ALLOW_MULTILINE
                *prev_name = '\0';
#endif
#if INI_CALL_HANDLER_ON_NEW_SECTION
                if (!HANDLER(user, section, NULL, NULL) && !error)
                    error = lineno;
#endif
            }
            else if (!error) {
                /* No ']' found on section line */
                error = lineno;
            }
        }
        else if (*start) {
            /* Not a comment, must be a name[=:]value pair */
            end = ini_find_chars_or_comment(start, "=:");
            if (*end == '=' || *end == ':') {
                *end = '\0';
                name = ini_rstrip(start);
                value = end + 1;
#if INI_ALLOW_INLINE_COMMENTS
                end = ini_find_chars_or_comment(value, NULL);
                if (*end)
                    *end = '\0';
#endif
                value = ini_lskip(value);
                ini_rstrip(value);

#if INI_ALLOW_MULTILINE
                ini_strncpy0(prev_name, name, sizeof(prev_name));
#endif
                /* Valid name[=:]value pair found, call handler */
                if (!HANDLER(user, section, name, value) && !error)
                    error = lineno;
            }
            else if (!error) {
                /* No '=' or ':' found on name[=:]value line */
#if INI_ALLOW_NO_VALUE
                *end = '\0';
                name = ini_rstrip(start);
                if (!HANDLER(user, section, name, NULL) && !error)
                    error = lineno;
#else
                error = lineno;
#endif
            }
        }

#if INI_STOP_ON_FIRST_ERROR
        if (error)
            break;
#endif
    }

#if !INI_USE_STACK
    ini_free(line);
#endif

    return error;
}

/* See documentation in header file. */
int ini_parse_file(FILE* file, ini_handler handler, void* user)
{
    return ini_parse_stream((ini_reader)fgets, file, handler, user);
}

/* See documentation in header file. */
int ini_parse(const char* filename, ini_handler handler, void* user)
{
    FILE* file;
    int error;

    file = fopen(filename, "r");
    if (!file)
        return -1;
    error = ini_parse_file(file, handler, user);
    fclose(file);
    return error;
}

/* An ini_reader function to read the next line from a string buffer. This
   is the fgets() equivalent used by ini_parse_string(). */
static char* ini_reader_string(char* str, int num, void* stream) {
    ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream;
    const char* ctx_ptr = ctx->ptr;
    size_t ctx_num_left = ctx->num_left;
    char* strp = str;
    char c;

    if (ctx_num_left == 0 || num < 2)
        return NULL;

    while (num > 1 && ctx_num_left != 0) {
        c = *ctx_ptr++;
        ctx_num_left--;
        *strp++ = c;
        if (c == '\n')
            break;
        num--;
    }

    *strp = '\0';
    ctx->ptr = ctx_ptr;
    ctx->num_left = ctx_num_left;
    return str;
}

/* See documentation in header file. */
int ini_parse_string(const char* string, ini_handler handler, void* user) {
    ini_parse_string_ctx ctx;

    ctx.ptr = string;
    ctx.num_left = strlen(string);
    return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
                            user);
}


code:
/* inih -- simple .INI file parser

SPDX-License-Identifier: BSD-3-Clause

Copyright (C) 2009-2020, Ben Hoyt

inih is released under the New BSD license (see LICENSE.txt). Go to the project
home page for more info:

https://github.com/benhoyt/inih

*/

#ifndef INI_H
#define INI_H

/* Make this header file easier to include in C++ code */
#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>

/* Nonzero if ini_handler callback should accept lineno parameter. */
#ifndef INI_HANDLER_LINENO
#define INI_HANDLER_LINENO 0
#endif

/* Visibility symbols, required for Windows DLLs */
#ifndef INI_API
#if defined _WIN32 || defined __CYGWIN__
#	ifdef INI_SHARED_LIB
#		ifdef INI_SHARED_LIB_BUILDING
#			define INI_API __declspec(dllexport)
#		else
#			define INI_API __declspec(dllimport)
#		endif
#	else
#		define INI_API
#	endif
#else
#	if defined(__GNUC__) && __GNUC__ >= 4
#		define INI_API __attribute__ ((visibility ("default")))
#	else
#		define INI_API
#	endif
#endif
#endif

/* Typedef for prototype of handler function.

   Note that even though the value parameter has type "const char*", the user
   may cast to "char*" and modify its content, as the value is not used again
   after the call to ini_handler. This is not true of section and name --
   those must not be modified.
*/
#if INI_HANDLER_LINENO
typedef int (*ini_handler)(void* user, const char* section,
                           const char* name, const char* value,
                           int lineno);
#else
typedef int (*ini_handler)(void* user, const char* section,
                           const char* name, const char* value);
#endif

/* Typedef for prototype of fgets-style reader function. */
typedef char* (*ini_reader)(char* str, int num, void* stream);

/* Parse given INI-style file. May have [section]s, name=value pairs
   (whitespace stripped), and comments starting with ';' (semicolon). Section
   is "" if name=value pair parsed before any section heading. name:value
   pairs are also supported as a concession to Python's configparser.

   For each name=value pair parsed, call handler function with given user
   pointer as well as section, name, and value (data only valid for duration
   of handler call). Handler should return nonzero on success, zero on error.

   Returns 0 on success, line number of first error on parse error (doesn't
   stop on first error), -1 on file open error, or -2 on memory allocation
   error (only when INI_USE_STACK is zero).
*/
INI_API int ini_parse(const char* filename, ini_handler handler, void* user);

/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
   close the file when it's finished -- the caller must do that. */
INI_API int ini_parse_file(FILE* file, ini_handler handler, void* user);

/* Same as ini_parse(), but takes an ini_reader function pointer instead of
   filename. Used for implementing custom or string-based I/O (see also
   ini_parse_string). */
INI_API int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
                     void* user);

/* Same as ini_parse(), but takes a zero-terminated string with the INI data
instead of a file. Useful for parsing INI data from a network socket or
already in memory. */
INI_API int ini_parse_string(const char* string, ini_handler handler, void* user);

/* Nonzero to allow multi-line value parsing, in the style of Python's
   configparser. If allowed, ini_parse() will call the handler with the same
   name for each subsequent line parsed. */
#ifndef INI_ALLOW_MULTILINE
#define INI_ALLOW_MULTILINE 1
#endif

/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
   the file. See https://github.com/benhoyt/inih/issues/21 */
#ifndef INI_ALLOW_BOM
#define INI_ALLOW_BOM 1
#endif

/* Chars that begin a start-of-line comment. Per Python configparser, allow
   both ; and # comments at the start of a line by default. */
#ifndef INI_START_COMMENT_PREFIXES
#define INI_START_COMMENT_PREFIXES ";#"
#endif

/* Nonzero to allow inline comments (with valid inline comment characters
   specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match
   Python 3.2+ configparser behaviour. */
#ifndef INI_ALLOW_INLINE_COMMENTS
#define INI_ALLOW_INLINE_COMMENTS 1
#endif
#ifndef INI_INLINE_COMMENT_PREFIXES
#define INI_INLINE_COMMENT_PREFIXES ";"
#endif

/* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */
#ifndef INI_USE_STACK
#define INI_USE_STACK 1
#endif

/* Maximum line length for any line in INI file (stack or heap). Note that
   this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */
#ifndef INI_MAX_LINE
#define INI_MAX_LINE 200
#endif

/* Nonzero to allow heap line buffer to grow via realloc(), zero for a
   fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is
   zero. */
#ifndef INI_ALLOW_REALLOC
#define INI_ALLOW_REALLOC 0
#endif

/* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK
   is zero. */
#ifndef INI_INITIAL_ALLOC
#define INI_INITIAL_ALLOC 200
#endif

/* Stop parsing on first error (default is to keep parsing). */
#ifndef INI_STOP_ON_FIRST_ERROR
#define INI_STOP_ON_FIRST_ERROR 0
#endif

/* Nonzero to call the handler at the start of each new section (with
   name and value NULL). Default is to only call the handler on
   each name=value pair. */
#ifndef INI_CALL_HANDLER_ON_NEW_SECTION
#define INI_CALL_HANDLER_ON_NEW_SECTION 0
#endif

/* Nonzero to allow a name without a value (no '=' or ':' on the line) and
   call the handler with value NULL in this case. Default is to treat
   no-value lines as an error. */
#ifndef INI_ALLOW_NO_VALUE
#define INI_ALLOW_NO_VALUE 0
#endif

/* Nonzero to use custom ini_malloc, ini_free, and ini_realloc memory
   allocation functions (INI_USE_STACK must also be 0). These functions must
   have the same signatures as malloc/free/realloc and behave in a similar
   way. ini_realloc is only needed if INI_ALLOW_REALLOC is set. */
#ifndef INI_CUSTOM_ALLOCATOR
#define INI_CUSTOM_ALLOCATOR 0
#endif

#ifdef __cplusplus
}
#endif

#endif /* INI_H */


code:
nano-signal-slot
================

Pure C++17 Signals and Slots

#### Include
```
// #include "nano_function.hpp"         // Nano::Function, Nano::Delegate_Key
// #include "nano_mutex.hpp"            // Nano::Spin_Mutex, all threading policies
// #include "nano_observer.hpp"         // Nano::Observer
#include "nano_signal_slot.hpp"         // Nano::Signal
```

#### Declare
```
// Declare Nano::Signals using function signature syntax
Nano::Signal<bool(const char*)> signal_one;
Nano::Signal<bool(const char*, std::size_t)> signal_two;
```

#### Connect
```
// Connect member functions to Nano::Signals
signal_one.connect<&Foo::slot_member_one>(foo);
signal_two.connect<&Foo::slot_member_two>(foo);

// Connect overloaded member functions (required template syntax)
signal_one.connect<Foo, &Foo::slot_overloaded_member>(foo);
signal_two.connect<Foo, &Foo::slot_overloaded_member>(foo);

// Connect a static member function
signal_one.connect<&Foo::slot_static_member_one>();

// Connect a free function
signal_two.connect<&slot_free_function_one>();
```

#### Fire / Fire Accumulate

_Slot emission is not guaranteed to be in the order of connection._

```
// Fire Signals
signal_one.fire("we get signal");
signal_two.fire("main screen turn on", __LINE__);

std::vector<bool> statuses;
auto accumulator = [&](bool srv)
{
    statuses.push_back(srv);
};

// Fire Signals and accumulate SRVs (signal return values)
signal_one.fire_accumulate(accumulator, "how are you gentlemen");
```

#### Disconnect
```
// Disconnect member functions from Nano::Signals
signal_one.disconnect<&Foo::slot_member_one>(foo);
signal_two.disconnect<&Foo::slot_member_two>(foo);

// Disconnect overloaded member functions (required template syntax)
signal_one.disconnect<Foo, &Foo::slot_overloaded_member>(foo);

// Disconnect a static member function
signal_one.disconnect<&Foo::slot_static_member_one>();

// Disconnect a free function
signal_two.disconnect<&slot_free_function_one>();

// Disconnect all slots
signal_two.disconnect_all();
```

#### Connection Management

_Automatic connection management requires public inheritance from Nano::Observer<>._

```
struct Foo : public Nano::Observer<>
{
    bool slot_member_one(const char* sl) const
    {
        std::cout << sl << std::endl;
        return true;
    }
	...
```

#### Function Objects

**_Connected function objects must live longer than the connected signal._**

_(be sure to disconnect the function object prior to it destructing)_

```
auto fo = [&](const char* sl)
{
    std::cout << sl << std::endl;
    return true;
};

...

// Connect any object that defines a suitable operator()
signal_one.connect(fo);

...

// Disconnect that same functor instance
signal_one.disconnect(fo);
```

#### Threading Policies

Nano-signal-slot has the following threading policies available for use:

|   | ST_Policy | TS_Policy | ST_Policy_Safe | TS_Policy_Safe |
|:-------|:---------:|:---------:|:--------------:|:--------------:|
| Single threading only | X | - | X | - |
| Thread safe using mutex | - | X | - | X |
| Reentrant safe* | - | - | X | X |

_* Reentrant safety achieved using emission copying and reference counting._

#### Threading Policies - Aliases

When integrating nano-signal-slot, it is recommended to alias the Nano::Signal and Nano::Observer template classes.

**When using a non-default Policy you must make sure that both Signal and Observer use the same policy.**

```
namespace Your_Namespace
{

// Creating aliases when using nano-signal-slot will increase the maintainability of your code
// especially if you are choosing to use the alternative policies.
template <typename Signatue>
using Your_Signal<Signature> = Nano::Signal<Signature, Nano::TS_Policy_Safe<>>;
using Your_Observer = Nano::Observer<Nano::TS_Policy_Safe<>>;

}
```

#### Threading Policies - Mutex Policy

Both the TS_Policy and TS_Policy_Safe allow for a provided mutex type if non-trivial locking is desired.

_The provided mutex type only needs to implement the BasicLockable requirement._

```
using Your_Policy = Nano::TS_Policy<Your_Mutex>;
```

## Deadlock Disclaimer

The TS_Policy does not mitigate any deadlocks that could occur due to slot emissions fiddling with their signals.
Additionally, when using this policy, it is not safe to destruct connected Nano::Observers from different threads.
Generally if the threading posture in your application allows for it then use the TS_Policy for the performance.
If the lifetimes of Signals vs Observers is unknown or if the slots could be hostile then use the TS_Policy_Safe.

#### Links

| [Benchmark Results](https://github.com/NoAvailableAlias/signal-slot-benchmarks/tree/master/#signal-slot-benchmarks) | [Benchmark Algorithms](https://github.com/NoAvailableAlias/signal-slot-benchmarks/tree/master/#benchmark-algorithms) | [Unit Tests](/tests/#unit-tests) |
|:-------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------:|:--------------------------------:|


code:
Benchmarks Have Moved
=====================

The comprehensive benchmarks have been moved to a new project [signal-slot-benchmarks](https://github.com/NoAvailableAlias/signal-slot-benchmarks/tree/master/#signal-slot-benchmarks).
Because links to this page still exist, this readme will remain here for the time being.


code:
#pragma once

#include <cstdint>
#include <array>

namespace Nano
{

using Delegate_Key = std::array<std::uintptr_t, 2>;

template <typename RT> class Function;
template <typename RT, typename... Args>
class Function<RT(Args...)> final
{
    // Only Nano::Observer is allowed private access
    template <typename> friend class Observer;

    using Thunk = RT(*)(void*, Args&&...);

    static inline Function bind(Delegate_Key const& delegate_key)
    {
        return
        {
            reinterpret_cast<void*>(delegate_key[0]),
            reinterpret_cast<Thunk>(delegate_key[1])
        };
    }

    public:

    void* const instance_pointer;
    const Thunk function_pointer;

    template <auto fun_ptr>
    static inline Function bind()
    {
        return
        {
            nullptr, [](void* /*NULL*/, Args&&... args)
            {
                return (*fun_ptr)(std::forward<Args>(args)...);
            }
        };
    }

    template <auto mem_ptr, typename T>
    static inline Function bind(T* pointer)
    {
        return
        {
            pointer, [](void* this_ptr, Args&&... args)
            {
                return (static_cast<T*>(this_ptr)->*mem_ptr)(std::forward<Args>(args)...);
            }
        };
    }

    template <typename L>
    static inline Function bind(L* pointer)
    {
        return
        {
            pointer, [](void *this_ptr, Args&&... args)
            {
                return static_cast<L*>(this_ptr)->operator()(std::forward<Args>(args)...);
            }
        };
    }

    inline RT operator() (Args... args)
    {
        return (*function_pointer)(instance_pointer, std::forward<Args>(args)...);
    }

    inline operator Delegate_Key() const
    {
        return
        {
            reinterpret_cast<std::uintptr_t>(instance_pointer),
            reinterpret_cast<std::uintptr_t>(function_pointer)
        };
    }
};

} // namespace Nano ------------------------------------------------------------