Browse Source

support dcparse compress flag

David Rose 22 years ago
parent
commit
be4d4625e3

+ 15 - 1
direct/src/dcparser/dcAtomicField.cxx

@@ -240,7 +240,7 @@ end_array() {
 bool DCAtomicField::ElementType::
 format_default_value(double num, string &formatted) const {
   double real_value = num * _divisor;
-  int int_value = (int)cfloor(real_value + 0.5);
+  int int_value = (int)floor(real_value + 0.5);
 
   switch (_type) {
   case ST_int8:
@@ -564,6 +564,17 @@ is_ownsend() const {
   return (_flags & F_ownsend) != 0;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCAtomicField::is_compress
+//       Access: Public
+//  Description: Returns true if the "compress" flag is set for this
+//               field, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool DCAtomicField::
+is_compress() const {
+  return (_flags & F_compress) != 0;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::Constructor
 //       Access: Public
@@ -621,6 +632,9 @@ write(ostream &out, int indent_level) const {
   if ((_flags & F_ownsend) != 0) {
     out << " ownsend";
   }
+  if ((_flags & F_compress) != 0) {
+    out << " compress";
+  }
 
   out << ";  // field " << _number << "\n";
 }

+ 6 - 1
direct/src/dcparser/dcAtomicField.h

@@ -19,11 +19,14 @@
 #ifndef DCATOMICFIELD_H
 #define DCATOMICFIELD_H
 
-#include <cmath.h>
 #include "dcbase.h"
 #include "dcField.h"
 #include "dcSubatomicType.h"
 
+// Must use math.h instead of cmath.h so this can compile outside of
+// Panda.
+#include <math.h>
+
 ////////////////////////////////////////////////////////////////////
 //       Class : DCAtomicField
 // Description : A single atomic field of a Distributed Class, as read
@@ -50,6 +53,7 @@ PUBLISHED:
   bool is_clsend() const;
   bool is_clrecv() const;
   bool is_ownsend() const;
+  bool is_compress() const;
 
 public:
   DCAtomicField();
@@ -94,6 +98,7 @@ public:
     F_clsend          = 0x0020,
     F_clrecv          = 0x0040,
     F_ownsend         = 0x0080,
+    F_compress        = 0x0100,
   };
 
   int _flags;  // A bitmask union of any of the above values.

+ 5 - 0
direct/src/dcparser/dcLexer.lxx

@@ -471,6 +471,11 @@ mol[0-9]+ {
   return KW_OWNSEND;
 }
 
+"compress" {
+  accept();
+  return KW_COMPRESS;
+}
+
 {INTEGERNUM} { 
   // An integer number.
   accept(); 

+ 5 - 0
direct/src/dcparser/dcParser.yxx

@@ -77,6 +77,7 @@ dc_cleanup_parser() {
 %token KW_CLSEND
 %token KW_CLRECV
 %token KW_OWNSEND
+%token KW_COMPRESS
 
 %type <u.dclass> dclass_name
 %type <u.atomic> atomic_name
@@ -414,6 +415,10 @@ atomic_flags:
         | atomic_flags KW_OWNSEND
 {
   current_atomic->_flags |= DCAtomicField::F_ownsend;
+}
+        | atomic_flags KW_COMPRESS
+{
+  current_atomic->_flags |= DCAtomicField::F_compress;
 }
         ;
 

+ 0 - 6
direct/src/dcparser/dcbase.h

@@ -46,15 +46,9 @@
 #pragma warning (disable : 4503)
 #endif  /* WIN32_VC */
 
-#if defined(WIN32)
 #include <iostream>
 #include <fstream>
 #include <iomanip>
-#else
-#include <iostream.h>
-#include <fstream.h>
-#include <iomanip.h>
-#endif
 
 #include <string>
 #include <assert.h>

+ 2 - 2
direct/src/distributed/ClientDistClass.py

@@ -62,14 +62,14 @@ class ClientDistClass:
                     requiredCDU.append(i)
         return requiredCDU
 
-    def updateField(self, do, di):
+    def updateField(self, do, di, allowCompress):
         # Get the update field id
         fieldId = di.getArg(STUint16)
         # look up the CDU
         assert(self.number2CDU.has_key(fieldId))
         cdu = self.number2CDU[fieldId]
         # Let the cdu finish the job
-        cdu.updateField(self, do, di)
+        cdu.updateField(self, do, di, allowCompress)
         return None
 
     def sendUpdate(self, cr, do, fieldName, args, sendToId = None):

+ 18 - 3
direct/src/distributed/ClientDistUpdate.py

@@ -20,6 +20,7 @@ class ClientDistUpdate:
         self.name = dcField.getName()
         self.types = []
         self.divisors = []
+        self.compress = 0
         self.deriveTypesFromParticle(dcField)
         # Figure out our function pointer
         exec("import " + cdc.name, moduleGlobals, moduleLocals)
@@ -40,19 +41,24 @@ class ClientDistUpdate:
             for i in range(0, dcFieldAtomic.getNumElements()):
                 self.types.append(dcFieldAtomic.getElementType(i))
                 self.divisors.append(dcFieldAtomic.getElementDivisor(i))
+            if dcFieldAtomic.isCompress():
+                self.compress = 1
+                
         elif dcFieldMolecular:
             for i in range(0, dcFieldMolecular.getNumAtomics()):
                 componentField = dcFieldMolecular.getAtomic(i)
                 for j in range(0, componentField.getNumElements()):
                     self.types.append(componentField.getElementType(j))
                     self.divisors.append(componentField.getElementDivisor(j))
+                if componentField.isCompress():
+                    self.compress = 1
         else:
             ClientDistUpdate.notify.error("field is neither atom nor molecule")
         return None
 
-    def updateField(self, cdc, do, di):
+    def updateField(self, cdc, do, di, allowCompress):
         # Get the arguments into a list
-        args = self.extractArgs(di)
+        args = self.extractArgs(di, allowCompress)
 
         assert(self.notify.debug("Received update for %d: %s.%s(%s)" % (do.doId, cdc.name, self.name, args)))
 
@@ -61,7 +67,13 @@ class ClientDistUpdate:
             apply(self.func, [do] + args)
         return None
 
-    def extractArgs(self, di):
+    def extractArgs(self, di, allowCompress):
+        if allowCompress and self.compress:
+            # Technically, the datagram pointer is const, so this is
+            # invalid.  Ignore that for now.
+            argsAt = di.getCurrentIndex()
+            di.getDatagram().uncompress(argsAt)
+
         args = []
         assert(len(self.types) == len(self.divisors))
         numTypes = len(self.types)
@@ -88,7 +100,10 @@ class ClientDistUpdate:
         datagram.addUint32(sendToId)
         # Add the field id
         datagram.addUint16(self.number)
+        argsAt = datagram.getLength()
         # Add the arguments
         self.addArgs(datagram, args)
+        if self.compress:
+            datagram.compress(argsAt)
         # send the datagram
         cr.send(datagram)

+ 1 - 1
direct/src/distributed/ClientRepository.py

@@ -517,7 +517,7 @@ class ClientRepository(DirectObject.DirectObject):
         cdc = self.doId2cdc.get(doId)
         if (do != None and cdc != None):
             # Let the cdc finish the job
-            cdc.updateField(do, di)
+            cdc.updateField(do, di, 1)
         else:
             ClientRepository.notify.warning(
                 "Asked to update non-existent DistObj " + str(doId))

+ 4 - 4
direct/src/distributed/DistributedObject.py

@@ -182,21 +182,21 @@ class DistributedObject(PandaObject):
     
     def updateRequiredFields(self, cdc, di):
         for i in cdc.broadcastRequiredCDU:
-            i.updateField(cdc, self, di)
+            i.updateField(cdc, self, di, 0)
     
     def updateAllRequiredFields(self, cdc, di):
         for i in cdc.allRequiredCDU:
-            i.updateField(cdc, self, di)
+            i.updateField(cdc, self, di, 0)
 
     def updateRequiredOtherFields(self, cdc, di):
         # First, update the required fields
         for i in cdc.broadcastRequiredCDU:
-            i.updateField(cdc, self, di)
+            i.updateField(cdc, self, di, 0)
         # Determine how many other fields there are
         numberOfOtherFields = di.getArg(STUint16)
         # Update each of the other fields
         for i in range(numberOfOtherFields):
-            cdc.updateField(self, di)
+            cdc.updateField(self, di, 0)
         return None
 
     def sendUpdate(self, fieldName, args = [], sendToId = None):

+ 38 - 0
panda/src/express/datagram.cxx

@@ -154,3 +154,41 @@ append_data(const void *data, size_t size) {
     _data.v().push_back(source[i]);
   }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: Datagram::compress
+//       Access: Public
+//  Description: Performs a simple bit-compression on the data stored
+//               within the datagram.  Data before from_byte will be
+//               unaffected.  This will be exactly reversed by a later
+//               call to uncompress(), but you must be careful to call
+//               each function exactly once.
+////////////////////////////////////////////////////////////////////
+void Datagram::
+compress(size_t from_byte) {
+  // For now, we don't actually compress the data, but just trivially
+  // encode it.
+ 
+  char *message = (char *)get_data();
+  size_t num_bytes = get_length();
+  for (size_t i = from_byte; i < num_bytes; i++) {
+    message[i] ^= 0x55;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Datagram::uncompress
+//       Access: Public
+//  Description: Reverses the effect of a previous call to compress().
+////////////////////////////////////////////////////////////////////
+void Datagram::
+uncompress(size_t from_byte) {
+  // For now, we don't actually compress the data, but just trivially
+  // encode it.
+ 
+  char *message = (char *)get_data();
+  size_t num_bytes = get_length();
+  for (size_t i = from_byte; i < num_bytes; i++) {
+    message[i] ^= 0x55;
+  }
+}

+ 3 - 0
panda/src/express/datagram.h

@@ -93,6 +93,9 @@ PUBLISHED:
   INLINE const void *get_data() const;
   INLINE size_t get_length() const;
 
+  void compress(size_t from_byte);
+  void uncompress(size_t from_byte);
+
   INLINE bool operator == (const Datagram &other) const;
   INLINE bool operator != (const Datagram &other) const;
   INLINE bool operator < (const Datagram &other) const;