POV-Ray : Newsgroups : povray.binaries.programming : Ancient POVMS docs : Ancient POVMS docs Server Time
19 Apr 2024 05:55:34 EDT (-0400)
  Ancient POVMS docs  
From: Thorsten Froehlich
Date: 5 Jun 2014 11:54:44
Message: <539092c4@news.povray.org>
I was digging in some old messages, and this might help clarify some 
developments. There are actually more messages, but at the time I used a 
different newsreader software and the backups are elsewhere...

Keep in mind that some information will be outdated!!

-------- Original Message --------
Subject: 	POVMS C++ interface posted
Date: 	Sat, 25 Sep 1999 18:52:25 -0500
From: 	Thorsten Froehlich
Newsgroups: 	private.pov-team


Hello,

I have posted an archive with the current C++ interface classes for the
POVMS. They hide the POVMS C interface behind standard C++ classes so you
only need to deal with these classes and not with actual POVMS data
sttuctres or calls.  Ther are, however, a few open ends where a C++
implementation does not make any sense. You will still need to install
standard POVMS C interface receive handler functions for messages, but with
the POVMS message data structures received you can easily create C++
interface objects out of them by calling a conversion constructor.
Also notice that you need to call the destructors of each of the C++
objects, contrary to the POVMS interface which takes over the ownership when
data is added to some structures. For example, while you would do this in
the C interface:


void myFunc(POVMSObjectPtr object, POVMSType key, char *str)
{
   POVMSAttribute attr;
   int ret;

   ret = POVMSAttr_New(&attr);
   if(ret == kNoErr)
     ret = POVMSAttr_Set(&attr, kPOVMSType_CString,
                         (void *)str, strlen(str) + 1);
   if(ret == kNoErr)
     ret = POVMSObject_Set(object, &attr, key);
}


It will look like this using the C++ interface:


void myFunc(POVMS_Object& object, POVMSType key, char *str)
{
   POVMS_Attribute attr;

   try
   {
     attr.Set(kPOVMSType_CString,
             (void *)str, strlen(str) + 1);

     object.Set(attr, key);
   }
   catch(int ret)
   {
     // ...
   }
}


Or, with a dynamic allocation like this:


void myFunc(POVMS_Object& object, POVMSType key, char *str)
{
   POVMS_Attribute *attr = new POVMS_Attribute;

   try
   {
     attr->Set(kPOVMSType_CString,
             (void *)str, strlen(str) + 1);

     object.Set(*attr, key);
   }
   catch(int ret)
   {
     // ...
   }

   delete attr;
}


Notice, however, that the following will _not_ work as expected:


void myFunc(POVMS_Object& object, POVMSType key, POVMSType key2, char *str)
{
   POVMS_Attribute *attr = new POVMS_Attribute;

   try
   {
     attr->Set(kPOVMSType_CString,
             (void *)str, strlen(str) + 1);

     object.Set(*attr, key);

     object.Set(*attr, key2); // won't work

     attr->Set(kPOVMSType_CString,
             (void *)str, strlen(str) + 1);

     object.Set(*attr, key2); // will work
  }
   catch(int ret)
   {
     // ...
   }

   delete attr;
}


The reason for this is that once the POVMS data has been added to an object
it belongs to that object. So after the first call to object.Set the POVMS
data the C++ object contains is empty. The second call to object.Set will
simply throw an exception that the data passed is empty.
Notice that you can reuse the object as done in the third call to
object.Set.  Also notice that there won't be memory leaks if you call
attr->Set several times, but each time the old data will be replaced.

Another note: The C++ implementation will throw exceptions. Currently all
exception data is of type int.


