← Back to team overview

yade-dev team mailing list archive

[svn] r1674 - in trunk: core gui/py lib/factory pkg/common/Engine/StandAloneEngine pkg/common/RenderingEngine/OpenGLRenderingEngine

 

Author: eudoxos
Date: 2009-02-20 23:56:45 +0100 (Fri, 20 Feb 2009)
New Revision: 1674

Modified:
   trunk/core/GeometricalModel.hpp
   trunk/core/MetaBody.hpp
   trunk/core/Omega.cpp
   trunk/core/Omega.hpp
   trunk/gui/py/PythonUI.cpp
   trunk/lib/factory/ClassFactory.cpp
   trunk/lib/factory/ClassFactory.hpp
   trunk/lib/factory/DynLibManager.cpp
   trunk/lib/factory/DynLibManager.hpp
   trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp
   trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.hpp
   trunk/pkg/common/Engine/StandAloneEngine/PersistentTriangulationCollider.cpp
   trunk/pkg/common/Engine/StandAloneEngine/PersistentTriangulationCollider.hpp
   trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.cpp
Log:
1. removed persistentInteraction from most places; they are still present in MetaBody, but not serialized any more, most importantly (avoids warnings) and not GL-drawn.
2. Plugin loading loginc completely changes, the underlying macro YADE_PLUGIN has still the same interface. We used __attribute__((constructor)), __attribute__((visibility("internal"))) and anonymous namespace magic to get there. This will make it possible to put multiple plugins to a single shared library without touching the source, only fiddling with SConscript's.
3. PythonUI is interactive by default (it was not?? weird.)


Modified: trunk/core/GeometricalModel.hpp
===================================================================
--- trunk/core/GeometricalModel.hpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/core/GeometricalModel.hpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -9,7 +9,7 @@
 #pragma once
 
 #include<yade/lib-base/yadeWm3Extra.hpp>
-#include <Wm3Vector3.h>
+#include<Wm3Vector3.h>
 #include<yade/lib-base/yadeWm3.hpp>
 #include<yade/lib-serialization/Serializable.hpp>
 #include<yade/lib-multimethods/Indexable.hpp>

Modified: trunk/core/MetaBody.hpp
===================================================================
--- trunk/core/MetaBody.hpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/core/MetaBody.hpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -57,7 +57,6 @@
 		(initializers)
 		(bodies)
 		(transientInteractions)
-		(persistentInteractions)
 		(physicalActions)
 		(miscParams)
 		(dispParams)

Modified: trunk/core/Omega.cpp
===================================================================
--- trunk/core/Omega.cpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/core/Omega.cpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -164,8 +164,7 @@
 	return (dynlibs[className].baseClasses.find(baseClassName)!=dynlibs[className].baseClasses.end());
 }
 
