Exemple #1
0
size_t Marshal::read_from_marshal(Marshal& m, size_t n) {
    assert(m.content_size() >= n);   // require m.content_size() >= n > 0
    size_t n_fetch = 0;

    if ((head_ == nullptr && tail_ == nullptr) || tail_->fully_written()) {
        // efficiently copy data by only copying pointers
        while (n_fetch < n) {
            // NOTE: The copied chunk is shared by 2 Marshal objects. Be careful
            //       that only one Marshal should be able to write to it! For the
            //       given 2 use cases, it works.
            chunk* chnk = m.head_->shared_copy();
            if (n_fetch + chnk->content_size() > n) {
                // only fetch enough bytes we need
                chnk->write_idx -= (n_fetch + chnk->content_size()) - n;
            }
            size_t cnt = chnk->content_size();
            assert(cnt > 0);
            n_fetch += cnt;
            verify(m.head_->discard(cnt) == cnt);
            if (head_ == nullptr) {
                head_ = tail_ = chnk;
            } else {
                tail_->next = chnk;
                tail_ = chnk;
            }
            if (m.head_->fully_read()) {
                if (m.tail_ == m.head_) {
                    // deleted the only chunk
                    m.tail_ = nullptr;
                }
                chunk* next = m.head_->next;
                delete m.head_;
                m.head_ = next;
            }
        }
        write_cnt_ += n_fetch;
        content_size_ += n_fetch;
        verify(m.content_size_ >= n_fetch);
        m.content_size_ -= n_fetch;

    } else {

        // number of bytes that need to be copied
        size_t copy_n = std::min(tail_->data->size - tail_->write_idx, n);
        char* buf = new char[copy_n];
        n_fetch = m.read(buf, copy_n);
        verify(n_fetch == copy_n);
        verify(this->write(buf, n_fetch) == n_fetch);
        delete[] buf;

        size_t leftover = n - copy_n;
        if (leftover > 0) {
            verify(tail_->fully_written());
            n_fetch += this->read_from_marshal(m, leftover);
        }
    }
    assert(n_fetch == n);
    assert(content_size_ == content_size_slow());
    return n_fetch;
}
dmz::Boolean
dmz::NetModulePacketCodecBasic::_write_object (
      const Handle ObjectHandle,
      const NetObjectEncodeEnum Mode,
      Marshal &outData) {

   Boolean result (False);

   EncodeObjectStruct *eos (_objTable.lookup (ObjectHandle));

   if (eos && _headerCodec) {

      const Int32 Place (outData.get_place ());
      if (_headerCodec->write_header (eos->PacketID, outData)) {

         if (eos->codec.encode_object (ObjectHandle, Mode, outData)) {

            outData.set_place (Place);
            result = _headerCodec->write_header (eos->PacketID, outData);
         }
      }
   }

   return result;
}
Exemple #3
0
dmz::Boolean
dmz::NetExtPacketCodecObjectNative::encode_object (
      const Handle ObjectHandle,
      const NetObjectEncodeEnum EncodeMode,
      Marshal &data) {

   Boolean result (False);

   if (_attrMod && _objMod) {

      UUID objectID;

      if (_objMod->lookup_uuid (ObjectHandle, objectID)) {

         data.set_next_uuid (_SysID);
         data.set_next_uuid (objectID);

         if (EncodeMode == NetObjectDeactivate) {

            data.set_next_int8 (0);
            result = True;
         }
         else {

            const ObjectType Type (_objMod->lookup_object_type (ObjectHandle));
            ArrayUInt32 typeArray;

            if (_attrMod->to_net_object_type (Type, typeArray)) {

               const Int32 TypeSize (typeArray.get_size ());
               data.set_next_int8 (Int8 (TypeSize));

               for (Int32 ix = 0; ix < TypeSize; ix++) {

                  data.set_next_uint8 (UInt8 (typeArray.get (ix)));
               }

               ObjectAttributeAdapter *current (_adapterList);

               while (current) {

                  current->encode (ObjectHandle, *_objMod, data);
                  current = current->next;
               }

               result = True;
            }

            _objMod->store_time_stamp (
               ObjectHandle,
               _lnvHandle,
               _time.get_last_frame_time ());
         }
      }
   }

   return result;
}
template <class T> Boolean
sizeElement<T>::write_element (const UInt32 PacketID, Marshal &data) {

   T value (0);

   value = T (data.get_length ());

   MarshalWrap wrap (data);

   wrap.set_next (value);

   return True;
}
dmz::Boolean
dmz::NetModulePacketCodecBasic::encode_event (
      const EventType &Type,
      const Handle EventHandle,
      Marshal &outData) {

   Boolean result (False);

   EncodeEventStruct *ees (_eventTypeTable.lookup (Type.get_handle ()));

   if (!ees) {

      EventType current (Type); current.become_parent ();

      while (!ees && current) {

         ees = _eventTypeTable.lookup (current.get_handle ());
         current.become_parent ();
      }
   }

   if (ees && _headerCodec) {

      const Int32 Place (outData.get_place ());
      if (_headerCodec->write_header (ees->PacketID, outData)) {

         if (ees->codec.encode_event (EventHandle, outData)) {

            outData.set_place (Place);
            result = _headerCodec->write_header (ees->PacketID, outData);
         }
      }
   }

   return result;
}
dmz::Boolean
dmz::NetExtPacketCodecObjectBasic::encode_object (
      const Handle ObjectHandle,
      const NetObjectEncodeEnum EncodeMode,
      Marshal &data) {

   Boolean result (False);

   if (_attrMod && _objMod) {

      UUID uuid;

      if (_objMod->lookup_uuid (ObjectHandle, uuid)) {

         const ObjectType Type (_objMod->lookup_object_type (ObjectHandle));
         ArrayUInt32 typeArray;

         if (_attrMod->to_net_object_type (Type, typeArray)) {

            Vector pos;
            Matrix ori;
            Vector vel;
            ArrayUInt32 stateArray;
            Mask state;

            _objMod->lookup_position (ObjectHandle, _defaultHandle, pos);
            _objMod->lookup_orientation (ObjectHandle, _defaultHandle, ori);
            _objMod->lookup_velocity (ObjectHandle, _defaultHandle, vel);
            _objMod->lookup_state (ObjectHandle, _defaultHandle, state);

            if (EncodeMode == NetObjectDeactivate) {

               state |= _deactivateState;
            }

            _attrMod->to_net_object_mask (Type, state, stateArray);

            data.set_next_uuid (_SysID);
            data.set_next_uuid (uuid);
            data.set_next_vector (pos);
            data.set_next_matrix (ori);
            data.set_next_vector (vel);
            data.set_next_uint32 (typeArray.get (0));
            data.set_next_uint32 (typeArray.get (1));
            data.set_next_uint32 (typeArray.get (2));
            data.set_next_uint32 (stateArray.get (0));

            const Int32 Place (data.get_place ());

            data.set_next_uint32 (0);

            UInt32 scalarCount (0);

            HashTableHandleIterator it;

            ScalarStruct *ss (_scalarTable.get_first (it));

            while (ss) {

               Float64 value (0.0);

               if (_objMod->lookup_scalar (ObjectHandle, ss->AttrHandle, value)) {

                  data.set_next_uint32 (ss->NetHandle);
                  data.set_next_float64 (value);
                  scalarCount++;

                  if (ss->LNVAttrHandle) {

                     _objMod->store_scalar (ObjectHandle, ss->LNVAttrHandle, value);
                  }
               }

               ss = _scalarTable.get_next (it);
            }

            const Int32 EndPlace (data.get_place ());
            data.set_place (Place);
            data.set_next_uint32 (scalarCount);
            data.set_place (EndPlace);

            _objMod->store_time_stamp (
               ObjectHandle,
               _lnvHandle,
               _time.get_last_frame_time ());

            _objMod->store_position (ObjectHandle, _lnvHandle, pos);
            _objMod->store_orientation (ObjectHandle, _lnvHandle, ori);
            _objMod->store_velocity (ObjectHandle, _lnvHandle, vel);

            if (EncodeMode != NetObjectDeactivate) {

               _objMod->store_state (ObjectHandle, _lnvHandle, state);
            }

            result = True;
         }
      }
   }

   return result;
}