yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #00989
[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;