-void Omega::scanPlugins()
-{
+void Omega::scanPlugins(){
 	FOREACH(string dld,preferences->dynlibDirectories) ClassFactory::instance().addBaseDirectory(dld);
 	vector<string> dynlibsList;
 	FOREACH(string si, preferences->dynlibDirectories){
@@ -177,54 +176,28 @@
 			if (!filesystem::is_directory(*di) && filesystem::exists(*di) && filesystem::extension(*di)!=".a" &&
 				ClassFactory::instance().libNameToSystemName(ClassFactory::instance().systemNameToLibName(filesystem::basename(pth)))==(pth.leaf())){
 				filesystem::path name(filesystem::basename(pth));
-				// warning: this can produce invalid name (too short).
-				// 0-length names are dumped directly
-				// names 0<length<4 should fail assertion in DynLibManager::systemNameToLibName
-				// the whole loading "logic" should be rewritten from scratch...
 				if(name.leaf().length()<1) continue; // filter out 0-length filenames
-				if(dynlibsList.size()==0 || ClassFactory::instance().systemNameToLibName(name.leaf())!=dynlibsList.back()) {
-					LOG_DEBUG("Added plugin: "<<si<<"/"<<pth.leaf()<<".");
-					dynlibsList.push_back(ClassFactory::instance().systemNameToLibName(name.leaf()));
+				string plugin=name.leaf();
+				if(!ClassFactory::instance().load(ClassFactory::instance().systemNameToLibName(plugin))){
+					string err=ClassFactory::instance().lastError();
+					if(err.find(": undefined symbol: ")!=std::string::npos){
+						size_t pos=err.rfind(":");	assert(pos!=std::string::npos);
+						std::string sym(err,pos+2); //2 removes ": " from the beginning
+						int status=0; char* demangled_sym=abi::__cxa_demangle(sym.c_str(),0,0,&status);
+						LOG_FATAL(plugin<<": undefined symbol `"<<demangled_sym<<"'"); LOG_FATAL(plugin<<": "<<err); LOG_FATAL("Bailing out.");
+					}
+					else {
+						LOG_FATAL(plugin<<": "<<err<<" ."); /* leave space to not to confuse c++filt */ LOG_FATAL("Bailing out.");
+					}
+					abort();
 				}
-				else LOG_DEBUG("Possible plugin discarded: "<<si<<"/"<<name.leaf()<<".");
-			} else LOG_DEBUG("File not considered a plugin: "<<pth.leaf()<<".");
-		}
-	}
-
-	bool allLoaded = true;
-	vector<string> dynlibsClassList; // dynlibsList holds filenames, this holds classes defined inside (may be different if using yadePuginClasses)
-	FOREACH(string dll, dynlibsList){
-		bool thisLoaded = ClassFactory::instance().load(dll);
-		if (!thisLoaded){
-			string err=ClassFactory::instance().lastError();
-			// HACK
-			if(err.find("cannot open shared object file: No such file or directory")!=std::string::npos){
-				LOG_INFO("Attempted to load nonexistent file; since this may be due to bad algorithm of filename construction, we pretend everything is OK (original error: `"<<err<<"').");
-				thisLoaded=true;
 			}
-			else if(err.find(": undefined symbol: ")!=std::string::npos){
-				size_t pos=err.rfind(":");
-				assert(pos!=std::string::npos);
-				std::string sym(err,pos+2); //2 removes ": " from the beginning
-				int status=0;
-				char* demangled_sym=abi::__cxa_demangle(sym.c_str(),0,0,&status);
-				LOG_FATAL("Undefined symbol `"<<demangled_sym<<"' ("<<err<<").");
-			}
-			else LOG_ERROR("Error loading Library `"<<dll<<"': "<<err<<" ."); // leave space to not to confuse c++filt
+			else LOG_DEBUG("File not considered a plugin: "<<pth.leaf()<<".");
 		}
-		else { // no error
-			if (ClassFactory::instance().lastPluginClasses().size()==0){ // regular plugin, one class per file
-				dynlibsClassList.push_back(dll);
-				LOG_DEBUG("Plugin "<<dll<<": loaded default class "<<dll<<".");
-			} else {// if plugin defines yadePluginClasses (has multiple classes), insert these into dynLibsList
-				vector<string> css=ClassFactory::instance().lastPluginClasses();
-				for(size_t i=0; i<css.size();i++) { dynlibsClassList.push_back(css[i]); LOG_DEBUG("Plugin "<<dll<<": loaded explicit class "<<css[i]<<".");  }
-			}
-		}
-		allLoaded &= thisLoaded;
 	}
-	if(!allLoaded) { LOG_FATAL("Error loading a plugin (see above; run with -v to see more), bailing out."); abort(); }
-	buildDynlibDatabase(dynlibsClassList);
+	list<string>& plugins(ClassFactory::instance().pluginClasses);
+	plugins.sort(); plugins.unique();
+	buildDynlibDatabase(vector<string>(plugins.begin(),plugins.end()));
 }
 
 void Omega::loadSimulationFromStream(std::istream& stream){

Modified: trunk/core/Omega.hpp
===================================================================
--- trunk/core/Omega.hpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/core/Omega.hpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -80,6 +80,7 @@
 		ptime				 msStartingPauseTime;
 		time_duration			 simulationPauseDuration;
 		string				 simulationFileName;
+
 		void buildDynlibDatabase(const vector<string>& dynlibsList); // FIXME - maybe in ClassFactory ?
 
 		map<string,string> memSavedSimulations;

Modified: trunk/gui/py/PythonUI.cpp
===================================================================
--- trunk/gui/py/PythonUI.cpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/gui/py/PythonUI.cpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -15,7 +15,7 @@
 struct termios PythonUI::tios, PythonUI::tios_orig;
 string PythonUI::runScript;
 bool PythonUI::stopAfter=false;
-bool PythonUI::nonInteractive=true;
+bool PythonUI::nonInteractive=false;
 vector<string> PythonUI::scriptArgs;
 
 PythonUI* PythonUI::self=NULL;

Modified: trunk/lib/factory/ClassFactory.cpp
===================================================================
--- trunk/lib/factory/ClassFactory.cpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/lib/factory/ClassFactory.cpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -10,6 +10,8 @@
 
 #include "ClassFactory.hpp"
 
+#include<boost/algorithm/string/regex.hpp>
+
 CREATE_LOGGER(ClassFactory);
 
 class Factorable;
@@ -123,3 +125,21 @@
 	return dlm.systemNameToLibName(name);
 }
 
+
+void ClassFactory::registerPluginClasses(const char* fileAndClasses[]){
+	assert(fileAndClasses[0]!=NULL); // must be file name
+	// only filename given, no classes names explicitly
+	if(fileAndClasses[1]==NULL){
+		/* strip leading path (if any; using / as path separator) and strip one suffix (if any) to get the contained class name */
+		string heldClass=boost::algorithm::replace_regex_copy(string(fileAndClasses[0]),boost::regex("^(.*/)?(.*?)(\\.[^.]*)?$"),string("\\2"));
+		LOG_DEBUG("Plugin "<<fileAndClasses[0]<<", class "<<heldClass<<" (deduced)");
+		pluginClasses.push_back(heldClass); // last item with everything up to last / take off and .suffix strip
+	}
+	else {
+		for(int i=1; fileAndClasses[i]!=NULL; i++){
+			LOG_DEBUG("Plugin "<<fileAndClasses[0]<<", class "<<fileAndClasses[i]);
+			pluginClasses.push_back(fileAndClasses[i]);
+		}
+	}
+}
+

Modified: trunk/lib/factory/ClassFactory.hpp
===================================================================
--- trunk/lib/factory/ClassFactory.hpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/lib/factory/ClassFactory.hpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -11,9 +11,10 @@
 #pragma once
 
 
-#include <map>
-#include <string>
-#include <iostream>
+#include<map>
+#include<string>
+#include<list>
+#include<iostream>
 
 #ifndef  __GXX_EXPERIMENTAL_CXX0X__
 #	include<boost/shared_ptr.hpp>
@@ -141,8 +142,10 @@
 
 		bool load(const string& name);
 		std::string lastError();
-		vector<string> lastPluginClasses(){ return dlm.lastPluginClasses; }
 
+		void registerPluginClasses(const char* fileAndClasses[]);
+		list<string> pluginClasses;
+
 		string libNameToSystemName(const string& name);
 		string systemNameToLibName(const string& name);
 
@@ -155,3 +158,11 @@
 };
 
 
