Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Binding/Sofa.Core] Call init() by default when creating a python object #173

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
3fd97b2
[SofaPython3] Call init() by default when creating a python object.
damienmarchal Sep 10, 2021
bca1050
[Bindings/Sofa] Add Sofa.__futurefeatures__
damienmarchal Sep 15, 2021
df6792b
[SofaPython3/Config] Add a mechanism to activate/deactivate futurefea…
damienmarchal Sep 15, 2021
aa8f506
[SofaPython3/Plugin] Restore the reloading of plugins.
damienmarchal Sep 15, 2021
13c7cba
[bindings/Sofa.Config] Refactor & add contextmanager for Sofa.future.…
damienmarchal Sep 15, 2021
e9db9fb
[Bindings/Sofa] Add Sofa.__futurefeatures__
damienmarchal Sep 15, 2021
57c2a30
[SofaPython3/Config] Add a mechanism to activate/deactivate futurefea…
damienmarchal Sep 15, 2021
0912787
[Bindings/Sofa.Config] Add has_feature in future.py
damienmarchal Sep 15, 2021
0ccd57d
Merge remote-tracking branch 'cristal/pr-add-future-feature' into pr-…
damienmarchal Sep 15, 2021
72cbea0
Merge remote-tracking branch 'upstream/master' into pr-add-future-fea…
damienmarchal Sep 17, 2021
5a409e6
Merge remote-tracking branch 'upstream/master' into pr-add-no-init-be…
damienmarchal Sep 17, 2021
d0111c0
Merge remote-tracking branch 'cristal/pr-add-future-feature' into pr-…
damienmarchal Sep 17, 2021
6c4d234
Merge remote-tracking branch 'upstream/master' into pr-add-future-fea…
damienmarchal Sep 27, 2021
2e994ae
[all] Rename the introduced feature Sofa.Config.future into Sofa.Life…
damienmarchal Sep 27, 2021
e8c7b2f
Merge remote-tracking branch 'upstream/master' into pr-add-no-init-be…
damienmarchal Sep 27, 2021
f844484
Merge remote-tracking branch 'cristal/pr-add-future-feature' into pr-…
damienmarchal Sep 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ if (NOT SP3_COMPILED_AS_SUBPROJECT)
message(STATUS "SOFA Framework:\n\tVersion: ${SofaFramework_VERSION}\n\tLocation: ${SOFA_ROOT_DIR}")
endif()

add_subdirectory(Lifetime)
add_subdirectory(Plugin)
add_subdirectory(bindings)
add_subdirectory(examples)
Expand Down
27 changes: 27 additions & 0 deletions Lifetime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
project(Lifetime VERSION 1.0)

set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/src/SofaPython3/lifetime/features.h
)

set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/src/SofaPython3/lifetime/features.cpp
)

find_package(SofaFramework REQUIRED)

