X3D libraries
The libraries to work with X3D dataset

node.h

Go to the documentation of this file.
00001 /*
00002  *    libx3d base -- X3D node definition
00003  *    Copyright (C) 2005  Made to Order Software, Corp.
00004  *
00005  *    This library is free software; you can redistribute it and/or
00006  *    modify it under the terms of the GNU Lesser General Public
00007  *    License as published by the Free Software Foundation; either
00008  *    version 2.1 of the License, or (at your option) any later version.
00009  *
00010  *    This library is distributed in the hope that it will be useful,
00011  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *    Lesser General Public License for more details.
00014  *
00015  *    You should have received a copy of the GNU Lesser General Public
00016  *    License along with this library; if not, write to the Free Software
00017  *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  *
00019  * File: base/include/x3d/node.h
00020  * License: GNU Lesser General Public License
00022  * $Revision: 1.25 $
00023  * $Date: 2005/12/19 01:31:09 $
00024  *
00025  * $Log: node.h,v $
00026  * Revision 1.25  2005/12/19 01:31:09  alexis
00027  * Added the LevelOfSupport object
00028  *
00029  * Revision 1.24  2005/12/11 09:15:30  alexis
00030  * Fixed the string destructor which would (try to) delete the g_empty buffer.
00031  *
00032  * Revision 1.23  2005/12/07 21:22:41  alexis
00033  * Changed many (void) parameters to ()
00034  * Added the Reset() functions
00035  *
00036  * Revision 1.22  2005/12/04 17:52:57  alexis
00037  * Changed the array Get() to return a non-const type.
00038  * Fixed the vector delete.
00039  * Made the FieldInfo a const in the listener FieldChanged()
00040  *
00041  * Revision 1.21  2005/12/02 09:03:53  alexis
00042  * Some fixes to the new listener code
00043  *
00044  * Revision 1.20  2005/11/29 06:51:36  alexis
00045  * Added yet some more documentation
00046  *
00047  * Revision 1.19  2005/11/28 12:09:02  alexis
00048  * Many changes so I could generate a list of files with their brief comment,
00049  * filename, license, size, number of lines, and last modification date.
00050  *
00051  * Revision 1.18  2005/11/28 03:17:44  alexis
00052  * Added the License: comment
00053  * Fixed the library name in the auto-generated files 1st line comment
00054  *
00055  * Revision 1.17  2005/11/27 11:17:24  alexis
00056  * Added a GetDefaultContainerFieldName() which returns the textual name
00057  * and the other now returns the numeric field name (much faster!)
00058  * Fixed the parameters of the SetChild() to use data instead of value.
00059  *
00060  * Revision 1.16  2005/11/27 09:40:29  alexis
00061  * Fixed the GetTypeCount() to return int instead of field_t
00062  *
00063  * Revision 1.15  2005/11/27 05:54:57  alexis
00064  * Fixed the nodes.html so it includes the smartpointer.h properly
00065  *
00066  * Revision 1.14  2005/11/26 23:46:07  alexis
00067  * Added the [M]ValueToString() functions
00068  * Fixed some warnings (signed/unsigned, unused local var., missing
00069  * return *this and some others)
00070  * Added new functions to the SFString (Escape/Unescape)
00071  *
00072  * Revision 1.13  2005/11/26 12:11:48  alexis
00073  * Added the proper GetFieldDefault() and FieldHasDefaultValue() functions
00074  * so we can save only these fields which are not set to the default value.
00075  *
00076  * Revision 1.12  2005/11/26 09:44:24  alexis
00077  * Added node type, default, SetChild() and constructors for basic types
00078  * (i.e. SFColor, SFRotation, etc. can be reset on instantiation)
00079  *
00080  * Revision 1.11  2005/11/26 02:13:40  alexis
00081  * Fixed the array size computation.
00082  * Changed the AddRef()/Release() calls so the caller test whether the pointer
00083  * is null (because C++ does not always give you a null pointer when calling
00084  * a function in an object which has multiple inheritance!)
00085  *
00086  * Revision 1.10  2005/11/25 08:13:27  alexis
00087  * Made the f_data field of the FieldInfo non-constant.
00088  *
00089  * Revision 1.9  2005/11/25 06:45:31  alexis
00090  * StringTo[M]Value and base set, array and vector copy operators
00091  *
00092  * Revision 1.8  2005/11/25 01:20:23  alexis
00093  * Changed the user instantiate_t function type into a callback class
00094  *
00095  * Revision 1.7  2005/11/25 00:37:45  alexis
00096  * Moved the { of the namespace
00097  *
00098  * Revision 1.6  2005/11/24 22:15:34  alexis
00099  * GetType() & GetField() definitions
00100  *
00101  * Revision 1.5  2005/11/24 11:02:25  alexis
00102  * Added a comment
00103  *
00104  * Revision 1.4  2005/11/24 04:52:07  alexis
00105  * Mainly added missing code (SFImage, SMNode)
00106  * Made the SFNode inherit the the object reference so it can be used in
00107  * a smart pointer (important to have nodes all over the place).
00108  *
00109  * Revision 1.3  2005/11/24 03:54:30  alexis
00110  * Removed the X3DMetadataObject sample
00111  *
00112  * Revision 1.2  2005/11/24 01:13:24  alexis
00113  * Added the set_default() functions.
00114  *
00115  * Revision 1.1  2005/11/23 22:23:15  alexis
00116  * Renamed the x3d_node.h to node.h
00117  *
00118  * Revision 1.5  2005/11/23 01:52:54  alexis
00119  * Compiling version
00120  *
00121  * Revision 1.4  2005/11/22 22:39:57  alexis
00122  * Fixed the #ifdef/#endif label
00123  *
00124  * Revision 1.3  2005/11/22 22:10:19  alexis
00125  * Ready to be compiled...
00126  *
00127  * Revision 1.2  2005/11/22 21:56:39  alexis
00128  * Update
00129  *
00130  * Revision 1.1  2005/11/22 21:10:46  alexis
00131  * Adding a new node header (in place of x3d_types.h)
00132  * And an implementation of some of the functions.
00133  *
00134  * Revision 1.2  2005/11/22 07:55:16  alexis
00135  * Made functions uppercase
00136  *
00137  * Revision 1.1  2005/11/22 02:15:26  alexis
00138  * Missing licenses
00139  * X3D type header file (1st version; compiles but missing the "bag"
00140  * functionality)
00141  *
00142  *
00143  */
00144 #ifndef __LIBX3D_NODE_H__
00145 #define __LIBX3D_NODE_H__
00146 
00147 #include        "smartpointers.h"
00148 
00149 #include        <assert.h>
00150 #include        <math.h>
00151 #include        <stdlib.h>
00152 #include        <stdio.h>
00153 #include        <stdint.h>
00154 #include        <string.h>
00155 #include        <wchar.h>
00156 #include        <wctype.h>
00157 
00158 
00159 namespace x3d
00160 {
00161 
00162 // **********************************************************************
00163 // EXCEPTION OBJECT
00164 // **********************************************************************
00165 /// A very few functions, when they come to a tie, will throw this error
00166 class Error
00167 {
00168 public:
00169                                 Error(const char *message)
00170                                 {
00171                                         int l = strlen(message) + 1;
00172                                         f_message = new char[l];
00173                                         memcpy(f_message, message, l);
00174 #ifdef DEBUG
00175 fprintf(stderr, "throw [new] Error(\"%s\");\n", f_message);
00176 #endif
00177                                 }
00178                                 ~Error()
00179                                 {
00180                                         delete [] f_message;
00181                                 }
00182 
00183         const char *            GetMessage(void) const { return f_message; }
00184 
00185 private:
00186         char *                  f_message;
00187 };
00188 
00189 
00190 
00191 // **********************************************************************
00192 // BASIC TEMPLATES
00193 // **********************************************************************
00194 
00195 // T -- class from which we want an array; type must be simple (int, float, ...)
00196 // step -- the number of items to create each time we enlarge the array
00197 /// The basic template used to create arrays
00198 template<class T, int step> class BaseSet
00199 {
00200 public:
00201                         BaseSet(void)
00202                         {
00203                                 f_count = 0;
00204                                 f_max = 0;
00205                                 f_array = 0;
00206                         }
00207                         BaseSet(const BaseSet& src)
00208                         {
00209                                 f_count = 0;
00210                                 f_max = 0;
00211                                 f_array = 0;
00212                                 if(src.f_count > 0) {
00213                                         MinimumSize(src.f_count);
00214                                         memcpy(f_array, src.f_array, src.f_count * sizeof(T));
00215                                         f_count = src.f_count;
00216                                 }
00217                         }
00218                         ~BaseSet()
00219                         {
00220                                 delete [] f_array;
00221                         }
00222         BaseSet&        operator = (const BaseSet& src)
00223                         {
00224                                 MinimumSize(src.f_count);
00225                                 memcpy(f_array, src.f_array, src.f_count * sizeof(T));
00226                                 f_count = src.f_count;
00227                                 return *this;
00228                         }
00229         bool            operator == (const BaseSet& src) const
00230                         {
00231                                 if(f_count != src.f_count) {
00232                                         return false;
00233                                 }
00234                                 return memcmp(f_array, src.f_array, f_count * sizeof(T)) == 0;
00235                         }
00236         bool            operator != (const BaseSet& src) const
00237                         {
00238                                 if(f_count != src.f_count) {
00239                                         return true;
00240                                 }
00241                                 return memcmp(f_array, src.f_array, f_count * sizeof(T)) != 0;
00242                         }
00243         void            Empty()
00244                         {
00245                                 delete [] f_array;
00246                                 f_count = 0;
00247                                 f_max = 0;
00248                                 f_array = 0;
00249                         }
00250         void            Reset()
00251                         {
00252                                 f_count = 0;
00253                         }
00254         bool            IsEmpty() const
00255                         {
00256                                 return f_count == 0;
00257                         }
00258         unsigned int    Count() const
00259                         {
00260                                 return f_count;
00261                         }
00262         T *             GetData() const
00263                         {
00264                                 return f_array;
00265                         }
00266         T&              Get(unsigned int idx) const
00267                         {
00268                                 assert(idx < f_count);
00269                                 return f_array[idx];
00270                         }
00271         void            Set(unsigned int idx, const T& item)
00272                         {
00273                                 assert(idx < f_count);
00274                                 f_array[idx] = item;
00275                         }
00276         void            Insert(int idx, const T& item)
00277                         {
00278                                 if((unsigned int) idx >= f_count) {
00279                                         idx = f_count;
00280                                 }
00281                                 MinimumSize(f_count + 1);
00282                                 if(static_cast<unsigned int>(idx) < f_count) {
00283                                         memmove(f_array + idx + 1, f_array + idx, (f_count - idx) * sizeof(T));
00284                                 }
00285                                 f_array[idx] = item;
00286                                 ++f_count;
00287                         }
00288         void            Delete(unsigned int idx)
00289                         {
00290                                 assert(idx < f_count);
00291                                 --f_count;
00292                                 if(idx < f_count) {
00293                                         memmove(f_array + idx, f_array + idx + 1, (f_count - idx) * sizeof(T));
00294                                 }
00295                         }
00296 
00297 private:
00298         void            MinimumSize(unsigned int size)
00299                         {
00300                                 if(size > f_max) {
00301                                         // we assume step > 0
00302                                         size = size + step - 1;
00303                                         size -= size % step;
00304                                         T *n = new T[size];
00305                                         if(f_count > 0) {
00306                                                 memcpy(n, f_array, f_count * sizeof(T));
00307                                         }
00308                                         delete [] f_array;
00309                                         f_array = n;
00310                                         f_max = size;
00311                                 }
00312                         }
00313 
00314         unsigned int    f_count;
00315         unsigned int    f_max;
00316         T *             f_array;
00317 };
00318 
00319 
00320 /// The Array is a specialization of the BaseSet<T, step> template for basic types (i.e. bool, double, float, int, structures thereof)
00321 template<class T, int step> class Array : private BaseSet<T, step>
00322 {
00323 public:
00324         typedef T       element_t;
00325 
00326                         Array()
00327                                 : BaseSet<T, step>()
00328                         {
00329                         }
00330                         Array(const Array& src)
00331                                 : BaseSet<T, step>(src)
00332                         {
00333                         }
00334                         ~Array()
00335                         {
00336                         }
00337         Array&          operator = (const Array& src)
00338                         {
00339                                 BaseSet<T, step>::operator = (src);
00340                                 return *this;
00341                         }
00342         bool            operator == (const Array& src) const
00343                         {
00344                                 return BaseSet<T, step>::operator == (src);
00345                         }
00346         bool            operator != (const Array& src) const
00347                         {
00348                                 return BaseSet<T, step>::operator != (src);
00349                         }
00350         void            Empty()
00351                         {
00352                                 BaseSet<T, step>::Empty();
00353                         }
00354         void            Reset()
00355                         {
00356                                 BaseSet<T, step>::Reset();
00357                         }
00358         bool            IsEmpty() const
00359                         {
00360                                 return BaseSet<T, step>::IsEmpty();
00361                         }
00362         unsigned int    Count() const
00363                         {
00364                                 return BaseSet<T, step>::Count();
00365                         }
00366         T *             GetData() const
00367                         {
00368                                 return BaseSet<T, step>::GetData();
00369                         }
00370         T&              Get(unsigned int idx) const
00371                         {
00372                                 return BaseSet<T, step>::Get(idx);
00373                         }
00374         void            Set(unsigned int idx, const T& item)
00375                         {
00376                                 BaseSet<T, step>::Set(idx, item);
00377                         }
00378         void            Insert(int idx, const T& item)
00379                         {
00380                                 BaseSet<T, step>::Insert(idx, item);
00381                         }
00382         void            Delete(unsigned int idx)
00383                         {
00384                                 BaseSet<T, step>::Delete(idx);
00385                         }
00386 };
00387 
00388 
00389 /// The Vector is a specialization of the BaseSet<T, step> template for complex types (i.e. SFString, SFImage, SFNode)
00390 template<class T, int step> class Vector : private BaseSet<T *, step>
00391 {
00392 public:
00393         //typedef T     element_t;
00394 
00395                         Vector()
00396                                 : BaseSet<T *, step>()
00397                         {
00398                         }
00399                         Vector(const Vector& src)
00400                                 : BaseSet<T *, step>(src)
00401                         {
00402                                 unsigned int idx = BaseSet<T *, step>::Count();
00403                                 while(idx > 0) {
00404                                         idx--;
00405                                         if(BaseSet<T *, step>::Get(idx) != 0) {
00406                                                 BaseSet<T *, step>::Get(idx)->AddRef();
00407                                         }
00408                                 }
00409                         }
00410                         ~Vector()
00411                         {
00412                                 // needed to call the Release()
00413                                 Empty();
00414                         }
00415         Vector&         operator = (const Vector& src)
00416                         {
00417                                 Empty();
00418                                 BaseSet<T *, step>::operator = (src);
00419                                 unsigned int idx = BaseSet<T *, step>::Count();
00420                                 while(idx > 0) {
00421                                         idx--;
00422                                         if(BaseSet<T *, step>::Get(idx) != 0) {
00423                                                 BaseSet<T *, step>::Get(idx)->AddRef();
00424                                         }
00425                                 }
00426                                 return *this;
00427                         }
00428         bool            operator == (const Vector& src) const
00429                         {
00430                                 unsigned int idx = BaseSet<T *, step>::Count();
00431                                 if(idx != src.Count()) {
00432                                         return false;
00433                                 }
00434                                 while(idx > 0) {
00435                                         idx--;
00436                                         if(*BaseSet<T *, step>::Get(idx) != *src.Get(idx)) {
00437                                                 return false;
00438                                         }
00439                                 }
00440                                 return true;
00441                         }
00442         bool            operator != (const Vector& src) const
00443                         {
00444                                 return !operator == (src);
00445                         }
00446         void            Empty()
00447                         {
00448                                 unsigned int idx = BaseSet<T *, step>::Count();
00449                                 while(idx > 0) {
00450                                         idx--;
00451                                         if(BaseSet<T *, step>::Get(idx) != 0) {
00452                                                 BaseSet<T *, step>::Get(idx)->Release();
00453                                         }
00454                                 }
00455                                 BaseSet<T *, step>::Empty();
00456                         }
00457         void            Reset()
00458                         {
00459                                 unsigned int idx = BaseSet<T *, step>::Count();
00460                                 while(idx > 0) {
00461                                         idx--;
00462                                         if(BaseSet<T *, step>::Get(idx) != 0) {
00463                                                 BaseSet<T *, step>::Get(idx)->Release();
00464                                         }
00465                                 }
00466                                 BaseSet<T *, step>::Reset();
00467                         }
00468         bool            IsEmpty() const
00469                         {
00470                                 return BaseSet<T *, step>::IsEmpty();
00471                         }
00472         unsigned int    Count() const
00473                         {
00474                                 return BaseSet<T *, step>::Count();
00475                         }
00476         T *             Get(unsigned int idx) const
00477                         {
00478                                 return BaseSet<T *, step>::Get(idx);
00479                         }
00480         void            Set(unsigned int idx, const T *item)
00481                         {
00482                                 if(item != 0) {
00483                                         item->AddRef();
00484                                 }
00485                                 if(BaseSet<T *, step>::Get(idx) != 0) {
00486                                         BaseSet<T *, step>::Get(idx)->Release();
00487                                 }
00488                                 BaseSet<T *, step>::Set(idx, item);
00489                         }
00490         void            Insert(int idx, T& item)
00491                         {
00492                                 if(&item != 0) {
00493                                         item.AddRef();
00494                                 }
00495                                 BaseSet<T *, step>::Insert(idx, &item);
00496                         }
00497         void            Insert(int idx, T *item)
00498                         {
00499                                 if(item != 0) {
00500                                         item->AddRef();
00501                                 }
00502                                 BaseSet<T *, step>::Insert(idx, item);
00503                         }
00504         void            Delete(unsigned int idx)
00505                         {
00506                                 if(BaseSet<T *, step>::Get(idx) != 0) {
00507                                         BaseSet<T *, step>::Get(idx)->Release();
00508                                 }
00509                                 BaseSet<T *, step>::Delete(idx);
00510                         }
00511 };
00512 
00513 
00514 
00515 
00516 // **********************************************************************
00517 // BASIC TYPES
00518 // **********************************************************************
00519 
00520 
00521 // The type and name of a field is represented by an integer.
00522 // The field facilities can be used to get the corresponding UTF-8 name.
00523 // The user can create new types and names at run time by calling a
00524 // registration function.
00525 typedef int             field_t;
00526 
00527 // a few internal types
00528 static const field_t            FLD_INVALID = -1;
00529 static const field_t            FLD_UNKNOWN = 0;
00530 static const field_t            FLD_NULL = 1;
00531 
00532 static const field_t            FLD_SYSTEM_NAMES = 256;
00533 static const field_t            FLD_USER_TYPES = 0x2000;        // first user type -- use RegisterUserType()
00534 static const field_t            FLD_USER_NAMES = 0x8000;        // first user name -- use RegisterUserName()
00535 
00536 // X3D predefined types (cannot instanciate directly)
00537 static const field_t            FLD_SFBOOL = 16;
00538 static const field_t            FLD_MFBOOL = 17;
00539 static const field_t            FLD_SFCOLOR = 18;
00540 static const field_t            FLD_MFCOLOR = 19;
00541 static const field_t            FLD_SFCOLORRGBA = 20;
00542 static const field_t            FLD_MFCOLORRGBA = 21;
00543 static const field_t            FLD_SFDOUBLE = 22;
00544 static const field_t            FLD_MFDOUBLE = 23;
00545 static const field_t            FLD_SFFLOAT = 24;
00546 static const field_t            FLD_MFFLOAT = 25;
00547 static const field_t            FLD_SFIMAGE = 26;
00548 static const field_t            FLD_MFIMAGE = 27;
00549 static const field_t            FLD_SFINT32 = 28;
00550 static const field_t            FLD_MFINT32 = 29;
00551 static const field_t            FLD_SFNODE = 30;                        // a collection of any other object
00552 static const field_t            FLD_MFNODE = 31;                        // an array of collections!
00553 static const field_t            FLD_SFROTATION = 32;
00554 static const field_t            FLD_MFROTATION = 33;
00555 static const field_t            FLD_SFSTRING = 34;
00556 static const field_t            FLD_MFSTRING = 35;
00557 static const field_t            FLD_SFTIME = 36;
00558 static const field_t            FLD_MFTIME = 37;
00559 static const field_t            FLD_SFVEC2D = 38;
00560 static const field_t            FLD_MFVEC2D = 39;
00561 static const field_t            FLD_SFVEC2F = 40;
00562 static const field_t            FLD_MFVEC2F = 41;
00563 static const field_t            FLD_SFVEC3D = 42;
00564 static const field_t            FLD_MFVEC3D = 43;
00565 static const field_t            FLD_SFVEC3F = 44;
00566 static const field_t            FLD_MFVEC3F = 45;
00567 
00568 
00569 
00570 // Unless otherwise noted, the default values are all zero (0 or 0.0)
00571 // These are very simple types so arrays of these types are as compact
00572 // as possible for the type.
00573 typedef bool            SFBool;
00574 typedef double          SFDouble;
00575 typedef float           SFFloat;
00576 typedef int32_t         SFInt32;
00577 typedef double          SFTime;         // default -1.0
00578 
00579 
00580 struct SFColor
00581 {
00582                         SFColor() {}
00583                         SFColor(float red, float green, float blue) { f_red = red; f_green = green; f_blue = blue; }
00584         void            set_default() { f_red = f_green = f_blue = 0.0f; }
00585         float           f_red;
00586         float           f_green;
00587         float           f_blue;
00588 };
00589 
00590 struct SFColorRGBA
00591 {
00592                         SFColorRGBA() {}
00593                         SFColorRGBA(float red, float green, float blue, float alpha)
00594                                 { f_red = red; f_green = green; f_blue = blue; f_alpha = alpha; }
00595         void            set_default() { f_red = f_green = f_blue = f_alpha = 0.0f; }
00596         float           f_red;
00597         float           f_green;
00598         float           f_blue;
00599         float           f_alpha;
00600 };
00601 
00602 struct SFRotation
00603 {
00604                         SFRotation() {}
00605                         SFRotation(float x, float y, float z, float angle) { f_x = x; f_y = y; f_z = z; f_angle = angle; }
00606         void            set_default() { f_x = f_y = f_angle = 0.0f; f_z = 1.0f; }
00607         float           f_x;
00608         float           f_y;
00609         float           f_z;
00610         float           f_angle;
00611 };
00612 
00613 
00614 struct SFVec2d
00615 {
00616                         SFVec2d() {}
00617                         SFVec2d(double x, double y) { f_x = x; f_y = y; }
00618         void            set_default() { f_x = f_y = 0.0; }
00619         double          f_x;
00620         double          f_y;
00621 };
00622 
00623 struct SFVec2f
00624 {
00625                         SFVec2f() {}
00626                         SFVec2f(float x, float y) { f_x = x; f_y = y; }
00627         void            set_default() { f_x = f_y = 0.0f; }
00628         float           f_x;
00629         float           f_y;
00630 };
00631 
00632 struct SFVec3d
00633 {
00634                         SFVec3d() {}
00635                         SFVec3d(double x, double y, double z) { f_x = x; f_y = y; f_z = z; }
00636         void            set_default() { f_x = f_y = f_z = 0.0; }
00637         double          f_x;
00638         double          f_y;
00639         double          f_z;
00640 };
00641 
00642 struct SFVec3f
00643 {
00644                         SFVec3f() {}
00645                         SFVec3f(float x, float y, float z) { f_x = x; f_y = y; f_z = z; }
00646         void            set_default() { f_x = f_y = f_z = 0.0f; }
00647         float           f_x;
00648         float           f_y;
00649         float           f_z;
00650 };
00651 
00652 
00653 // TODO: adjust the 2nd template parameter according to the type
00654 typedef Array<SFBool, 256>      MFBool;         // we could later have a way to use bits instead
00655 typedef Array<SFColor, 256>     MFColor;
00656 typedef Array<SFColorRGBA, 256> MFColorRGBA;
00657 typedef Array<SFDouble, 256>    MFDouble;
00658 typedef Array<SFFloat, 256>     MFFloat;
00659 typedef Array<SFInt32, 256>     MFInt32;
00660 typedef Array<SFRotation, 256>  MFRotation;
00661 typedef Array<SFTime, 256>      MFTime;
00662 typedef Array<SFVec2d, 256>     MFVec2d;
00663 typedef Array<SFVec2f, 256>     MFVec2f;
00664 typedef Array<SFVec3d, 256>     MFVec3d;
00665 typedef Array<SFVec3f, 256>     MFVec3f;
00666 
00667 
00668 
00669 
00670 // **********************************************************************
00671 // COMPLEX TYPES (String, Image)
00672 // **********************************************************************
00673 
00674 
00675 // UTF-8 strings (c_str() always returns a non-null pointer to a null terminated string pointer)
00676 class SFString : public pointer::ReferencedObject
00677 {
00678 public:
00679                                 SFString(void) { f_size = 0; f_str = const_cast<char *>(g_empty); }
00680                                 SFString(const SFString& src) { f_size = 0; f_str = const_cast<char *>(g_empty); Set(src.f_str); }
00681                                 SFString(const char *str, int len = -1) { f_size = 0; f_str = const_cast<char *>(g_empty); Set(str); }
00682                                 ~SFString() { if(f_str != g_empty) { delete [] f_str; } }
00683         SFString&               operator = (const SFString& src) { if(this != &src) { Set(src.f_str); } return *this; }
00684         SFString&               operator = (const char *str) { Set(str); return *this; }
00685 
00686         bool                    operator == (const SFString& src) const { return strcmp(f_str, src.f_str) == 0; }
00687         bool                    operator == (const char *str) const { return strcmp(f_str, str) == 0; }
00688         bool                    operator != (const SFString& src) const { return strcmp(f_str, src.f_str) != 0; }
00689         bool                    operator != (const char *str) const { return strcmp(f_str, str) != 0; }
00690         bool                    operator <= (const SFString& src) const { return strcmp(f_str, src.f_str) <= 0; }
00691         bool                    operator <  (const char *str) const { return strcmp(f_str, str) < 0; }
00692         bool                    operator >= (const SFString& src) const { return strcmp(f_str, src.f_str) >= 0; }
00693         bool                    operator >  (const char *str) const { return strcmp(f_str, str) > 0; }
00694 
00695         SFString                operator + (const SFString& src) const { SFString temp(*this); temp.Append(src.f_str); return temp; }
00696         SFString                operator + (const char *str) const { SFString temp(*this); temp.Append(str); return temp; }
00697         SFString&               operator += (const SFString& src) { Append(src.f_str); return *this; }
00698         SFString&               operator += (const char *str) { Append(str); return *this; }
00699 
00700         void                    Empty(void) { Set(0); }
00701         bool                    IsEmpty(void) const { return f_size == 0; }
00702         void                    SetValue(const SFString& src) { Set(src.f_str); }
00703         void                    SetValue(const char *str) { Set(str); }
00704         void                    SetValue(const wchar_t *str);
00705         void                    GetValue(char *str, int size);
00706         void                    GetValue(wchar_t *str, int size);
00707 
00708         int                     Size(void) const { return f_size; }
00709         const char *            c_str(void) const { return f_str; }
00710         void                    Append(const SFString& src) { Append(src.f_str); }
00711         void                    Append(const char *str);
00712 
00713         SFString                Escape(void) const;
00714         SFString                Unescape(void) const;
00715 
00716 private:
00717         // later we should have a reference counted buffer for the string data
00718         // (like in std::string)
00719         void                    Set(const char *str, int len = -1);
00720 
00721         static const char       g_empty[1];
00722 
00723         int                     f_size;
00724         char *                  f_str;
00725 };
00726 typedef pointer::SmartPointer<SFString>         SFStringPtr;
00727 typedef Vector<SFString, 24>                    MFString;
00728 
00729 
00730 
00731 class SFImage : public pointer::ReferencedObject
00732 {
00733 public:
00734         // IMPORTANT NOTE:
00735         //      We assume that in memory the components are stored in order (RGBA)
00736         //      That way there will be no endianess problem at run time (i.e. in
00737         //      big or little endian, OpenGL understands RGBA like us: red first,
00738         //      then green, a little bit of blue and finally alpha).
00739         //      To load and save images to XML files, however, we will need to
00740         //      convert the value properly.
00741         //
00742         //      uint8_t *p = my_image.getpixels();
00743         //      int red   = p[0];
00744         //      int green = p[1];
00745         //      int blue  = p[2];
00746         //      int alpha = p[3];
00747         //
00748 
00749         // the number of components in the image (or depth) determines its type
00750         enum {
00751                 SFIMAGE_TYPE_LUMINANCE = 1,
00752                 SFIMAGE_TYPE_LUMINANCE_ALPHA = 2,
00753                 SFIMAGE_TYPE_RGB = 3,
00754                 SFIMAGE_TYPE_RGBA = 4,
00755         };
00756 
00757                         SFImage(void) { f_width = f_height = f_components = f_size = 0; f_pixels = 0; }
00758                         SFImage(const SFImage& src)
00759                         {
00760                                 f_width = src.f_width;
00761                                 f_height = src.f_height;
00762                                 f_components = src.f_components;
00763                                 f_size = 0;
00764                                 f_pixels = 0;
00765                                 ResizeBuffer();
00766                                 if(f_size > 0) {
00767                                         memcpy(f_pixels, src.f_pixels, f_size);
00768                                 }
00769                         }
00770                         ~SFImage() { delete [] f_pixels; }
00771 
00772         void            Empty(void) { delete [] f_pixels; f_width = f_height = f_components = f_size = 0; f_pixels = 0; }
00773         bool            IsEmpty(void) const { return f_size == 0; }
00774         void            Clear(void) { if(f_size) { memset(f_pixels, 0, f_size); } }
00775         void            SetSize(int width, int height, int components) { f_width = width; f_height = height; f_components = components; ResizeBuffer(); }
00776         void            SetWidth(int width) { f_width = width; ResizeBuffer(); }
00777         void            SetHeight(int height) { f_height = height; ResizeBuffer(); }
00778         void            SetComponents(int components) { f_components = components; ResizeBuffer(); }
00779         int             GetWidth(void) const { return f_width; }
00780         int             GetHeight(void) const { return f_height; }
00781         int             GetComponents(void) const { return f_components; }
00782         int             GetBuffersize(void) const { return f_size; }
00783         uint8_t *       GetPixels(void) { return f_pixels; }
00784         const uint8_t * GetPixels(void) const { return f_pixels; }
00785 
00786 private:
00787         void            ResizeBuffer(void)
00788                         {
00789                                 uint8_t *old_pixels = f_pixels;
00790                                 int old_size = f_size;
00791                                 f_size = f_width * f_height * f_components;
00792                                 if(f_size > 0) {
00793                                         f_pixels = new uint8_t[f_size];
00794                                         int l = old_size > f_size ? f_size : old_size;
00795                                         if(old_pixels) {
00796                                                 // copy the old pixels (probably useless...)
00797                                                 memcpy(f_pixels, old_pixels, l);
00798                                         }
00799                                         // TODO: the reference doesn't specify whether we should
00800                                         //       clear the pixels...
00801                                         //memset(f_pixels + l, 0, f_size - l);
00802                                 }
00803                                 else {
00804                                         f_pixels = 0;
00805                                 }
00806                                 delete [] old_pixels;
00807                         }
00808 
00809         int             f_width;
00810         int             f_height;
00811         int             f_components;
00812         int             f_size;         // the current size
00813         uint8_t *       f_pixels;       // size = f_width * f_height * f_components
00814 };
00815 typedef pointer::SmartPointer<SFImage>          SFImagePtr;
00816 typedef Vector<SFImage, 2>                      MFImage;
00817 
00818 
00819 
00820 
00821 
00822 // **********************************************************************
00823 // NODE
00824 // **********************************************************************
00825 
00826 class SFNode;
00827 typedef Vector<SFNode, 20>              MFNode;
00828 
00829 
00830 
00831 
00832 /// The structure used to get and set field values (see also the get_ and set_ functions)
00833 struct FieldInfo
00834 {
00835         union {
00836                 void *          f_any;
00837                 SFBool *        f_SFBool;
00838                 MFBool *        f_MFBool;
00839                 SFColor *       f_SFColor;
00840                 MFColor *       f_MFColor;
00841                 SFColorRGBA *   f_SFColorRGBA;
00842                 MFColorRGBA *   f_MFColorRGBA;
00843                 SFDouble *      f_SFDouble;
00844                 MFDouble *      f_MFDouble;
00845                 SFFloat *       f_SFFloat;
00846                 MFFloat *       f_MFFloat;
00847                 SFImage *       f_SFImage;
00848                 MFImage *       f_MFImage;
00849                 SFInt32 *       f_SFInt32;
00850                 MFInt32 *       f_MFInt32;
00851                 SFNode *        f_SFNode;
00852                 MFNode *        f_MFNode;
00853                 SFRotation *    f_SFRotation;
00854                 MFRotation *    f_MFRotation;
00855                 SFString *      f_SFString;
00856                 MFString *      f_MFString;
00857                 SFTime *        f_SFTime;
00858                 MFTime *        f_MFTime;
00859                 SFVec2d *       f_SFVec2d;
00860                 MFVec2d *       f_MFVec2d;
00861                 SFVec2f *       f_SFVec2f;
00862                 MFVec2f *       f_MFVec2f;
00863                 SFVec3d *       f_SFVec3d;
00864                 MFVec3d *       f_MFVec3d;
00865                 SFVec3f *       f_SFVec3f;
00866                 MFVec3f *       f_MFVec3f;
00867         } f_data;
00868         field_t         f_type;
00869         field_t         f_name;
00870 };
00871 
00872 
00873 /// Interface used to listen to all modifications to any node
00874 class SFNodeListener : public pointer::ReferencedObject
00875 {
00876 public:
00877         virtual                 ~SFNodeListener();
00878 
00879         virtual void            SFNodeListener_Destroyed(SFNode *node);
00880         virtual void            SFNodeListener_FieldChanged(SFNode *node, const FieldInfo *info);
00881 };
00882 typedef pointer::SmartPointer<SFNodeListener>   SFNodeListenerPtr;
00883 typedef Vector<SFNodeListener, 6>               MFNodeListener;
00884 
00885 
00886 
00887 /// All the non-abstract nodes in the X3D set derive once from SFNode
00888 class SFNode : public pointer::ReferencedObject
00889 {
00890 public:
00891         virtual                 ~SFNode();
00892 
00893         virtual bool            IsNodeType(field_t type) const;
00894         virtual field_t         GetNodeType(int idx = 0) const;
00895         virtual int             GetTypeCount() const;
00896         virtual const char *    GetNodeName() const;
00897 
00898         virtual bool            GetFieldDefault(field_t name, FieldInfo *info) const;
00899         virtual bool            FieldHasDefaultValue(field_t name) const;
00900         virtual bool            GetFieldByName(field_t name, FieldInfo *info) const;
00901         virtual bool            GetFieldByIndex(int idx, FieldInfo *info) const;
00902         virtual int             GetFieldCount() const;
00903         virtual field_t         GetDefaultContainerField() const;
00904         virtual const char *    GetDefaultContainerFieldName() const;
00905 
00906         virtual bool            SetFieldByName(field_t name, const void *data);
00907         field_t                 SetFieldByName(const char *name, const char *data);
00908         field_t                 SetChild(SFNode *child, const char *containerField, bool insert = true);
00909         field_t                 SetChild(SFNode *child, field_t name, bool insert);
00910 
00911         void                    RegisterListener(SFNodeListener *listener);
00912         bool                    UnregisterListener(SFNodeListener *listener);
00913 
00914 protected:
00915         void                    Event_FieldChanged(const FieldInfo *info);
00916 
00917 private:
00918         void                    Event_Destroyed();
00919 
00920         MFNodeListener          f_listener;
00921 };
00922 typedef pointer::SmartPointer<SFNode>   SFNodePtr;
00923 
00924 
00925 
00926 
00927 class UserType
00928 {
00929 public:
00930         virtual                 ~UserType();
00931 
00932         virtual void *          CreateField(void) = 0;
00933         virtual void            DestroyField(void *field) = 0;
00934         virtual bool            StringToValue(void *value, const char *& str) = 0;
00935         virtual bool            ValueToString(void *value, const char *& str) = 0;
00936 };
00937 
00938 
00939 
00940 extern  field_t                 RegisterUserType(const char *type, UserType *user_type);
00941 extern  field_t                 RegisterUserName(const char *name);
00942 extern  const char *            GetName(field_t id);
00943 extern  int                     CompareName(const char *n1, const char *n2);
00944 
00945 extern  field_t                 GetField(const char *name);
00946 extern  field_t                 GetType(const char *name);
00947 
00948 
00949 extern  SFNode *                CreateNode(field_t type);
00950 
00951 // you can create your own instantitor
00952 class Instantiator
00953 {
00954 public:
00955         virtual                 ~Instantiator();
00956         virtual SFNode *        CreateNode(field_t type) = 0;
00957 };
00958 extern  void                    RegisterType(field_t type, Instantiator *instantiator);
00959 
00960 
00961 
00962 template<class MF>
00963 bool StringToMValue(MF& value, const char *& str)
00964 {
00965         typename MF::element_t item;
00966 
00967         value.Empty();
00968         while(StringToValue(item, str)) {
00969                 value.Insert(-1, item);
00970         }
00971 
00972         return true;
00973 }
00974 
00975 extern  bool                    StringToMValue(MFString& value, const char *& str);
00976 
00977 extern  bool                    StringToValue(SFBool& value, const char *& str);
00978 extern  bool                    StringToValue(SFColor& value, const char *& str);
00979 extern  bool                    StringToValue(SFColorRGBA& value, const char *& str);
00980 extern  bool                    StringToValue(SFDouble& value, const char *& str);
00981 extern  bool                    StringToValue(SFFloat& value, const char *& str);
00982 extern  bool                    StringToValue(SFImage& value, const char *& str);
00983 extern  bool                    StringToValue(SFInt32& value, const char *& str);
00984 extern  bool                    StringToValue(SFRotation& value, const char *& str);
00985 //extern bool                   StringToValue(SFTime& value, const char *& str); -- SFTime == SFDouble
00986 extern  bool                    StringToValue(SFVec2d& value, const char *& str);
00987 extern  bool                    StringToValue(SFVec2f& value, const char *& str);
00988 extern  bool                    StringToValue(SFVec3d& value, const char *& str);
00989 extern  bool                    StringToValue(SFVec3f& value, const char *& str);
00990 
00991 
00992 
00993 
00994 
00995 template<class MF>
00996 void MValueToString(const MF& value, SFString& str)
00997 {
00998         str.Empty();
00999         int max = value.Count();
01000         for(int idx = 0; idx < max; ++idx) {
01001                 SFString item_str;
01002                 ValueToString(value.Get(idx), item_str);
01003                 if(idx != 0) {
01004                         str += " ";
01005                 }
01006                 str += item_str;
01007         }
01008 }
01009 
01010 extern  void                    MValueToString(const MFString& value, SFString& str);
01011 
01012 extern  bool                    ValueToString(const FieldInfo *info, SFString& str);
01013 
01014 extern  void                    ValueToString(SFBool value, SFString& str);
01015 extern  void                    ValueToString(const SFColor& value, SFString& str);
01016 extern  void                    ValueToString(const SFColorRGBA& value, SFString& str);
01017 extern  void                    ValueToString(SFDouble value, SFString& str);
01018 extern  void                    ValueToString(SFFloat value, SFString& str);
01019 extern  void                    ValueToString(const SFImage& value, SFString& str);
01020 extern  void                    ValueToString(SFInt32 value, SFString& str);
01021 extern  void                    ValueToString(const SFRotation& value, SFString& str);
01022 //extern void                   ValueToString(SFTime& value, SFString& str); -- SFTime == SFDouble
01023 extern  void                    ValueToString(const SFVec2d& value, SFString& str);
01024 extern  void                    ValueToString(const SFVec2f& value, SFString& str);
01025 extern  void                    ValueToString(const SFVec3d& value, SFString& str);
01026 extern  void                    ValueToString(const SFVec3f& value, SFString& str);
01027 
01028 
01029 // **********************************************************************
01030 // LEVEL OF SUPPORT
01031 // **********************************************************************
01032 /// An object which will give you the level of support of the different components of the library
01033 class LevelOfSupport
01034 {
01035 public:
01036         virtual                 ~LevelOfSupport();
01037 
01038         virtual SFInt32         get_level(SFInt32 name) const = 0;
01039         static SFInt32          get_max_level(SFInt32 name);
01040 };
01041 
01042 extern  LevelOfSupport *        GetBaseSupport();
01043 
01044 
01045 
01046 
01047 
01048 
01049 
01050 };              // namespace x3d
01051 
01052 
01053 
01054 // vim: ts=8
01055 #endif          // #ifndef __LIBX3D_NODE_H__

00021 * $Id: node.h,v 1.25 2005/12/19 01:31:09 alexis Exp $