1. SirPolly
  2. PolyEngine

Commits

TWO  committed 3ff4866

Added initial Python (stackless) wrapper
Fixed logging of < >

  • Participants
  • Parent commits 0de1ed1
  • Branches default

Comments (0)

Files changed (41)

File PolyMain/PolyMain.vcxproj

View file
  • Ignore whitespace
     <LinkIncremental>true</LinkIncremental>
     <OutDir>lib\</OutDir>
     <TargetName>$(ProjectName)_d</TargetName>
-    <IncludePath>..\dependencies\include\squirrel;..\dependencies\include;lib;$(IncludePath)</IncludePath>
+    <IncludePath>..\dependencies\include;lib;$(IncludePath)</IncludePath>
     <LibraryPath>..\dependencies\lib\debug;$(LibraryPath)</LibraryPath>
     <IntDir>obj\$(Configuration)\</IntDir>
   </PropertyGroup>

File PolyMain/include/core/PolyLog.cpp

View file
  • Ignore whitespace
 	}
 
 	void Log::logMessage(const String& msg, LogLevel lvl, const String& file, uint line) {
+		String msgEscaped = StringUtil::replaceAll(msg, "<", "&lt;");
+		msgEscaped = StringUtil::replaceAll(msgEscaped, ">", "&gt;");
+
 		BOOST_FOREACH(ILogListener* listener, mListeners)
-			listener->logMessage(msg, lvl, file, line);
+			listener->logMessage(msgEscaped, lvl, file, line);
 
 		ulong time = TimeUtil::getMS();
 
 		if(!file.empty())
 			mFile << "<span class='source'>" << file << " line " << line << "</span>";
 
-		mFile << msg
+		mFile << msgEscaped
 			<< "</div>" << std::endl;
 
 		mFile.flush();

File PolyMain/include/game/PolyEntityLogic.cpp

View file
  • Ignore whitespace
 	}
 
 	EntityLogic::~EntityLogic() {
-	//	gEnv.entityMgr->removeEntityLogic(this);
 	}
 }

File PolyMain/include/game/PolyEntityManager.h

View file
  • Ignore whitespace
 		void				getEntitiesInSphere(const Vector3& position, float radius, EntityVector& entities) const;
 
 		// EntityLogic
+		///
 		void				addEntityLogic(EntityLogicPtr logic);
 		void				removeEntityLogic(EntityLogicPtr logic);
 

File PolyPython/PolyPython.vcxproj

View file
  • Ignore whitespace
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="include\PolyPython.h" />
+    <ClInclude Include="include\PolyPythonBindings.h" />
+    <ClInclude Include="include\PolyPythonPrerequisites.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="include\converter\arg_to_python_base.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\converter\builtin_converters.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\converter\from_python.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\converter\registry.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\converter\type_id.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\dict.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\errors.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\exec.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\import.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\list.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\long.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\module.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\numeric.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\class.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\enum.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\function.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\function_doc_signature.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\inheritance.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\iterator.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\life_support.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\pickle_support.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object\stl_iterator.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object_operators.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\object_protocol.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\PolyPythonBindings.cpp" />
+    <ClCompile Include="include\PolyPythonPrerequisites.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\slice.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\str.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\tuple.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="include\wrapper.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{5C7D060D-DEF2-4EFF-B694-DB083CC9804C}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>PolyPython</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>lib\</OutDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+    <IncludePath>C:\Python32\include;C:\Python32\include\Stackless;..\dependencies\include;lib;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Python32\libs;..\dependencies\lib\debug;$(LibraryPath)</LibraryPath>
+    <IntDir>obj\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>lib\</OutDir>
+    <IncludePath>C:\Python32\include;C:\Python32\include\Stackless;..\dependencies\include;lib;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Python32\libs;..\dependencies\lib\release;$(LibraryPath)</LibraryPath>
+    <IntDir>obj\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_PolyPythonExportInterface;BOOST_PYTHON_SOURCE;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PrecompiledHeaderFile>PolyPythonPrerequisites.h</PrecompiledHeaderFile>
+      <AdditionalOptions>-Zm1000</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>OgreMain_d.lib;PhysX3CHECKED_x86.lib;PhysX3CommonCHECKED_x86.lib;PhysX3CookingCHECKED_x86.lib;PhysX3CharacterKinematicCHECKED_x86.lib;PhysX3ExtensionsCHECKED.lib;PhysXVisualDebuggerSDKCHECKED.lib;PolyMain_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <IgnoreSpecificDefaultLibraries>LIBCMT</IgnoreSpecificDefaultLibraries>
+    </Link>
+    <PostBuildEvent>
+      <Command>copy $(TargetPath) ..\bin\*.*</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_PolyPythonExportInterface;BOOST_PYTHON_SOURCE;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PrecompiledHeaderFile>PolyPythonPrerequisites.h</PrecompiledHeaderFile>
+      <AdditionalOptions>-Zm1000</AdditionalOptions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>OgreMain.lib;PhysX3CHECKED_x86.lib;PhysX3CommonCHECKED_x86.lib;PhysX3CookingCHECKED_x86.lib;PhysX3CharacterKinematicCHECKED_x86.lib;PhysX3ExtensionsCHECKED.lib;PhysXVisualDebuggerSDKCHECKED.lib;PolyMain.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <IgnoreSpecificDefaultLibraries>LIBCMT</IgnoreSpecificDefaultLibraries>
+    </Link>
+    <PostBuildEvent>
+      <Command>copy $(TargetPath) ..\bin\*.*</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

File PolyPython/PolyPython.vcxproj.filters