For now I haven't written any documentation for the C++ class part, in most
parts it work exactly like the C implemenation and I have noted all
differences.
I will try to write docs, but midterm exams are coming nearer and it might
take until late October or so. :-(

It is also very important to note that I have _not_ used the classes myself
so far, so there will likely be problems left. Please let me know of any
unexpected behaviour!


      Thorsten



-------- Original Message --------
Subject: 	Re: POVMS
Date: 	Thu, 12 Apr 2001 13:18:25 -0500
From: 	Thorsten Froehlich
To: 	Chris Cason


 > Could you please show me how I can use POVMS to retrieve the error line,
 > column, and token from POVMS after a parsing error ? I can see you send
 > them via Where_Error (), but I have no idea how to get them from the
 > Windows side.

Well, you can get the file and line number easily.  Unfortunately you
cannot get the column where the error occurred because this information
is not always available.  It could be added and have a default value, of
course.  I am not sure what the specific token that caused the error
would be useful for as it is part of the error message already.

This is the code I use on the Mac:

POVMS_InstallReceiver(Mac__ReceiveHandler,
                       kPOVMsgClass_RenderOutput,
                       kPOVMSType_WildCard); // you will get i.e.
                                             // kPOVMsgIdent_Error,
                                             // kPOVMsgIdent_FatalError,
                                             // kPOVMsgIdent_Warning,
                                             // kPOVMsgIdent_Debug


int Mac__ReceiveHandler(POVMSObjectPtr msg,
                         POVMSObjectPtr result,
                         int mode)
{
  POVMSAttribute attr;
  POVMSType hid;
  Str255 fname = kEmptyString;
  FSSpec file;
  Handle h;
  long l = 0;
  long s = 0;
  int ret = 0;
  int line;

  ret = POVMSObject_Get(msg, &attr, kPOVMSMessageIdentID);
  if(ret == 0)
  {
   l = sizeof(POVMSType);
   ret = POVMSAttr_Get(&attr, kPOVMSType_Type, (void *)(&hid), &l);
   (void)POVMSAttr_Delete(&attr);
  }
  if(ret == 0)
  {
   switch(hid)
   {
    case kPOVMsgIdent_Error:
    case kPOVMsgIdent_FatalError:
     ret = POVMSObject_Get(msg, &attr, kPOVAttrib_EnglishText);
     if(ret == 0)
      ret = POVMSAttr_Size(&attr, &l);
     if(ret == 0)
     {
      h = NewHandle(l);
      if(h == NULL)
       ret = -2;
     }
     if(ret == 0)
     {
      HLock(h);
      ret = POVMSAttr_Get(&attr, kPOVMSType_CString, (void *)(*h), &l);
      HUnlock(h);
     }
     if(ret == 0)
      (void)POVMSAttr_Delete(&attr);
     if(POVMSObject_Get(msg, &attr, kPOVAttrib_FileName) == 0)
     {
      l = 0;
      if(POVMSAttr_Size(&attr, &l) == 0)
      {
       if(l < 256)
       {
        if(POVMSAttr_Get(&attr, kPOVMSType_CString,
                             (void *)(&fname[1]), &l) == 0)
        {
         fname[0] = l - 1;
         if(FSMakeFSSpec(0, 0, fname, &file) != noErr)
          fname[0] = 0;
        }
       }
      }
      (void)POVMSAttr_Delete(&attr);
     }
     if(POVMSObject_Get(msg, &attr, kPOVAttrib_Line) == 0)
     {
      l = sizeof(int);
      ret = POVMSAttr_Get(&attr, kPOVMSType_Int, (void *)(&line), &l);
      (void)POVMSAttr_Delete(&attr);
     }
     if(ret == 0)
     {
      if(fname[0] == 0)
       (dynamic_cast<POVRayMac *>(gApplication))->messageWindow->
                     AddMessage(kStatusError, h, NULL, 0);
      else
       (dynamic_cast<POVRayMac *>(gApplication))->messageWindow->
                     AddMessage(kStatusError, h, &file, line);
     }
     break;
    case kPOVMsgIdent_Warning:
     ret = POVMSObject_Get(msg, &attr, kPOVAttrib_EnglishText);
     if(ret == 0)
      ret = POVMSAttr_Size(&attr, &l);
     if(ret == 0)
     {
      h = NewHandle(l);
      if(h == NULL)
       ret = -2;
     }
     if(ret == 0)
     {
      HLock(h);
      ret = POVMSAttr_Get(&attr, kPOVMSType_CString, (void *)(*h), &l);
      HUnlock(h);
     }
     if(ret == 0)
      (void)POVMSAttr_Delete(&attr);
     if(POVMSObject_Get(msg, &attr, kPOVAttrib_FileName) == 0)
     {
      l = 0;
      if(POVMSAttr_Size(&attr, &l) == 0)
      {
       if(l < 256)
       {
        if(POVMSAttr_Get(&attr, kPOVMSType_CString,
                             (void *)(&fname[1]), &l) == 0)
        {
         fname[0] = l - 1;
         if(FSMakeFSSpec(0, 0, fname, &file) != noErr)
          fname[0] = 0;
        }
       }
      }
      (void)POVMSAttr_Delete(&attr);
     }
     if(POVMSObject_Get(msg, &attr, kPOVAttrib_Line) == 0)
     {
      l = sizeof(int);
      ret = POVMSAttr_Get(&attr, kPOVMSType_Int, (void *)(&line), &l);
      (void)POVMSAttr_Delete(&attr);
     }
     if(ret == 0)
     {
      if(fname[0] == 0)
       (dynamic_cast<POVRayMac *>(gApplication))->messageWindow->
                     AddMessage(kStatusWarning, h, NULL, 0);
      else
       (dynamic_cast<POVRayMac *>(gApplication))->messageWindow->
                     AddMessage(kStatusWarning, h, &file, line);
     }
     break;
    case kPOVMsgIdent_Debug:
     ret = POVMSObject_Get(msg, &attr, kPOVAttrib_EnglishText);
     if(ret == 0)
      ret = POVMSAttr_Size(&attr, &l);
     if(ret == 0)
     {
      h = NewHandle(l);
      if(h == NULL)
       ret = -2;
     }
     if(ret == 0)
     {
      HLock(h);
      ret = POVMSAttr_Get(&attr, kPOVMSType_CString, (void *)(*h), &l);
      HUnlock(h);
     }
     if(ret == 0)
      (void)POVMSAttr_Delete(&attr);
     if(ret == 0)
      (dynamic_cast<POVRayMac *>(gApplication))->messageWindow->
                    AddMessage(kStatusDebug, h, NULL, 0);
     break;
    default:
     h = NewHandle(5);
     if(h == NULL)
      ret = -2;
     if(ret == 0)
     {
      HLock(h);
      *((int *)(*h)) = hid;
      (*h)[4] = 0;
      HUnlock(h);
      (dynamic_cast<POVRayMac *>(gApplication))->messageWindow->
                    AddMessage(kStatusDebug, h, NULL, 0);
     }
     break;
   }
  }

  return ret;
}


 > PS I think the pre-beta is going very well. I'm pleased with the number of
 > bugs we've quashed, and also the amount of contributed work that's coming
 > in (e.g. the scenes, includes, and the icons for the windows version).

I agree.  A lot of bugs have been found, and with a bit of luck we can
have a public beta in the foreseeable future.


        Thorsten




-------- Original Message --------
Subject: 	Re: Possible memleak in POVMS ?
Date: 	Wed, 17 Mar 2004 19:40:01 +0100
From: 	Thorsten Froehlich
Newsgroups: 	private.povray.programming
References: 	<40588369@news.povray.org>


In article <40588369@news.povray.org> , Nicolas Calimet wrote:

 >         So I went to look at the core code, and noticed that only
 > base/povms.cpp still uses direct calls to malloc and friends, as
 > denoted in a comment near the top of the file where the POVMS_Sys_*
 > macros are declared.  If there is a leak here, it won't be reported
 > as in the rest of the code.

Yes, POVMS cannot use the POV_xxx memory allocation functions because POVMS
is used for error output inside the memory allocation functions.  Thus, if
memory allocation would fail inside POVMS it would trigger a POVMS message
to be generated, which would try to allocate memory, fail to allocate it and
trigger a POVMS message to be generated, and so on.

This is why there are the macros.  They allow POVMS memory allocation to be
replaced by something system specific that works on a lower level than
POV_xxx memory allocation.  The Mac version makes use of this to overload
the POVMS memory allocation with a special multithreadsafe allocator (so one
can link the core code against a non-multithreadsafe allocator, which tends
to be a bit faster).

In addition to this, the Mac also overloads the generic POV_xxx memory
allocation functions to provide a nice way to fail in out of memory
conditions by having a special safety buffer (128 KB) that is released when
POV-Ray runs out of memory.  This free memory allows the GUI (and POVMS)
enough air to run important tasks such as displaying an error message before
POV_xxx memory allocations are freed.

Consequently, the Mac memory allocation is much different from the generic
memory allocation.  And the Mac version also uses slightly different (older)
handlers for POVMS, which were back during the 3.5 development tested for
memory leaks.  It may well be that the 3.6 default handlers or other changes
in 3.6 do indeed cause memory leaks in POVMS (i.e. messages are not freed).
I do have the old code to debug POVMS memory allocation somewhere.  If I can
get it to compile again, I will either post it or submit it (if that makes
sense - this depends on the stability of the memory debugging code for
POVMS) such that you can then debug POVMS as it behaves on your platform.

I will make getting this code working a priority, so hopefully I will have
it ready for you later this week(end).


Regarding the slowdown, Chris and I observed similar patterns on Mac and
Windows, but we were able to at least obscure it by making parsing faster.
Still, we are not sure parsing was the real cause of the slowdown.  There
was simply not enough time to investigate this closer for beta 2.

     Thorsten


Post a reply to this message


Attachments:
Download 'getting started with povms.pdf' (50 KB)

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.