add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES})
add_library(SofaPython3::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

target_link_libraries(${PROJECT_NAME} PUBLIC SofaCore)

sofa_create_component_in_package_with_targets(
COMPONENT_NAME ${PROJECT_NAME}
COMPONENT_VERSION ${SofaPython3_VERSION}
PACKAGE_NAME SofaPython3
TARGETS ${PROJECT_NAME} AUTO_SET_TARGET_PROPERTIES
INCLUDE_SOURCE_DIR "src"
INCLUDE_INSTALL_DIR "."
OPTIMIZE_BUILD_DIR FALSE
RELOCATABLE ".."
)
22 changes: 22 additions & 0 deletions Lifetime/LifetimeConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# CMake package configuration file for the @PROJECT_NAME@ module
@PACKAGE_GUARD@
@PACKAGE_INIT@

set(SP3_BUILD_TEST @SP3_BUILD_TEST@)

find_package(pybind11 CONFIG REQUIRED)
find_package(SofaFramework REQUIRED)
find_package(SofaSimulationGraph REQUIRED)

if(SP3_BUILD_TEST)
find_package(Sofa.Testing REQUIRED)
endif()

# If we are importing this config file and the target is not yet there this is indicating that
# target is an imported one. So we include it
if(NOT TARGET @PROJECT_NAME@)
include("${CMAKE_CURRENT_LIST_DIR}/PluginTargets.cmake")
endif()

# Check that the component/target is there.
check_required_components(@PROJECT_NAME@)
62 changes: 62 additions & 0 deletions Lifetime/src/SofaPython3/lifetime/features.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/******************************************************************************
* SofaPython3 plugin *
* (c) 2021 CNRS, University of Lille, INRIA *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Contact information: [email protected] *
******************************************************************************/
#include <iostream>
#include <map>
#include <stdexcept>
#include <SofaPython3/lifetime/features.h>

namespace sofapython3::lifetime::features
{

std::map<std::string, bool> features;

bool get(const std::string& name)
{
auto f = features.find(name);
if(f == features.end())
throw std::runtime_error("Missing attribute '"+name+"'");

return (f->second);
}

void set(const std::string& name, bool value)
{
auto f = features.find(name);
if(f == features.end())
throw std::runtime_error("Missing attribute '"+name+"'");

(f->second) = value;
}

void init(const std::string& name, bool value)
{
features[name] = value;
}


std::vector<std::string> list_features()
{
std::vector<std::string> v;
for(auto& it : features)
v.push_back(it.first);
return v;
}

} //namespace sofapython3::futurefeatures
43 changes: 43 additions & 0 deletions Lifetime/src/SofaPython3/lifetime/features.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/******************************************************************************
* SofaPython3 plugin *
* (c) 2021 CNRS, University of Lille, INRIA *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Contact information: [email protected] *
******************************************************************************/
#pragma once

#include <sofa/config.h>
#include <string>
#include <vector>

namespace sofapython3::lifetime::features
{

/// Retrieve the value associated with the feature "name"
/// raise an exception if "name" is not existing.
SOFA_EXPORT_DYNAMIC_LIBRARY bool get(const std::string& name);

/// Change the value associated with the feature "name"
/// raise an exception if "name" is not existing.
SOFA_EXPORT_DYNAMIC_LIBRARY void set(const std::string& name, bool value);

/// Create and set a new value for feature with "name"
SOFA_EXPORT_DYNAMIC_LIBRARY void init(const std::string& name, bool value);

/// Returns the list of registered features names
SOFA_EXPORT_DYNAMIC_LIBRARY std::vector<std::string> list_features();

} ///namespace sofapython3::futurefeatures
5 changes: 2 additions & 3 deletions Plugin/src/SofaPython3/PythonEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,16 @@ void PythonEnvironment::Init()
// Lastly, we (try to) add modules from the root of SOFA
addPythonModulePathsFromDirectory( Utils::getSofaPathPrefix() );

py::module::import("SofaRuntime");
getStaticData()->m_sofamodule = py::module::import("Sofa");

PyRun_SimpleString("import SofaRuntime");

// python livecoding related
PyRun_SimpleString("from Sofa.livecoding import onReimpAFile");

// general sofa-python stuff

// python modules are automatically reloaded at each scene loading
//setAutomaticModuleReload( true );
setAutomaticModuleReload( true );

// Initialize pluginLibraryPath by reading PluginManager's map
std::map<std::string, Plugin>& map = PluginManager::getInstance().getPluginMap();
Expand Down
1 change: 1 addition & 0 deletions bindings/Sofa/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
project(Bindings.Sofa)

set(SOFABINDINGS_MODULE_LIST
Lifetime
Components
Core
Helper
Expand Down
6 changes: 3 additions & 3 deletions bindings/Sofa/package/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@
import Sofa.constants
import Sofa.Helper
import Sofa.Core
import Sofa.Lifetime
import Sofa.Simulation
import Sofa.Types
import Sofa.Components
import SofaTypes

from .prefab import *
from .lifetime import __feature__

__all__=["constants", "Helper", "Core", "Simulation", "Types", "SofaTypes", "prefab"]
__all__=["constants", "Helper", "Core", "Simulation", "Types", "SofaTypes", "prefab", "future"]

# Keep a list of the modules always imported in the Sofa-PythonEnvironment
try:
Expand All @@ -56,7 +57,6 @@
# e.g. plugin's modules defined from c++
__SofaPythonEnvironment_modulesExcludedFromReload = []


def unloadModules():
""" call this function to unload python modules and to force their reload
(useful to take into account their eventual modifications since
Expand Down
46 changes: 46 additions & 0 deletions bindings/Sofa/package/lifetime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Activate/deactive some feature of sofa python

Use that to control how some part of the binding should behave.

Usage:
from Sofa.Lifetime import __feature__

with __feature__("feature_name", True):
do_something()

with __feature__("feature_name", False):
do_something()
"""
import Sofa.Lifetime
from contextlib import ContextDecorator

### Initialize the feature set.
# Add your own feature by un-commenting the following line
#Sofa.Lifetime.init("my_feature", False)
Sofa.Lifetime.init("object_auto_init", False)

def has_feature(name):
return Sofa.Lifetime.get(name)

def list_features():
return Sofa.Lifetime.list_features()

class __feature__(ContextDecorator):
@staticmethod
def list_features():
return self.Config.list_feature()

def __init__(self, name, value):
self.name=name
self.new_value=value
self.old_value=None

def __enter__(self):
self.old_value=Sofa.Config.get(self.name)
Sofa.Lifetime.set(self.name, self.new_value)
return self

def __exit__(self, *exc):
Sofa.Lifetime.set(self.name, self.old_value)
return False
21 changes: 17 additions & 4 deletions bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
* Contact information: [email protected] *
******************************************************************************/


/// Neede to have automatic conversion from pybind types to stl container.
#include <pybind11/stl.h>
#include <pybind11/eval.h>
Expand Down Expand Up @@ -53,18 +52,21 @@ using sofapython3::PythonEnvironment;
#include <SofaPython3/Sofa/Core/Binding_Node_doc.h>
#include <SofaPython3/Sofa/Core/Binding_NodeIterator.h>
#include <SofaPython3/Sofa/Core/Binding_PythonScriptEvent.h>

using sofa::core::objectmodel::BaseObjectDescription;

#include <queue>
#include <sofa/core/objectmodel/Link.h>

#include <SofaPython3/lifetime/features.h>

#include <pybind11/eval.h>

/// Makes an alias for the pybind11 namespace to increase readability.
namespace py { using namespace pybind11; }

using sofa::simulation::Node;

namespace sofapython3 {
namespace sofapython3
{

bool checkParamUsage(BaseObjectDescription& desc)
{
Expand Down Expand Up @@ -186,12 +188,18 @@ py::object getObject(Node &n, const std::string &name, const py::kwargs& kwargs)
/// Implement the addObject function.
py::object addObjectKwargs(Node* self, const std::string& type, const py::kwargs& kwargs)
{
bool doInit = true;
if (kwargs.contains("name"))
{
std::string name = py::str(kwargs["name"]);
if (sofapython3::isProtectedKeyword(name))
throw py::value_error("Cannot call addObject with name " + name + ": Protected keyword");
}
if (kwargs.contains("__noInit"))
{
doInit = !py::bool_(kwargs["__noInit"]);
kwargs.attr("pop")("__noInit");
}
/// Prepare the description to hold the different python attributes as data field's
/// arguments then create the object.
BaseObjectDescription desc {type.c_str(), type.c_str()};
Expand Down Expand Up @@ -226,6 +234,11 @@ py::object addObjectKwargs(Node* self, const std::string& type, const py::kwargs
if(d)
d->setPersistent(true);
}

if(doInit && sofapython3::lifetime::features::get("object_auto_init"))
{
object->init();
}
return PythonFactory::toPython(object.get());
}

Expand Down
2 changes: 1 addition & 1 deletion bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,5 @@ SP3_add_python_module(
DESTINATION Sofa
SOURCES ${SOURCE_FILES}
HEADERS ${HEADER_FILES}
DEPENDS SofaBaseUtils SofaBaseCollision SofaCore SofaHelper SofaSimulationCore SofaDefaultType SofaBaseVisual SofaPython3::Plugin
DEPENDS SofaBaseUtils SofaBaseCollision SofaCore SofaHelper SofaSimulationCore SofaDefaultType SofaBaseVisual SofaPython3::Lifetime SofaPython3::Plugin
)
26 changes: 26 additions & 0 deletions bindings/Sofa/src/SofaPython3/Sofa/Lifetime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
project(Bindings.Sofa.Lifetime)

set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Lifetime.cpp
)

if (NOT TARGET SofaPython3::Plugin)
find_package(SofaPython3 REQUIRED)
endif()

find_package(Sofa.Config REQUIRED)
find_package(SofaFramework REQUIRED)
find_package(SofaBaseCollision REQUIRED)
find_package(SofaBaseVisual REQUIRED)
find_package(SofaBaseUtils REQUIRED)

SP3_add_python_module(
TARGET ${PROJECT_NAME}
PACKAGE Bindings
MODULE Lifetime
DESTINATION Sofa
SOURCES ${SOURCE_FILES}
HEADERS ${HEADER_FILES}
DEPENDS Sofa.Config SofaBaseUtils SofaBaseCollision SofaCore SofaHelper SofaSimulationCore SofaDefaultType SofaBaseVisual SofaPython3::Lifetime SofaPython3::Plugin
)

Loading