View file
  • Ignore whitespace
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="include\PolyPythonBindings.cpp" />
+    <ClCompile Include="include\PolyPythonPrerequisites.cpp" />
+    <ClCompile Include="include\dict.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\errors.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\exec.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\import.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\list.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\long.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\module.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\numeric.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object_operators.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object_protocol.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\slice.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\str.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\tuple.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\wrapper.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\class.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\enum.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\function.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\function_doc_signature.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\inheritance.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\iterator.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\life_support.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\pickle_support.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\object\stl_iterator.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\converter\arg_to_python_base.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\converter\builtin_converters.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\converter\from_python.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\converter\registry.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+    <ClCompile Include="include\converter\type_id.cpp">
+      <Filter>python</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="include\PolyPython.h" />
+    <ClInclude Include="include\PolyPythonBindings.h" />
+    <ClInclude Include="include\PolyPythonPrerequisites.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <Filter Include="python">
+      <UniqueIdentifier>{b8a616e5-36e2-4501-8bb9-a856b1ba804b}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>

File PolyPython/include/PolyPython.h

View file
  • Ignore whitespace
+/*
+    Copyright (c) Oliver 'SirPolly' Weitzel
+                                                                                  
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+                                                                                  
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+                                                                                  
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE. 
+    
+*/
+
+#ifndef PolyPython_h
+#define PolyPython_h
+
+#include "PolyPythonPrerequisites.h"
+
+#endif

File PolyPython/include/PolyPythonBindings.cpp

View file
  • Ignore whitespace
+/*
+    Copyright (c) Oliver 'SirPolly' Weitzel
+                                                                                  
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+                                                                                  
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+                                                                                  
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE. 
+    
+*/
+
+#include "PolyPythonPrerequisites.h"
+
+#include "PolyPythonBindings.h"
+
+
+class PythonEntityLogic : public EntityLogic {
+public:
+	PythonEntityLogic(PyObject* p)
+	:	mSelf(p) {}
+	PythonEntityLogic(PyObject* p, const EntityLogic& self)
+	:	mSelf(p), EntityLogic(self) {}
+
+	virtual void updateEntities(const EntityList& entities) {
+		bp::call_method<void>(mSelf, "updateEntities", entities);
+	}
+	static void updateEntitiesDefault(EntityLogic& self, const EntityList& entities) {
+		self.EntityLogic::updateEntities(entities);
+	}
+private:
+	PyObject* mSelf;
+};
+
+void logDefault(const char* str) {
+	POLY_LOG(str);
+}
+void logError(const char* str) {
+	POLY_LOG_CRITICAL(str);
+}
+
+BOOST_PYTHON_MODULE(poly) {
+	// Core
+	bp::def("_log_hook", &logDefault);
+	bp::def("_log_error_hook", &logError);
+
+	// Game
+	bp::class_<EntityList>("EntityList")
+		.def("__len__", &EntityList::size);
+
+	bp::class_<EntityLogic, PythonEntityLogic, EntityLogicPtr>("EntityLogic")
+		.def("updateEntities", &PythonEntityLogic::updateEntitiesDefault);
+
+	bp::class_<EntityManager, boost::noncopyable>("EntityManager")
+		.def("addEntityLogic", &EntityManager::addEntityLogic);
+
+	// Runtime environment
+	EntityManager* entityMgr =  gEnv.entityMgr.get();
+	bp::scope().attr("entityMgr") = boost::ref(entityMgr); 
+}
+
+void init_print(bp::object mainNamespace) {
+	bp::exec(
+		"import sys\n"
+		"import poly\n"
+		"class StdoutCatcher:\n"
+		"	def write(self, str):\n"
+		"		poly._log_hook(str)\n"
+		"class StderrCatcher:\n"
+		"	def write(self, str):\n"
+		"		poly._log_error_hook(str)\n"
+		"sys.stdout = StdoutCatcher()\n"
+		"sys.stderr = StderrCatcher()\n",
+		mainNamespace,
+		mainNamespace);
+}

File PolyPython/include/PolyPythonBindings.h

View file
  • Ignore whitespace
+/*
+    Copyright (c) Oliver 'SirPolly' Weitzel
+                                                                                  
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+                                                                                  
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+                                                                                  
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE. 
+    
+*/
+
+#ifndef PolyPythonBindings_h
+#define PolyPythonBindings_h
+
+extern "C" __declspec(dllexport) PyObject* PyInit_poly();
+void init_print(bp::object mainNamespace);
+
+#endif

File PolyPython/include/PolyPythonPrerequisites.cpp

View file
  • Ignore whitespace
+/*
+    Copyright (c) Oliver 'SirPolly' Weitzel
+                                                                                  
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+                                                                                  
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+                                                                                  
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE. 
+    
+*/
+
+#include "PolyPythonPrerequisites.h"
+#include "PolyPythonBindings.h"
+
+
+namespace Poly {
+	namespace Python {
+		bp::object main_module;
+		bp::object main_namespace;
+
+		void init() {
+			PyImport_AppendInittab("poly", &PyInit_poly);
+
+			Py_Initialize();
+			if(!Py_IsInitialized()) {
+				POLY_LOG_CRITICAL("Failed to initialize Python!");
+				return;
+			}
+
+			try {
+				main_module = bp::import("__main__");
+				main_namespace = main_module.attr("__dict__");
+				
+				init_print(main_namespace);
+			}
+			catch(const bp::error_already_set&) {
+				_fetchError();
+			}
+		}
+
+		void runScript(const String& fileName) {
+			try {
+				POLY_LOG("Running script '" << fileName << "'");
+
+				Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(fileName);
+				String content = stream->getAsString();
+
+				bp::exec(content.c_str(), main_namespace, main_namespace);
+			}
+			catch(const bp::error_already_set&) {
+				_fetchError();
+			}
+		}
+
+		void _fetchError() {
+			PyObject* ptype, *pvalue, *ptraceback;
+			PyErr_Fetch( &ptype, &pvalue, &ptraceback );
+
+			//Extract error message
+			String strErrorMessage = bp::extract<String>( pvalue );
+
+			bp::handle<> hType( ptype );
+			bp::object extype( hType );
+
+			long lineno = 0;
+			String filename;
+			String funcname;
+
+			if(ptraceback) {
+				bp::handle<> hTraceback( ptraceback );
+				bp::object traceback( hTraceback );
+
+				lineno = bp::extract<long> (traceback.attr("tb_lineno"));
+				filename = bp::extract<String>(traceback.attr("tb_frame").attr("f_code").attr("co_filename"));
+				funcname = bp::extract<String>(traceback.attr("tb_frame").attr("f_code").attr("co_name"));
+			}
+
+			String msg = "Error " + filename + "(" + StringConverter::toString( lineno ) + ") : " + strErrorMessage;
+
+
+			POLY_LOG_CRITICAL(msg);
+		}
+	}
+}