+/*! Macro defining what classes can be found in this plugin -- must always be used in the respective .cpp file. If left empty, filename will be used to deduce that.
+ *
+ * Note:
+ * 	1. Visibility must be set to "internal" (or "protected") so that other plugins' init will not shadow this one and all of them get properly executed.
+ * 	2. The function must be enclosed in its own anonymous namespace, otherwise there will be clashes (liker errors) if more files with YADE_PLUGIN are linked together.
+ */
+#define YADE_PLUGIN(...) namespace{ __attribute__((constructor)) __attribute__((visibility("internal"))) void registerThisPluginClasses(void){ const char* info[]={__FILE__ , ##__VA_ARGS__ , NULL}; ClassFactory::instance().registerPluginClasses(info);} }
+

Modified: trunk/lib/factory/DynLibManager.cpp
===================================================================
--- trunk/lib/factory/DynLibManager.cpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/lib/factory/DynLibManager.cpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -50,84 +50,31 @@
 }
 
 
-/*Factory DynLibManager::resolve(const string libName, const string symb )
-{
-	if (isLoaded(libName))
-	{
-		string tmpSymb;
-		tmpSymb = symb;
-		tmpSymb.push_back('_');
-		tmpSymb.append(libName);
-		
-		#ifdef WIN32
-			void * sym = (void*)GetProcAddress(handles[libName], tmpSymb);
-			if (sym==NULL)
-				error();
-			return (Factory)sym;
-		#else
-			void * sym = dlsym(handles[libName], tmpSymb.data());
-		
-			if (error())  
-				return NULL;
-			else
-				return (Factory)sym;
-		#endif
-	}
-	else
-	{
-		return NULL;
-	}
-}*/
-
-
 bool DynLibManager::loadFromDirectoryList (const string& libName )
 {
-	lastPluginClasses.clear();
-
 	if (libName.empty()) return false;
-
 	string libFileName = libNameToSystemName(libName);
-
 	string baseDir = findLibDir(libName);
-
 	string fullLibName;
 	if (baseDir.length()==0) return load(libFileName,libName);
 	else return load(baseDir+"/"+libFileName,libName);
-	
 }
 
 
 bool DynLibManager::load (const string& fullLibName, const string& libName )
 {
-	lastPluginClasses.clear();
-
 	if (libName.empty() || fullLibName.empty()){
 		LOG_ERROR("Empty filename for library `"<<libName<<"'.");
 		return false;
 	}
-	/*if(!filesystem::exists(fullLibName)){
-		LOG_ERROR("Trying to load library `"<<libName<<"' from nonexistent file `"<<fullLibName<<"'?! (still returning success)");
-		return true;
-	}*/
-
 #ifdef WIN32
 	if (isLoaded(libName)) return true;
 	HINSTANCE handle = LoadLibraryA(fullLibName.c_str());
 #else
 	void * handle = dlopen(fullLibName.data(), RTLD_NOW);
 #endif
-
 	if (!handle) return !error();
-
 	handles[libName] = handle;
-
-#ifndef WIN32
-	char**yadePluginClasses=(char**)dlsym(handle, "yadePluginClasses");
-	// errors are ignored, since definition of this sybol is optional
-	if(!dlerror()){ for(int i=0; yadePluginClasses[i]!=NULL && strlen(yadePluginClasses[i])>0; i++){
-		lastPluginClasses.push_back(yadePluginClasses[i]); LOG_DEBUG("Pushed back `"<<yadePluginClasses[i]<<"'."); }
-	}
-#endif
 	return true;
 }
 

