[Debian-astro-commits] [gyoto] 192/221: + Add Gyoto::Object::get/set(std::string const &property_name ...) + Gyoto::Value::operator [unsigned] long() work also if the other type of long was set + Python: * bugfix: avoid segfault when outputting a NULL SmartPointer; * new typemaps around Gyoto::Value

Thibaut Jean-Claude Paumard thibaut at moszumanska.debian.org
Fri May 22 20:52:45 UTC 2015


This is an automated email from the git hooks/post-receive script.

thibaut pushed a commit to branch master
in repository gyoto.

commit da505ec0da17ad3dc8507dca3261819ed1d6c74d
Author: Thibaut Paumard <paumard at users.sourceforge.net>
Date:   Wed Jan 14 12:52:05 2015 +0100

    + Add Gyoto::Object::get/set(std::string const &property_name ...)
    + Gyoto::Value::operator [unsigned] long() work also if the other type of long was set
    + Python:
      * bugfix: avoid segfault when outputting a NULL SmartPointer;
      * new typemaps around Gyoto::Value
---
 include/GyotoObject.h |  12 ++++
 lib/Object.C          |  32 +++++++++
 lib/Value.C           |  28 +++++++-
 python/example.py     |  14 ++--
 python/gyoto.i        | 186 ++++++++++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 257 insertions(+), 15 deletions(-)

diff --git a/include/GyotoObject.h b/include/GyotoObject.h
index 7fba758..57a6000 100644
--- a/include/GyotoObject.h
+++ b/include/GyotoObject.h
@@ -188,12 +188,24 @@ class Gyoto::Object
   /// Set Value (expressed in unit) of a Property
   void set(Property const &p, Value val, std::string const &unit);
 
+  /// Set Value of a Property
+  void set(std::string const &pname, Value val);
+
+  /// Set Value (expressed in unit) of a Property
+  void set(std::string const &pname, Value val, std::string const &unit);
+
   /// Get Value of a Property
   Value get(Property const &p) const;
 
+  /// Get Value of a Property
+  Value get(std::string const &pname) const;
+
   /// Get Value of a Property, converted to unit
   Value get(Property const &p, std::string const &unit) const;
 
