Logo Search packages:      
Sourcecode: octaviz version File versions  Download package

octaviz.cc

/*

Copyright (C) 1996 John W. Eaton
Copyright (C) 2004 Paul Kienzle
Copyright (C) 2004 Dragan Tubic

This file is part of Octave.

Octave is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

Octave 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 General Public License
for more details.

You should have received a copy of the GNU General Public License
along with Octave; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include <vtkObjectBase.h>          
#include <vtkObject.h>        

// The following must be defined for recent versions of Octave.
#define TYPEID_HAS_CLASS

#include <octave/oct.h>
#include <octave/parse.h>
#include <octave/variables.h>
#include <octave/symtab.h>
#include <octave/pager.h>
#include <octave/config.h>

#include <cstdlib>
#include <string>
#include <ostream>
#include <iomanip>
#include <vector>
#include <ext/hash_map>

#include "octaviz.h"

// Threads
//#include <pthread.h>

#include <X11/Intrinsic.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/keysym.h>

XtAppContext vtk_app_context;

std::map<Atom, unsigned int> vtk_delete_window_atoms;

/// Main vtk event loop
int vtk_event_loop()
{
      std::vector<Atom> to_close;
      
      while ( XtAppPending(vtk_app_context) )
      {
            XEvent event;
            XtAppNextEvent( vtk_app_context, &event);
            if ( event.type != ClientMessage )
            {
                  XtDispatchEvent( &event);
            } else
            {
                  // Ignore WM_DELETE_WINDOW. We will close the windows below.
                  Atom wm = event.xclient.data.l[0];
                  if ( vtk_delete_window_atoms.find(wm) == vtk_delete_window_atoms.end() ) 
                  {
                        XtDispatchEvent( &event);
                  } else
                  {
                        to_close.push_back( wm );
                  }
            }
      }
      // close figures if there's any pending
      bool clear_wm = to_close.size() > 0;
      
      for ( unsigned int i = 0; i < to_close.size(); i++ )
      {
            std::map<Atom, unsigned int>::iterator wm;
            wm = vtk_delete_window_atoms.find( to_close[i] );
            if ( wm != vtk_delete_window_atoms.end() ) 
            {
                  Matrix A(2,2);
                  A(0,0) = wm->second;
                  A(0,1) = wm->second;
                  A(1,0) = wm->second;
                  A(1,1) = wm->second;
                  octave_value x = A;
                  feval("vtk_close",x);
            }
      }
      if ( clear_wm ) 
      {
            vtk_delete_window_atoms.clear();
      }
}

/// End of X window and threading stuff

vtk_object::vtk_object ( vtkObjectBase *pointer, bool belongs_to_octave )
    : octave_base_value (), 
            vtk_pointer ( pointer ) 
{
      //std::cout << "Creating.\n" << std::flush;
      std::map<unsigned int, int>& reference_count = get_reference_map();

      unsigned int key = reinterpret_cast<unsigned int>( pointer );
      
      if ( belongs_to_octave ) 
      {
            // This is a newly created vtk object that belongs to octave
            // we need to reference count it
            if ( reference_count.find(key) != reference_count.end() )
                  {
                        error("Panic: creating vtk object that already exists!\n");
                  }
    reference_count[key] = 1;
            return;
      }
      
      // If this is a clone than it exists in reference count map
      if ( reference_count.find(key) == reference_count.end() ) return;
      // It belongs to octave, increase reference count
      //std::cout << "Increasing reference count2.\n" << std::flush;
      reference_count[key]++;
}

vtk_object::vtk_object (void)
    : octave_base_value (), 
            vtk_pointer (NULL) 
{
      //std::cout << "Creating null.\n" << std::flush;
}

vtk_object::vtk_object (const vtk_object& s )
    : octave_base_value (s), 
            vtk_pointer (s.vtk_pointer) 
{
      //std::cout << "Creating copy.\n" << std::flush;
      std::map<unsigned int, int>& reference_count = get_reference_map();

      unsigned int key = reinterpret_cast<unsigned int>( vtk_pointer );
      
      // If this is a clone than it exists in reference count map
      if ( reference_count.find(key) == reference_count.end() ) return;
      // It belongs to octave, increase reference count
      //std::cout << "Increasing reference count3.\n" << std::flush;
      reference_count[key]++; 
}

vtk_object::~vtk_object (void) 
{ 
      //std::cout << "Destroying.\n" << std::flush;
      std::map<unsigned int, int>& reference_count = get_reference_map();
      unsigned int key = reinterpret_cast<unsigned int>( vtk_pointer );
      // Check if the pointer is reference counted.
      if ( reference_count.find(key) == reference_count.end() ) return;
      
      // It belongs to octave, decrease reference count
      reference_count[key]--;
      // If the count is larger than 0 we don't care, there is another
      // octave variable that references this vtk object.
      if ( reference_count[key] > 0 ) return;
      // Delete the vtk object, nobody references it anymore
      //std::cout << "Destroying vtk object.\n" << std::flush;
      vtk_pointer->Delete();
      vtk_pointer = NULL;
      reference_count.erase( reference_count.find(key) );
}

unsigned int vtk_object::uint_value (bool req_int, bool frc_str_conv ) const
{
      return reinterpret_cast<unsigned int>(vtk_pointer);
}
 
bool vtk_object::is_defined (void) const 
{ 
      return true; 
}

// since we are a function, we won't see do_index_op
octave_value vtk_object::do_index_op (const octave_value_list &, int)
{
      error("octave_object: do_index_op(idx,can_resize)");
      return octave_value();
}

// x.v = y     x(idx).v = y     x{idx}.v = y
octave_value vtk_object::subsasgn (const std::string& type,
                                                                        const LIST<octave_value_list>& idx,
                                                                        const octave_value& rhs)
{
      error("octave_object: subsasgn(type,idx,rhs)");
      return octave_value ();
}

// x.v     x(idx).v     x{idx}.v
octave_value vtk_object::subsref (const std::string SUBSREF_STRREF type,
            const LIST<octave_value_list>& idx)
{
      //octave_stdout << "octave_object: subsref(type,idx)" << std::endl;
      return subsref (type, idx, 1)(0);
}

// [i,j] = x(i)
octave_value_list vtk_object::do_multi_index_op (int, const octave_value_list&)
{
      error("octave_object: do_multi_index_op(nargout,args)");
      return octave_value_list();
}

static bool
any_arg_is_magic_colon (const octave_value_list& args)
{
  int nargin = args.length ();

  for (int i = 0; i < nargin; i++)
    if (args(i).is_magic_colon ())
      return true;

  return false;
}

// [i,j] = x.v(...)
octave_value_list vtk_object::subsref (const std::string SUBSREF_STRREF type,
                       const LIST<octave_value_list>& idx,
                       int nargout)
{
  octave_value_list retval;
  size_t skip = 1;

  switch (type[0])
    {
    case '.':
      {
                        std::string class_name = vtk_pointer->GetClassName();
                        
                        octave_value_list args;
                        args(0) = octave_value( new vtk_object(*this) );
                        args(1) = idx.front()(0).string_value ();
                  if (idx.LISTSIZE () < 2 || type[1] != '(') 
            {
                        octave_value res;
            retval = feval(class_name,args,nargout);
            } 
                  else 
            {
            skip = 2;
            LIST<octave_value_list>::const_iterator pidx = idx.begin();
                        octave_value_list args;
                        args(0) = octave_value( new vtk_object(*this) );
                        args(1) = (*pidx)(0).string_value ();
                        pidx++;

            int n = args.length ();
            for ( int i = 0; i < (*pidx).length (); i++ ) args(i+2) = (*pidx)(i);

            if (any_arg_is_magic_colon (*pidx)) 
            {
                              error ("invalid use of colon in method argument list");
            } 
            else 
            {
                  retval = feval(class_name,args,nargout);
            }
        }
      }
      break;
    case '(':
    case '{':
      {
                        std::string nm = type_name ();
                        error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
      }
      break;

    default:
      panic_impossible ();
    }

  if (!error_state && idx.LISTSIZE () > skip)
    retval = retval(0).next_subsref (type, idx, skip);

  return retval;
} 

void vtk_object::print (std::ostream& os, bool pr_as_read_syntax) const
{
      if ( vtk_pointer == NULL )
      {
        os << "NULL";
      } else
      {
        vtk_pointer->Print(os);
      }
} 


std::map<unsigned int, int>& vtk_object::get_reference_map()
{
      static std::map<unsigned int, int>  reference_count;
      return reference_count;
}

void vtk_object::print_ref_table()
{
      octave_stdout << "vtk_object::print_ref_table\n" << std::flush;
      std::map<unsigned int, int>& reference_count = get_reference_map();
      std::map<unsigned int, int>:: iterator i;
      for ( i = reference_count.begin(); i != reference_count.end(); i++ )
      {
            octave_stdout << std::hex << (*i).first << ":" << (*i).second << std::endl;
      }
}

DEFINE_OCTAVE_ALLOCATOR (vtk_object);

#ifdef TYPEID_HAS_CLASS
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (vtk_object, "vtk_object", "vtk_object");
#else
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (vtk_object, "vtk_object");
#endif


//--------------------------------------------------------------------
vtkOctaveCommand::vtkOctaveCommand()
{ 
  this->obj = NULL;
}
//--------------------------------------------------------------------
vtkOctaveCommand::~vtkOctaveCommand()
{ 
   if (this->obj)
     {
//                      this->Delete();
     }
   this->obj = NULL;
}
//--------------------------------------------------------------------
void vtkOctaveCommand::SetObject(vtk_object *o)
{ 
   this->obj = o; 
}
//--------------------------------------------------------------------
void vtkOctaveCommand::SetFunctionName(const char* function_name )
{ 
   this->function = function_name; 
}
//--------------------------------------------------------------------
void vtkOctaveCommand::Execute(vtkObject *ptr, unsigned long eventtype,
                               void *CallData)
{
   const char *eventname;
   eventname = this->GetStringFromEventId(eventtype);
       std::cout << "Executing " << this->function << " for " << eventname << "\n" << std::flush;
       std::cout << this->obj << endl;
       this->obj->print_ref_table();
       
       octave_value_list x;
       std::cout << "Assigning parameters 1" << std::flush << std::endl;
   
   x(0) = octave_value( new vtk_object( ptr, false ) );
       std::cout << "Assigning parameters 2" << std::flush << std::endl;
   x(1) = octave_value(eventname);
       std::cout << "Evaluating observer function" << std::flush << std::endl;
       
       feval(this->function,x);
}
//--------------------------------------------------------------------




/*
;;; Local Variables: ***
;;; mode: C++ ***
;;; End: ***
*/
 

Generated by  Doxygen 1.6.0   Back to index