File PolyPython/include/PolyPythonPrerequisites.h

View file
  • Ignore whitespace
+/*
+    Copyright (c) Oliver 'SirPolly' Weitzel
+                                                                                  
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+                                                                                  
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+                                                                                  
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE. 
+    
+*/
+
+#ifndef PolyPythonPrerequisites_h
+#define PolyPythonPrerequisites_h
+
+#include "Poly.h"
+using namespace Poly;
+
+// Note: Needs stackless Python 3.2! Only the headers, source files are included in this project.
+#include <boost/python.hpp>
+namespace bp = boost::python;
+
+// DLL
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+#	ifdef _PolyPythonExportInterface
+#		define _PolyPythonExport __declspec(dllexport)
+#	else
+#		define _PolyPythonExport __declspec(dllimport)
+#	endif
+#else
+#	define _PolyPythonExport
+#endif
+
+namespace Poly {
+	namespace Python {
+		_PolyPythonExport void init();
+		_PolyPythonExport void runScript(const String& fileName);
+		_PolyPythonExport void _fetchError();
+	}
+}
+
+#endif

File PolyPython/include/converter/arg_to_python_base.cpp

View file
  • Ignore whitespace
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/converter/arg_to_python_base.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/handle.hpp>
+#include <boost/python/refcount.hpp>
+
+namespace boost { namespace python { namespace converter { 
+
+namespace detail
+{
+  arg_to_python_base::arg_to_python_base(
+      void const volatile* source, registration const& converters)
+# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179
+      : handle<>
+# else
+      : m_ptr
+# endif
+         (converters.to_python(source))
+  {
+  }
+}
+
+}}} // namespace boost::python::converter

File PolyPython/include/converter/builtin_converters.cpp