Modified: trunk/lib/factory/DynLibManager.hpp
===================================================================
--- trunk/lib/factory/DynLibManager.hpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/lib/factory/DynLibManager.hpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -27,12 +27,7 @@
 
 using namespace std;
 
-/*! Macro defining what classes can be found in this plugin -- must always be used in the respective .cpp file.
 
-If left empty, filename will be used to deduce that.
-*/
-#define YADE_PLUGIN(...) const char* yadePluginClasses[]={ __VA_ARGS__ "", NULL };
-
 class DynLibManager 
 {
 	private :
@@ -62,7 +57,6 @@
 		string systemNameToLibName(const string& name);
 		string findLibDir(const string& name);
 		string lastError();
-		vector<string> lastPluginClasses;
 		DECLARE_LOGGER;
 
 	private :

Modified: trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -18,7 +18,6 @@
 
 PersistentSAPCollider::PersistentSAPCollider() : BroadInteractor()
 {
-	noTransientIfPersistentExists=false;
 	haveDistantTransient=false;
 
 	nbObjects=0;
@@ -185,7 +184,6 @@
 	const shared_ptr<Interaction>& interaction=transientInteractions->find(body_id_t(id1),body_id_t(id2));
 	bool found=(interaction!=0);//Bruno's Hack
 	// if there is persistent interaction, we will not create transient one!
-	bool foundPersistent = noTransientIfPersistentExists ? (persistentInteractions->find(body_id_t(id1),body_id_t(id2))!=0) : false;
 	
 	// test if the AABBs of the spheres number "id1" and "id2" are overlapping
 	int offset1=3*id1, offset2=3*id2;
@@ -205,7 +203,7 @@
 	// inserts the pair p=(id1,id2) if the two AABB overlaps and if p does not exists in the overlappingBB
 	//if((id1==0 && id2==1) || (id1==1 && id2==0)) LOG_DEBUG("Processing #0 #1");
 	//if(interaction&&!interaction->isReal){ LOG_DEBUG("Unreal interaction #"<<id1<<"=#"<<id2<<" (overlap="<<overlap<<", haveDistantTransient="<<haveDistantTransient<<")");}
-	if(overlap && !found && !foundPersistent){
+	if(overlap && !found){
 		//LOG_DEBUG("Creating interaction #"<<id1<<"=#"<<id2);
 		transientInteractions->insert(body_id_t(id1),body_id_t(id2));
 	}

Modified: trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.hpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.hpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -58,7 +58,6 @@
 		// collection of AABB that are in interaction
 		//protected : vector< set<unsigned int> > overlappingBB;
 		shared_ptr<InteractionContainer> transientInteractions;
-		shared_ptr<InteractionContainer> persistentInteractions;
 		/// upper right corner of the AABB of the objects =>  for spheres = center[i]-radius
 		vector<Real> maxima;
 
@@ -97,14 +96,11 @@
 		/// return true if BoundingVolume is in potential interaction
 		bool probeBoundingVolume(const BoundingVolume& bv);
 
-		//! When creating transient interaction, look first if a persistent link between the pair in question exists; in that case, skip it.
-		bool noTransientIfPersistentExists;
 		//! Don't break transient interaction once bodies don't overlap anymore; material law will be responsible for breaking it.
 		bool haveDistantTransient;
 
 		void registerAttributes(){
 			BroadInteractor::registerAttributes();
-			REGISTER_ATTRIBUTE(noTransientIfPersistentExists);
 			REGISTER_ATTRIBUTE(haveDistantTransient);
 		}
 

Modified: trunk/pkg/common/Engine/StandAloneEngine/PersistentTriangulationCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PersistentTriangulationCollider.cpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/pkg/common/Engine/StandAloneEngine/PersistentTriangulationCollider.cpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -117,8 +117,6 @@
 			// look if the pair (id1,id2) already exists in the overleppingBB collection
 			const shared_ptr<Interaction>& interaction=transientInteractions->find ( body_id_t ( id1 ),body_id_t ( id2 ) );
 			bool found= ( interaction!=0 );//Bruno's Hack
-			// if there is persistent interaction, we will not create transient one!
-			//bool foundPersistent = noTransientIfPersistentExists ? ( persistentInteractions->find ( body_id_t ( id1 ),body_id_t ( id2 ) ) !=0 ) : false;
 
 			// inserts the pair p=(id1,id2) if the two AABB overlaps and if p does not exists in the overlappingBB
 			if ( !found )

Modified: trunk/pkg/common/Engine/StandAloneEngine/PersistentTriangulationCollider.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PersistentTriangulationCollider.hpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/pkg/common/Engine/StandAloneEngine/PersistentTriangulationCollider.hpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -71,7 +71,6 @@
 		// collection of AABB that are in interaction
 		//protected : vector< set<unsigned int> > overlappingBB;
 		shared_ptr<InteractionContainer> transientInteractions;
-		shared_ptr<InteractionContainer> persistentInteractions;
 		/// upper right corner of the AABB of the objects =>  for spheres = center[i]-radius
 		vector<Real> maxima;
 

Modified: trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.cpp
===================================================================
--- trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.cpp	2009-02-20 19:21:34 UTC (rev 1673)
+++ trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.cpp	2009-02-20 22:56:45 UTC (rev 1674)
@@ -380,15 +380,6 @@
 
 void OpenGLRenderingEngine::renderInteractionGeometry(const shared_ptr<MetaBody>& rootBody){	
 	{
-		boost::mutex::scoped_lock lock(rootBody->persistentInteractions->drawloopmutex);
-		FOREACH(const shared_ptr<Interaction>& I, *rootBody->persistentInteractions){
-			if(!I->interactionGeometry) continue;
-			const shared_ptr<Body>& b1=Body::byId(I->getId1(),rootBody), b2=Body::byId(I->getId2(),rootBody);
-			if(!(b1->physicalParameters->isDisplayed||b2->physicalParameters->isDisplayed)) continue;
-			glPushMatrix(); interactionGeometryDispatcher(I->interactionGeometry,I,b1,b2,Interaction_wire); glPopMatrix();
-		}
-	}
-	{
 		boost::mutex::scoped_lock lock(rootBody->transientInteractions->drawloopmutex);
 		FOREACH(const shared_ptr<Interaction>& I, *rootBody->transientInteractions){
 			if(!I->interactionGeometry) continue;
@@ -402,15 +393,6 @@
 
 void OpenGLRenderingEngine::renderInteractionPhysics(const shared_ptr<MetaBody>& rootBody){	
 	{
-		boost::mutex::scoped_lock lock(rootBody->persistentInteractions->drawloopmutex);
-		FOREACH(const shared_ptr<Interaction>& I, *rootBody->persistentInteractions){
-			if(!I->interactionPhysics) continue;
-			const shared_ptr<Body>& b1=Body::byId(I->getId1(),rootBody), b2=Body::byId(I->getId2(),rootBody);
-			if(!(b1->physicalParameters->isDisplayed||b2->physicalParameters->isDisplayed)) continue;
-			glPushMatrix(); interactionPhysicsDispatcher(I->interactionPhysics,I,b1,b2,Interaction_wire); glPopMatrix();
-		}
-	}
-	{
 		boost::mutex::scoped_lock lock(rootBody->transientInteractions->drawloopmutex);
 		FOREACH(const shared_ptr<Interaction>& I, *rootBody->transientInteractions){
 			if(!I->interactionPhysics) continue;