+  /// Get Value of a Property, converted to unit
+  Value get(std::string const &pname, std::string const &unit) const;
+
   /// Find property by name
   /**
    * Look into the Property list for a Property whose \a name (or
diff --git a/lib/Object.C b/lib/Object.C
index bb2dc2f..b2df225 100644
--- a/lib/Object.C
+++ b/lib/Object.C
@@ -120,6 +120,20 @@ void Object::set(Property const &p, Value val) {
 # undef ___local_case
 }
 
+void Object::set(std::string const &pname, Value val) {
+  Property const * p = property(pname);
+  if (!p) throwError("No Property by that name");
+  set(*p, ((p->type == Property::bool_t && pname == p->name_false)?
+	  Value(!val):val));
+}
+
+void Object::set(std::string const &pname, Value val, std::string const &unit) {
+  Property const * p = property(pname);
+  if (!p) throwError("No Property by that name");
+  set(*p, ((p->type == Property::bool_t && pname == p->name_false)?
+	  Value(!val):val), unit);
+}
+
 Value Object::get(Property const &p,
 			    std::string const &unit) const {
 
@@ -189,6 +203,24 @@ Value Object::get(Property const &p) const {
 # undef ___local_case
 }
 
+Value Object::get(std::string const &pname) const {
+  Property const * p = property(pname);
+  if (!p) throwError("No Property by that name");
+  Value res = get(*p);
+  if (p->type == Property::bool_t && pname == p->name_false)
+    return !bool(res);
+  return res;
+}
+
+Value Object::get(std::string const &pname, std::string const &unit) const{
+  Property const * p = property(pname);
+  if (!p) throwError("No Property by that name");
+  Value res = get(*p, unit);
+  if (p->type == Property::bool_t && pname == p->name_false)
+    return !bool(res);
+  return res;
+}
+
 Property const * Object::property(std::string const pname) const {
   Property const * prop = getProperties(); 
   while (prop) {
diff --git a/lib/Value.C b/lib/Value.C
index d3fbea4..47baa68 100644
--- a/lib/Value.C
+++ b/lib/Value.C
@@ -22,10 +22,34 @@ Value::~Value() {}
   return T;						\
   }
 
+Value::Value(long val) : type(Property::long_t), Long(val){}
+Value::Value(unsigned long val) : type(Property::unsigned_long_t), ULong(val){}
+Value::operator long() const {
+  switch (type) {
+  case Property::long_t:
+    return Long;
+  case Property::unsigned_long_t:
+    return long(ULong);
+  default:
+    throwError("This Value does not hold a long (or unsigned long)");
+  }
+  return 0;
+}
+
+Value::operator unsigned long() const {
+  switch (type) {
+  case Property::long_t:
+    return (unsigned long)(Long);
+  case Property::unsigned_long_t:
+    return ULong;
+  default:
+    throwError("This Value does not hold a long (or unsigned long)");
+  }
+  return 0;
+}
+
 ___local_stuff(double, double_t, Double)
 ___local_stuff(bool, bool_t, Bool)
-___local_stuff(long, long_t, Long)
-___local_stuff(unsigned long, unsigned_long_t, ULong)
 ___local_stuff(std::string, string_t, String)
 ___local_stuff(std::vector<double>, vector_double_t, VDouble)
 ___local_stuff(std::vector<unsigned long>, vector_unsigned_long_t, VULong)
diff --git a/python/example.py b/python/example.py
index fa185b2..c338f9c 100644
--- a/python/example.py
+++ b/python/example.py
@@ -218,13 +218,14 @@ kerr=gyoto.Metric('KerrBL')
 
 # Most properties that can be set in an XML file can also be accessed
 # from Python using the Property/Value mechanism:
+# Low-level access:
 p=tt.property("SmallRadius")
+p.type==gyoto.Property.double_t
 tt.set(p, gyoto.Value(0.2))
-tt.get(p).toDouble() == 0.2
-
-p=kerr.property("Spin")
-kerr.set(p, gyoto.Value(0.95))
-kerr.get(p).toDouble() == 0.95
+tt.get(p) == 0.2
+# Higher-level:
+kerr.set("Spin", 0.95)
+kerr.get("Spin") == 0.95
 
 # However, we also have Python extensions around the standard Gyoto
 # plug-ins. Beware that the plug-in must be loaded into Gyoto before
@@ -241,8 +242,7 @@ tr2=gyoto_std.Torus()
 # and we can cast a generic pointer (from the gyoto extension) to a
 # derived class:
 tr=gyoto_std.Torus(tt)
-p=tt.property("SmallRadius")
-tt.get(p).toDouble() == tr.smallRadius()
+tt.get("SmallRadius") == tr.smallRadius()
 
 # Another example: using a complex (i.e. compound) Astrobj:
 cplx=gyoto_std.ComplexAstrobj()
diff --git a/python/gyoto.i b/python/gyoto.i
index 8a24a84..fad8fea 100644
--- a/python/gyoto.i
+++ b/python/gyoto.i
@@ -92,10 +92,11 @@
   Gyoto::SmartPointer<gtype>  (gtype *)
 {
   gtype* normal_pointer=(gtype *) (Gyoto::SmartPointer<gtype>(result));
-  normal_pointer->incRefCount();
+  if (normal_pointer) normal_pointer->incRefCount();
   $result = SWIG_NewPointerObj( normal_pointer, stype, SWIG_POINTER_OWN |  0 );
 }
-%typemap(typecheck) Gyoto::SmartPointer<gtype>, gtype * {
+%typemap(typecheck,precedence=SWIG_TYPECHECK_VOIDPTR)
+Gyoto::SmartPointer<gtype>, gtype * {
   void *vptr = 0;
   int res = SWIG_ConvertPtr($input, &vptr, stype, 0);
   $1 = SWIG_CheckState(res);
@@ -145,7 +146,7 @@
     Gyoto::SmartPointer<Gyoto::klass::Generic> pres=
       Gyoto::klass::getSubcontractor(nm.c_str())(NULL);
     Gyoto::klass::Generic * res = (Gyoto::klass::Generic *)(pres);
-    res -> incRefCount();
+    if (res) res -> incRefCount();
     return res;
   }
 };
@@ -242,6 +243,177 @@ GyotoSmPtrTypeMapClassDerived(Units, Converter);
 GyotoSmPtrTypeMapClassDerived(Worldline, IntegState);
 GyotoSmPtrTypeMapClassDerived(Astrobj, Properties);
 
+// Typemaps for Gyoto::Value:
+// In: cast from Python representations for all the supported types.
+// Implementation is specific to Python.
+%typemap(in) Gyoto::Value {
+  int res=0;
+  void *argp=0;
+  res=SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_Gyoto__Value, 0);
+  if (SWIG_IsOK(res)) {
+    Gyoto::Value * temp = reinterpret_cast< Gyoto::Value * >(argp);
+    $1 = *temp;
+    if (SWIG_IsNewObj(res)) delete temp;
+  }
+
+  if (!SWIG_IsOK(res)) {
+    res=SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_Gyoto__Metric__Generic, 0);
+    if (SWIG_IsOK(res)) {
+      Gyoto::SmartPointer<Gyoto::Metric::Generic> temp = reinterpret_cast< Gyoto::Metric::Generic * >(argp);
+      $1 = Gyoto::Value(temp);
+    }
+  }
+
+  if (!SWIG_IsOK(res)) {
+    res=SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_Gyoto__Astrobj__Generic, 0);
+    if (SWIG_IsOK(res)) {
+      Gyoto::SmartPointer<Gyoto::Astrobj::Generic> temp = reinterpret_cast< Gyoto::Astrobj::Generic * >(argp);
+      $1 = Gyoto::Value(temp);
+    }
+  }
+
+  if (!SWIG_IsOK(res)) {
+    res=SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_Gyoto__Spectrum__Generic, 0);
+    if (SWIG_IsOK(res)) {
+      Gyoto::SmartPointer<Gyoto::Spectrum::Generic> temp = reinterpret_cast< Gyoto::Spectrum::Generic * >(argp);
+      $1 = Gyoto::Value(temp);
+    }
+  }
+
+  if (!SWIG_IsOK(res)) {
+    res=SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_Gyoto__Spectrometer__Generic, 0);
+    if (SWIG_IsOK(res)) {
+      Gyoto::SmartPointer<Gyoto::Spectrometer::Generic> temp = reinterpret_cast< Gyoto::Spectrometer::Generic * >(argp);
+      $1 = Gyoto::Value(temp);
+    }
+  }
+
+  if (!SWIG_IsOK(res)) {
+    res=SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_Gyoto__Screen, 0);
+    if (SWIG_IsOK(res)) {
+      Gyoto::SmartPointer<Gyoto::Screen> temp = reinterpret_cast< Gyoto::Screen * >(argp);
+      $1 = Gyoto::Value(temp);
+    }
+  }
+
+  if (!SWIG_IsOK(res)) {
+    std::string *temp = 0;
+    res = SWIG_AsPtr_std_string ($input, &temp) ;
+    if (SWIG_IsOK(res)) $1 = Gyoto::Value(*temp);
+    if (SWIG_IsNewObj(res) && temp) delete temp;
+  }
+
+  if (!SWIG_IsOK(res)) {
+    std::vector<unsigned long> *temp=0;
+    res = swig::traits_asptr< std::vector<unsigned long> >::asptr($input, &temp);
+    if (SWIG_IsOK(res)) $1 = Gyoto::Value(*temp);
+    if (SWIG_IsNewObj(res) && temp) delete temp;
+  }
+
+  if (!SWIG_IsOK(res)) {
+    std::vector<double> *temp=0;
+    res = swig::traits_asptr< std::vector<double> >::asptr($input, &temp);
+    if (SWIG_IsOK(res)) $1 = Gyoto::Value(*temp);
+    if (SWIG_IsNewObj(res) && temp) delete temp;
+  }
+
+  /*
+  // This would help in making this language-agnostic, but it become
+  // difficult to distinguish the various subtypes (long vs bool vs
+  // double):
+  if (!SWIG_IsOK(res)) {
+    bool temp=false;
+    res = SWIG_AsVal(bool)($input, &temp)
+    if (SWIG_IsOK(res)) $1 = Gyoto::Value(temp);
+  }
+  */
+
+  if (SWIG_IsOK(res)) ; // done
+  else if (PyBool_Check($input)) $1 = Gyoto::Value($input == Py_True);
+  else if (PyInt_Check($input)) $1 = Gyoto::Value(long(PyInt_AsLong($input)));
+  else if (PyLong_Check($input)) $1 = Gyoto::Value(long(PyLong_AsLong($input)));
+  else if (PyFloat_Check($input)) $1 = Gyoto::Value(PyFloat_AsDouble($input));
+  else {
+    SWIG_exception_fail(SWIG_ArgError(res), "argument of type 'Gyoto::Value*'");
+  }
+ }
+// Typecheck: should be debugged, does not seem to filter anything
+%typemap(typecheck) Gyoto::Value {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_Gyoto__Value, 0);
+  $1 = res;
+  //  $1 = res ||
+  //    PyInt_Check($input) ||
+  //    PyLong_Check($input)
+  //    ;
+}
+// Out: cast from Gyoto::Value to language-specific representation
+// for each sub-type. Probably language-agnostic.
+%typemap(out) Gyoto::Value {
+  switch ($1.type) {
+  case Gyoto::Property::unsigned_long_t:
+    $result = SWIG_From_unsigned_SS_long((unsigned long)($1));
+    break;
+  case Gyoto::Property::long_t:
+    $result = SWIG_From_long(long($1));
+    break;
+  case Gyoto::Property::bool_t:
+    $result = SWIG_From_bool(bool($1));
+    break;
+  case Gyoto::Property::double_t:
+    $result = SWIG_From_double(double($1));
+    break;
+  case Gyoto::Property::filename_t:
+  case Gyoto::Property::string_t:
+    $result = SWIG_From_std_string(static_cast< std::string >($1));
+    break;
+  case Gyoto::Property::vector_double_t:
+    $result = swig::from(($1).operator std::vector<double>());
+    break;
+  case Gyoto::Property::vector_unsigned_long_t:
+    $result = swig::from(($1).operator std::vector<unsigned long>());
+    break;
+  case Gyoto::Property::metric_t:
+    {
+      Gyoto::Metric::Generic* normal_pointer=(Gyoto::Metric::Generic *) (Gyoto::SmartPointer<Gyoto::Metric::Generic>($1));
+      if (normal_pointer) normal_pointer->incRefCount();
+      $result = SWIG_NewPointerObj( normal_pointer, SWIGTYPE_p_Gyoto__Metric__Generic, SWIG_POINTER_OWN |  0 );
+    }
+    break;
+  case Gyoto::Property::astrobj_t:
+    {
+      Gyoto::Astrobj::Generic* normal_pointer=(Gyoto::Astrobj::Generic *) (Gyoto::SmartPointer<Gyoto::Astrobj::Generic>($1));
+      if (normal_pointer) normal_pointer->incRefCount();
+      $result = SWIG_NewPointerObj( normal_pointer, SWIGTYPE_p_Gyoto__Astrobj__Generic, SWIG_POINTER_OWN |  0 );
+    }
+    break;
+  case Gyoto::Property::spectrum_t:
+    {
+      Gyoto::Spectrum::Generic* normal_pointer=(Gyoto::Spectrum::Generic *) (Gyoto::SmartPointer<Gyoto::Spectrum::Generic>($1));
+      if (normal_pointer) normal_pointer->incRefCount();
+      $result = SWIG_NewPointerObj( normal_pointer, SWIGTYPE_p_Gyoto__Spectrum__Generic, SWIG_POINTER_OWN |  0 );
+    }
+    break;
+  case Gyoto::Property::spectrometer_t:
+    {
+      Gyoto::Spectrometer::Generic* normal_pointer=(Gyoto::Spectrometer::Generic *) (Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>($1));
+      if (normal_pointer) normal_pointer->incRefCount();
+      $result = SWIG_NewPointerObj( normal_pointer, SWIGTYPE_p_Gyoto__Spectrometer__Generic, SWIG_POINTER_OWN |  0 );
+    }
+    break;
+  case Gyoto::Property::screen_t:
+    {
+      Gyoto::Screen* normal_pointer=(Gyoto::Screen *) (Gyoto::SmartPointer<Gyoto::Screen>($1));
+      if (normal_pointer) normal_pointer->incRefCount();
+      $result = SWIG_NewPointerObj( normal_pointer, SWIGTYPE_p_Gyoto__Screen, SWIG_POINTER_OWN |  0 );
+    }
+    break;
+  default:
+    $result = SWIG_NewPointerObj((new Gyoto::Value(static_cast< const Gyoto::Value& >($1))), SWIGTYPE_p_Gyoto__Value, SWIG_POINTER_OWN |  0 );
+  }
+}
+
+
 // Non-Gyoto typemaps:
 // Handle std::string
 %include "std_string.i";