View file
  • Ignore whitespace
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/handle.hpp>
+#include <boost/python/type_id.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/refcount.hpp>
+
+#include <boost/python/detail/config.hpp>
+#include <boost/python/detail/wrap_python.hpp>
+
+#include <boost/python/converter/builtin_converters.hpp>
+#include <boost/python/converter/rvalue_from_python_data.hpp>
+#include <boost/python/converter/registry.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/converter/shared_ptr_deleter.hpp>
+#include <boost/python/converter/pytype_function.hpp>
+
+#include <boost/cast.hpp>
+#include <string>
+#include <complex>
+
+namespace boost { namespace python { namespace converter {
+
+shared_ptr_deleter::shared_ptr_deleter(handle<> owner)
+    : owner(owner)
+{}
+
+shared_ptr_deleter::~shared_ptr_deleter() {}
+
+void shared_ptr_deleter::operator()(void const*)
+{
+    owner.reset();
+}
+
+namespace
+{
+
+  // An lvalue conversion function which extracts a char const* from a
+  // Python String.
+#if PY_VERSION_HEX < 0x03000000
+  void* convert_to_cstring(PyObject* obj)
+  {
+      return PyString_Check(obj) ? PyString_AsString(obj) : 0;
+  }
+#else
+  void* convert_to_cstring(PyObject* obj)
+  {
+      return PyUnicode_Check(obj) ? _PyUnicode_AsString(obj) : 0;
+  }
+#endif
+
+  // Given a target type and a SlotPolicy describing how to perform a
+  // given conversion, registers from_python converters which use the
+  // SlotPolicy to extract the type.
+  template <class T, class SlotPolicy>
+  struct slot_rvalue_from_python
+  {
+   public:
+      slot_rvalue_from_python()
+      {
+          registry::insert(
+              &slot_rvalue_from_python<T,SlotPolicy>::convertible
+              , &slot_rvalue_from_python<T,SlotPolicy>::construct
+              , type_id<T>()
+              , &SlotPolicy::get_pytype
+              );
+      }
+      
+   private:
+      static void* convertible(PyObject* obj)
+      {
+          unaryfunc* slot = SlotPolicy::get_slot(obj);
+          return slot && *slot ? slot : 0;
+      }
+
+      static void construct(PyObject* obj, rvalue_from_python_stage1_data* data)
+      {
+          // Get the (intermediate) source object
+          unaryfunc creator = *static_cast<unaryfunc*>(data->convertible);
+          handle<> intermediate(creator(obj));
+
+          // Get the location in which to construct
+          void* storage = ((rvalue_from_python_storage<T>*)data)->storage.bytes;
+# ifdef _MSC_VER
+#  pragma warning(push)
+#  pragma warning(disable:4244)
+# endif 
+          new (storage) T( SlotPolicy::extract(intermediate.get()) );
+          
+# ifdef _MSC_VER
+#  pragma warning(pop)
+# endif 
+          // record successful construction
+          data->convertible = storage;
+      }
+  };
+
+  // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
+  // "slot" which just returns its argument. 
+  extern "C" PyObject* identity_unaryfunc(PyObject* x)
+  {
+      Py_INCREF(x);
+      return x;
+  }
+  unaryfunc py_object_identity = identity_unaryfunc;
+
+#if PY_VERSION_HEX >= 0x03000000
+  // As in Python 3 there is only one integer type, we can have much
+  // simplified logic.
+  // XXX(bhy) maybe the code will work with 2.6 or even 2.5?
+  struct int_rvalue_from_python_base
+  {
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+          return PyLong_Check(obj) ? &py_object_identity : 0;
+      }
+      static PyTypeObject const* get_pytype() {return &PyLong_Type;}
+  };
+
+  template <class T>
+  struct signed_int_rvalue_from_python : int_rvalue_from_python_base
+  {
+      static T extract(PyObject* intermediate)
+      {
+          long x = PyLong_AsLong(intermediate);
+          if (PyErr_Occurred())
+              throw_error_already_set();
+          return numeric_cast<T>(x);
+      }
+  };
+
+  template <class T>
+  struct unsigned_int_rvalue_from_python : int_rvalue_from_python_base
+  {
+      static T extract(PyObject* intermediate)
+      {
+          unsigned long x = PyLong_AsUnsignedLong(intermediate);
+          if (PyErr_Occurred())
+              throw_error_already_set();
+          return numeric_cast<T>(x);
+      }
+  };
+#else // PY_VERSION_HEX >= 0x03000000
+  // A SlotPolicy for extracting signed integer types from Python objects
+  struct signed_int_rvalue_from_python_base
+  {
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+          PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
+          if (number_methods == 0)
+              return 0;
+
+          return (
+#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
+          !PyBool_Check(obj) &&
+#endif
+          (PyInt_Check(obj) || PyLong_Check(obj)))
+
+        ? &number_methods->nb_int : 0;
+      }
+      static PyTypeObject const* get_pytype() { return &PyInt_Type;}
+  };
+
+  template <class T>
+  struct signed_int_rvalue_from_python : signed_int_rvalue_from_python_base
+  {
+      static T extract(PyObject* intermediate)
+      {
+          long x = PyInt_AsLong(intermediate);
+          if (PyErr_Occurred())
+              throw_error_already_set();
+          return numeric_cast<T>(x);
+      }
+  };
+  
+  // A SlotPolicy for extracting unsigned integer types from Python objects
+  struct unsigned_int_rvalue_from_python_base
+  {
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+          PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
+          if (number_methods == 0)
+              return 0;
+
+          return (
+#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
+          !PyBool_Check(obj) &&
+#endif
+          (PyInt_Check(obj) || PyLong_Check(obj)))
+              ? &py_object_identity : 0;
+      }
+      static PyTypeObject const* get_pytype() { return &PyInt_Type;}
+  };
+
+  template <class T>
+  struct unsigned_int_rvalue_from_python : unsigned_int_rvalue_from_python_base
+  {
+      static T extract(PyObject* intermediate)
+      {
+          if (PyLong_Check(intermediate)) {
+              // PyLong_AsUnsignedLong() checks for negative overflow, so no
+              // need to check it here.
+              unsigned long result = PyLong_AsUnsignedLong(intermediate);
+              if (PyErr_Occurred())
+                  throw_error_already_set();
+              return numeric_cast<T>(result);
+          } else {
+              // None of PyInt_AsUnsigned*() functions check for negative
+              // overflow, so use PyInt_AS_LONG instead and check if number is
+              // negative, issuing the exception appropriately.
+              long result = PyInt_AS_LONG(intermediate);
+              if (PyErr_Occurred())
+                  throw_error_already_set();
+              if (result < 0) {
+                  PyErr_SetString(PyExc_OverflowError, "can't convert negative"
+                                  " value to unsigned");
+                  throw_error_already_set();
+              }
+              return numeric_cast<T>(result);
+          }
+      }
+  };
+#endif // PY_VERSION_HEX >= 0x03000000
+
+// Checking Python's macro instead of Boost's - we don't seem to get
+// the config right all the time. Furthermore, Python's is defined
+// when long long is absent but __int64 is present.
+  
+#ifdef HAVE_LONG_LONG
+  // A SlotPolicy for extracting long long types from Python objects
+
+  struct long_long_rvalue_from_python_base
+  {
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+#if PY_VERSION_HEX >= 0x03000000
+          return PyLong_Check(obj) ? &py_object_identity : 0;
+#else
+          PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
+          if (number_methods == 0)
+              return 0;
+
+          // Return the identity conversion slot to avoid creating a
+          // new object. We'll handle that in the extract function
+          if (PyInt_Check(obj))
+              return &number_methods->nb_int;
+          else if (PyLong_Check(obj))
+              return &number_methods->nb_long;
+          else
+              return 0;
+#endif
+      }
+      static PyTypeObject const* get_pytype() { return &PyLong_Type;}
+  };
+  
+  struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
+  {
+      static BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
+      {
+#if PY_VERSION_HEX < 0x03000000
+          if (PyInt_Check(intermediate))
+          {
+              return PyInt_AS_LONG(intermediate);
+          }
+          else
+#endif
+          {
+              BOOST_PYTHON_LONG_LONG result = PyLong_AsLongLong(intermediate);
+              
+              if (PyErr_Occurred())
+                  throw_error_already_set();
+
+              return result;
+          }
+      }
+  };
+
+  struct unsigned_long_long_rvalue_from_python : long_long_rvalue_from_python_base
+  {
+      static unsigned BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
+      {
+#if PY_VERSION_HEX < 0x03000000
+          if (PyInt_Check(intermediate))
+          {
+              return numeric_cast<unsigned BOOST_PYTHON_LONG_LONG>(PyInt_AS_LONG(intermediate));
+          }
+          else
+#endif
+          {
+              unsigned BOOST_PYTHON_LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate);
+              
+              if (PyErr_Occurred())
+                  throw_error_already_set();
+
+              return result;
+          }
+      }
+  };
+#endif 
+
+  // A SlotPolicy for extracting bool from a Python object
+  struct bool_rvalue_from_python
+  {
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+#if PY_VERSION_HEX >= 0x03000000
+          return obj == Py_None || PyLong_Check(obj) ? &py_object_identity : 0;
+#elif PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
+          return obj == Py_None || PyBool_Check(obj) ? &py_object_identity : 0;
+#else
+          return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
+#endif
+      }
+      
+      static bool extract(PyObject* intermediate)
+      {
+          return PyObject_IsTrue(intermediate);
+      }
+
+      static PyTypeObject const* get_pytype()
+      {
+#if PY_VERSION_HEX >= 0x02030000
+        return &PyBool_Type;
+#else
+        return &PyInt_Type;
+#endif
+      }
+  };
+
+  // A SlotPolicy for extracting floating types from Python objects.
+  struct float_rvalue_from_python
+  {
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+          PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
+          if (number_methods == 0)
+              return 0;
+
+          // For integer types, return the tp_int conversion slot to avoid
+          // creating a new object. We'll handle that below
+#if PY_VERSION_HEX < 0x03000000
+          if (PyInt_Check(obj))
+              return &number_methods->nb_int;
+#endif
+
+          return (PyLong_Check(obj) || PyFloat_Check(obj))
+              ? &number_methods->nb_float : 0;
+      }
+      
+      static double extract(PyObject* intermediate)
+      {
+#if PY_VERSION_HEX < 0x03000000
+          if (PyInt_Check(intermediate))
+          {
+              return PyInt_AS_LONG(intermediate);
+          }
+          else
+#endif
+          {
+              return PyFloat_AS_DOUBLE(intermediate);
+          }
+      }
+      static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
+  };
+
+#if PY_VERSION_HEX >= 0x03000000
+  unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
+#endif
+
+  // A SlotPolicy for extracting C++ strings from Python objects.
+  struct string_rvalue_from_python
+  {
+      // If the underlying object is "string-able" this will succeed
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+#if PY_VERSION_HEX >= 0x03000000
+          return (PyUnicode_Check(obj)) ? &py_unicode_as_string_unaryfunc : 
+                  PyBytes_Check(obj) ? &py_object_identity : 0;
+#else
+          return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0;
+
+#endif
+      };
+
+      // Remember that this will be used to construct the result object 
+#if PY_VERSION_HEX >= 0x03000000
+      static std::string extract(PyObject* intermediate)
+      {
+          return std::string(PyBytes_AsString(intermediate),PyBytes_Size(intermediate));
+      }
+      static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
+#else
+      static std::string extract(PyObject* intermediate)
+      {
+          return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
+      }
+      static PyTypeObject const* get_pytype() { return &PyString_Type;}
+#endif
+  };
+
+#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
+  // encode_string_unaryfunc/py_encode_string -- manufacture a unaryfunc
+  // "slot" which encodes a Python string using the default encoding
+  extern "C" PyObject* encode_string_unaryfunc(PyObject* x)
+  {
+      return PyUnicode_FromEncodedObject( x, 0, 0 );
+  }
+  unaryfunc py_encode_string = encode_string_unaryfunc;
+
+  // A SlotPolicy for extracting C++ strings from Python objects.
+  struct wstring_rvalue_from_python
+  {
+      // If the underlying object is "string-able" this will succeed
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+          return PyUnicode_Check(obj)
+              ? &py_object_identity
+#if PY_VERSION_HEX >= 0x03000000
+            : PyBytes_Check(obj)
+#else
+            : PyString_Check(obj)
+#endif
+              ? &py_encode_string
+            : 0;
+      };
+
+      // Remember that this will be used to construct the result object 
+      static std::wstring extract(PyObject* intermediate)
+      {
+          std::wstring result(::PyObject_Length(intermediate), L' ');
+          if (!result.empty())
+          {
+              int err = PyUnicode_AsWideChar(
+#if PY_VERSION_HEX < 0x03020000
+                  (PyUnicodeObject *)
+#endif
+                    intermediate
+                , &result[0]
+                , result.size());
+
+              if (err == -1)
+                  throw_error_already_set();
+          }
+          return result;
+      }
+      static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
+  };
+#endif 
+
+  struct complex_rvalue_from_python
+  {
+      static unaryfunc* get_slot(PyObject* obj)
+      {
+          if (PyComplex_Check(obj))
+              return &py_object_identity;
+          else
+              return float_rvalue_from_python::get_slot(obj);
+      }
+      
+      static std::complex<double> extract(PyObject* intermediate)
+      {
+          if (PyComplex_Check(intermediate))
+          {
+              return std::complex<double>(
+                  PyComplex_RealAsDouble(intermediate)
+                  , PyComplex_ImagAsDouble(intermediate));
+          }
+#if PY_VERSION_HEX < 0x03000000
+          else if (PyInt_Check(intermediate))
+          {
+              return PyInt_AS_LONG(intermediate);
+          }
+#endif
+          else
+          {
+              return PyFloat_AS_DOUBLE(intermediate);
+          }
+      }
+      static PyTypeObject const* get_pytype() { return &PyComplex_Type;}
+  };
+} 
+
+BOOST_PYTHON_DECL PyObject* do_return_to_python(char x)
+{
+#if PY_VERSION_HEX >= 0x03000000
+    return PyUnicode_FromStringAndSize(&x, 1);
+#else
+    return PyString_FromStringAndSize(&x, 1);
+#endif
+}
+  
+BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x)
+{
+#if PY_VERSION_HEX >= 0x03000000
+    return x ? PyUnicode_FromString(x) : boost::python::detail::none();
+#else
+    return x ? PyString_FromString(x) : boost::python::detail::none();
+#endif
+}
+  
+BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject* x)
+{
+    return x ? x : boost::python::detail::none();
+}
+  
+BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject* x)
+{
+    if (x == 0)
+        return boost::python::detail::none();
+      
+    Py_INCREF(x);
+    return x;
+}
+
+#define REGISTER_INT_CONVERTERS(signedness, U)                          \
+        slot_rvalue_from_python<                                        \
+                signedness U                                            \
+                ,signedness##_int_rvalue_from_python<signedness U>      \
+         >()
+
+#define REGISTER_INT_CONVERTERS2(U)             \
+        REGISTER_INT_CONVERTERS(signed, U);     \
+        REGISTER_INT_CONVERTERS(unsigned, U)  
+
+void initialize_builtin_converters()
+{
+    // booleans
+    slot_rvalue_from_python<bool,bool_rvalue_from_python>();
+
+    // integer types
+    REGISTER_INT_CONVERTERS2(char);
+    REGISTER_INT_CONVERTERS2(short);
+    REGISTER_INT_CONVERTERS2(int);
+    REGISTER_INT_CONVERTERS2(long);
+    
+// using Python's macro instead of Boost's - we don't seem to get the
+// config right all the time.
+# ifdef HAVE_LONG_LONG
+    slot_rvalue_from_python<signed BOOST_PYTHON_LONG_LONG,long_long_rvalue_from_python>();
+    slot_rvalue_from_python<unsigned BOOST_PYTHON_LONG_LONG,unsigned_long_long_rvalue_from_python>();
+# endif
+        
+    // floating types
+    slot_rvalue_from_python<float,float_rvalue_from_python>();
+    slot_rvalue_from_python<double,float_rvalue_from_python>();
+    slot_rvalue_from_python<long double,float_rvalue_from_python>();
+    
+    slot_rvalue_from_python<std::complex<float>,complex_rvalue_from_python>();
+    slot_rvalue_from_python<std::complex<double>,complex_rvalue_from_python>();
+    slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
+    
+    // Add an lvalue converter for char which gets us char const*
+#if PY_VERSION_HEX < 0x03000000
+    registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
+#else
+    registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyUnicode_Type>::get_pytype);
+#endif
+
+    // Register by-value converters to std::string, std::wstring
+#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
+    slot_rvalue_from_python<std::wstring, wstring_rvalue_from_python>();
+# endif 
+    slot_rvalue_from_python<std::string, string_rvalue_from_python>();
+
+}
+
+}}} // namespace boost::python::converter

File PolyPython/include/converter/from_python.cpp

View file
  • Ignore whitespace
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/converter/from_python.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/converter/rvalue_from_python_data.hpp>
+
+#include <boost/python/object/find_instance.hpp>
+
+#include <boost/python/handle.hpp>
+#include <boost/python/detail/raw_pyobject.hpp>
+#include <boost/python/cast.hpp>
+
+#include <vector>
+#include <algorithm>
+
+namespace boost { namespace python { namespace converter { 
+
+// rvalue_from_python_stage1 -- do the first stage of a conversion
+// from a Python object to a C++ rvalue.
+//
+//    source     - the Python object to be converted
+//    converters - the registry entry for the target type T
+//
+// Postcondition: where x is the result, one of:
+//
+//   1. x.convertible == 0, indicating failure
+//
+//   2. x.construct == 0, x.convertible is the address of an object of
+//      type T. Indicates a successful lvalue conversion
+//
+//   3. where y is of type rvalue_from_python_data<T>,
+//      x.construct(source, y) constructs an object of type T
+//      in y.storage.bytes and then sets y.convertible == y.storage.bytes,
+//      or else throws an exception and has no effect.
+BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
+    PyObject* source
+    , registration const& converters)
+{
+    rvalue_from_python_stage1_data data;
+
+    // First check to see if it's embedded in an extension class
+    // instance, as a special case.
+    data.convertible = objects::find_instance_impl(source, converters.target_type, converters.is_shared_ptr);
+        data.construct = 0;
+    if (!data.convertible)
+    {
+        for (rvalue_from_python_chain const* chain = converters.rvalue_chain;
+             chain != 0;
+             chain = chain->next)
+        {
+            void* r = chain->convertible(source);
+            if (r != 0)
+            {
+                data.convertible = r;
+                data.construct = chain->construct;
+                break;
+            }
+        }
+    }
+    return data;
+}
+
+// rvalue_result_from_python -- return the address of a C++ object which
+// can be used as the result of calling a Python function.
+//
+//      src  - the Python object to be converted
+//
+//      data - a reference to the base part of a
+//             rvalue_from_python_data<T> object, where T is the
+//             target type of the conversion.
+//
+// Requires: data.convertible == &registered<T>::converters
+//
+BOOST_PYTHON_DECL void* rvalue_result_from_python(
+    PyObject* src, rvalue_from_python_stage1_data& data)
+{
+    // Retrieve the registration
+    // Cast in two steps for less-capable compilers
+    void const* converters_ = data.convertible;
+    registration const& converters = *static_cast<registration const*>(converters_);
+
+    // Look for an eligible converter
+    data = rvalue_from_python_stage1(src, converters);
+    return rvalue_from_python_stage2(src, data, converters);
+}
+
+BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
+    PyObject* source, rvalue_from_python_stage1_data& data, registration const& converters)
+{
+    if (!data.convertible)
+    {
+        handle<> msg(
+#if PY_VERSION_HEX >= 0x03000000
+            ::PyUnicode_FromFormat
+#else
+            ::PyString_FromFormat
+#endif
+                (
+                "No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s"
+                , converters.target_type.name()
+                , source->ob_type->tp_name
+                ));
+              
+        PyErr_SetObject(PyExc_TypeError, msg.get());
+        throw_error_already_set();
+    }
+
+    // If a construct function was registered (i.e. we found an
+    // rvalue conversion), call it now.
+    if (data.construct != 0)
+        data.construct(source, &data);
+
+    // Return the address of the resulting C++ object
+    return data.convertible;
+}
+
+BOOST_PYTHON_DECL void* get_lvalue_from_python(
+    PyObject* source
+    , registration const& converters)
+{
+    // Check to see if it's embedded in a class instance
+    void* x = objects::find_instance_impl(source, converters.target_type);
+    if (x)
+        return x;
+
+    lvalue_from_python_chain const* chain = converters.lvalue_chain;
+    for (;chain != 0; chain = chain->next)
+    {
+        void* r = chain->convert(source);
+        if (r != 0)
+            return r;
+    }
+    return 0;
+}
+
+namespace
+{
+  // Prevent looping in implicit conversions. This could/should be
+  // much more efficient, but will work for now.
+  typedef std::vector<rvalue_from_python_chain const*> visited_t;
+  static visited_t visited;
+
+  inline bool visit(rvalue_from_python_chain const* chain)
+  {
+      visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain);
+      if (p != visited.end() && *p == chain)
+          return false;
+      visited.insert(p, chain);
+      return true;
+  }
+
+  // RAII class for managing global visited marks.
+  struct unvisit
+  {
+      unvisit(rvalue_from_python_chain const* chain)
+          : chain(chain) {}
+      
+      ~unvisit()
+      {
+          visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain);
+          assert(p != visited.end());
+          visited.erase(p);
+      }
+   private:
+      rvalue_from_python_chain const* chain;
+  };
+}
+
+
+BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python(
+    PyObject* source
+    , registration const& converters)
+{    
+    if (objects::find_instance_impl(source, converters.target_type))
+        return true;
+    
+    rvalue_from_python_chain const* chain = converters.rvalue_chain;
+    
+    if (!visit(chain))
+        return false;
+
+    unvisit protect(chain);
+    
+    for (;chain != 0; chain = chain->next)
+    {
+        if (chain->convertible(source))
+            return true;
+    }
+
+    return false;
+}
+
+namespace
+{
+  void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type)
+  {
+      handle<> msg(
+#if PY_VERSION_HEX >= 0x03000000
+          ::PyUnicode_FromFormat
+#else
+          ::PyString_FromFormat
+#endif
+              (
+              "No registered converter was able to extract a C++ %s to type %s"
+              " from this Python object of type %s"
+              , ref_type
+              , converters.target_type.name()
+              , source->ob_type->tp_name
+              ));
+              
+      PyErr_SetObject(PyExc_TypeError, msg.get());
+
+      throw_error_already_set();
+  }
+
+  void* lvalue_result_from_python(
+      PyObject* source
+      , registration const& converters
+      , char const* ref_type)
+  {
+      handle<> holder(source);
+      if (source->ob_refcnt <= 1)
+      {
+          handle<> msg(
+#if PY_VERSION_HEX >= 0x3000000
+              ::PyUnicode_FromFormat
+#else
+              ::PyString_FromFormat
+#endif
+                  (
+                  "Attempt to return dangling %s to object of type: %s"
+                  , ref_type
+                  , converters.target_type.name()));
+          
+          PyErr_SetObject(PyExc_ReferenceError, msg.get());
+
+          throw_error_already_set();
+      }
+      
+      void* result = get_lvalue_from_python(source, converters);
+      if (!result)
+          (throw_no_lvalue_from_python)(source, converters, ref_type);
+      return result;
+  }
+  
+}
+
+BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject* source, registration const& converters)
+{
+    (throw_no_lvalue_from_python)(source, converters, "pointer");
+}
+
+BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject* source, registration const& converters)
+{
+    (throw_no_lvalue_from_python)(source, converters, "reference");
+}
+
+BOOST_PYTHON_DECL void* reference_result_from_python(
+    PyObject* source
+    , registration const& converters)
+{
+    return (lvalue_result_from_python)(source, converters, "reference");
+}
+  
+BOOST_PYTHON_DECL void* pointer_result_from_python(
+    PyObject* source
+    , registration const& converters)
+{
+    if (source == Py_None)
+    {
+        Py_DECREF(source);
+        return 0;
+    }
+    return (lvalue_result_from_python)(source, converters, "pointer");
+}
+  
+BOOST_PYTHON_DECL void void_result_from_python(PyObject* o)
+{
+    Py_DECREF(expect_non_null(o));
+}
+
+} // namespace boost::python::converter
+
+BOOST_PYTHON_DECL PyObject*
+pytype_check(PyTypeObject* type_, PyObject* source)
+{
+    if (!PyObject_IsInstance(source, python::upcast<PyObject>(type_)))
+    {
+        ::PyErr_Format(
+            PyExc_TypeError
+            , "Expecting an object of type %s; got an object of type %s instead"
+            , type_->tp_name
+            , source->ob_type->tp_name
+            );
+        throw_error_already_set();
+    }
+    return source;
+}
+
+}} // namespace boost::python