@@ -249,6 +421,9 @@ GyotoSmPtrTypeMapClassDerived(Astrobj, Properties);
 // Handle std::vector<double> and <unsigned long int>
 %include "std_vector.i";
 %template(vector_double) std::vector<double>;
+%{
+  typedef unsigned long unsignedlong;
+  %}
 %template(vector_unsigned_long) std::vector<unsigned long>;
 
 // Handle some arrays as NumPy arrays
@@ -359,8 +534,7 @@ GyotoSmPtrClassDerived(Astrobj, ThinDisk)
 %define _PConverter(member, method)
   Gyoto::Units::Converter * method() {
   Gyoto::Units::Converter * res = $self->member;
-    if (!res) Gyoto::throwError(#member " converter not set");
-    res -> incRefCount();
+    if (res) res -> incRefCount();
     return res;
   }
 %enddef
@@ -377,7 +551,7 @@ GyotoSmPtrClassGeneric(Spectrometer)
 %extend Gyoto::Spectrometer::Complex {
   Gyoto::Spectrometer::Generic * __getitem__ (int i) {
     Gyoto::Spectrometer::Generic * res = ($self)->operator[](i);
-    res -> incRefCount();
+    if (res) res -> incRefCount();
     return res;
   }
  };

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-astro/packages/gyoto.git



More information about the Debian-astro-commits mailing list