File PolyPython/include/converter/registry.cpp

View file
  • Ignore whitespace
+//  Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/converter/registry.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/converter/builtin_converters.hpp>
+
+#include <set>
+#include <stdexcept>
+
+#if defined(__APPLE__) && defined(__MACH__) && defined(__GNUC__) \
+ && __GNUC__ == 3 && __GNUC_MINOR__ <= 4 && !defined(__APPLE_CC__)
+# define BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
+#endif
+
+#if defined(BOOST_PYTHON_TRACE_REGISTRY) \
+ || defined(BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND)
+# include <iostream>
+#endif
+
+namespace boost { namespace python { namespace converter { 
+BOOST_PYTHON_DECL PyTypeObject const* registration::expected_from_python_type() const
+{
+    if (this->m_class_object != 0)
+        return this->m_class_object;
+
+    std::set<PyTypeObject const*> pool;
+
+    for(rvalue_from_python_chain* r = rvalue_chain; r ; r=r->next)
+        if(r->expected_pytype)
+            pool.insert(r->expected_pytype());
+
+    //for now I skip the search for common base
+    if (pool.size()==1)
+        return *pool.begin();
+
+    return 0;
+
+}
+
+BOOST_PYTHON_DECL PyTypeObject const* registration::to_python_target_type() const
+{
+    if (this->m_class_object != 0)
+        return this->m_class_object;
+
+    if (this->m_to_python_target_type != 0)
+        return this->m_to_python_target_type();
+
+    return 0;
+}
+
+BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
+{
+    if (this->m_class_object == 0)
+    {
+        ::PyErr_Format(
+            PyExc_TypeError
+            , const_cast<char*>("No Python class registered for C++ class %s")
+            , this->target_type.name());
+    
+        throw_error_already_set();
+    }
+    
+    return this->m_class_object;
+}
+  
+BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source) const
+{
+    if (this->m_to_python == 0)
+    {
+        handle<> msg(
+#if PY_VERSION_HEX >= 0x3000000
+            ::PyUnicode_FromFormat
+#else
+            ::PyString_FromFormat
+#endif
+            (
+                "No to_python (by-value) converter found for C++ type: %s"
+                , this->target_type.name()
+                )
+            );
+            
+        PyErr_SetObject(PyExc_TypeError, msg.get());
+
+        throw_error_already_set();
+    }
+        
+    return source == 0
+        ? incref(Py_None)
+        : this->m_to_python(const_cast<void*>(source));
+}
+
+namespace
+{
+  template< typename T >
+  void delete_node( T* node )
+  {
+      if( !!node && !!node->next )
+          delete_node( node->next );
+      delete node;
+  }
+}
+
+registration::~registration()
+{
+  delete_node(lvalue_chain);
+  delete_node(rvalue_chain);
+}
+
+
+namespace // <unnamed>
+{
+  typedef registration entry;
+  
+  typedef std::set<entry> registry_t;
+  
+#ifndef BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
+  registry_t& entries()
+  {
+      static registry_t registry;
+
+# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
+      static bool builtin_converters_initialized = false;
+      if (!builtin_converters_initialized)
+      {
+          // Make this true early because registering the builtin
+          // converters will cause recursion.
+          builtin_converters_initialized = true;
+          
+          initialize_builtin_converters();
+      }
+#  ifdef BOOST_PYTHON_TRACE_REGISTRY
+      std::cout << "registry: ";
+      for (registry_t::iterator p = registry.begin(); p != registry.end(); ++p)
+      {
+          std::cout << p->target_type << "; ";
+      }
+      std::cout << '\n';
+#  endif 
+# endif 
+      return registry;
+  }
+#else
+  registry_t& static_registry()
+  {
+    static registry_t result;
+    return result;
+  }
+
+  bool static_builtin_converters_initialized()
+  {
+    static bool result = false;
+    if (result == false) {
+      result = true;
+      std::cout << std::flush;
+      return false;
+    }
+    return true;
+  }
+
+  registry_t& entries()
+  {
+# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
+      if (!static_builtin_converters_initialized())
+      {
+          initialize_builtin_converters();
+      }
+#  ifdef BOOST_PYTHON_TRACE_REGISTRY
+      std::cout << "registry: ";
+      for (registry_t::iterator p = static_registry().begin(); p != static_registry().end(); ++p)
+      {
+          std::cout << p->target_type << "; ";
+      }
+      std::cout << '\n';
+#  endif 
+# endif 
+      return static_registry();
+  }
+#endif // BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
+
+  entry* get(type_info type, bool is_shared_ptr = false)
+  {
+#  ifdef BOOST_PYTHON_TRACE_REGISTRY
+      registry_t::iterator p = entries().find(entry(type));
+      
+      std::cout << "looking up " << type << ": "
+                << (p == entries().end() || p->target_type != type
+                    ? "...NOT found\n" : "...found\n");
+#  endif
+      std::pair<registry_t::const_iterator,bool> pos_ins
+          = entries().insert(entry(type,is_shared_ptr));
+      
+#  if __MWERKS__ >= 0x3000
+      // do a little invariant checking if a change was made
+      if ( pos_ins.second )
+          assert(entries().invariants());
+#  endif
+      return const_cast<entry*>(&*pos_ins.first);
+  }
+} // namespace <unnamed>
+
+namespace registry
+{
+  void insert(to_python_function_t f, type_info source_t, PyTypeObject const* (*to_python_target_type)())
+  {
+#  ifdef BOOST_PYTHON_TRACE_REGISTRY
+      std::cout << "inserting to_python " << source_t << "\n";
+#  endif 
+      entry* slot = get(source_t);
+      
+      assert(slot->m_to_python == 0); // we have a problem otherwise
+      if (slot->m_to_python != 0)
+      {
+          std::string msg = (
+              std::string("to-Python converter for ")
+              + source_t.name()
+              + " already registered; second conversion method ignored."
+          );
+          
+          if ( ::PyErr_Warn( NULL, const_cast<char*>(msg.c_str()) ) )
+          {
+              throw_error_already_set();
+          }
+      }
+      slot->m_to_python = f;
+      slot->m_to_python_target_type = to_python_target_type;
+  }
+
+  // Insert an lvalue from_python converter
+  void insert(convertible_function convert, type_info key, PyTypeObject const* (*exp_pytype)())
+  {
+#  ifdef BOOST_PYTHON_TRACE_REGISTRY
+      std::cout << "inserting lvalue from_python " << key << "\n";
+#  endif 
+      entry* found = get(key);
+      lvalue_from_python_chain *registration = new lvalue_from_python_chain;
+      registration->convert = convert;
+      registration->next = found->lvalue_chain;
+      found->lvalue_chain = registration;
+      
+      insert(convert, 0, key,exp_pytype);
+  }
+
+  // Insert an rvalue from_python converter
+  void insert(convertible_function convertible
+              , constructor_function construct
+              , type_info key