Example #1
0
 void NascentModelCommandStream::SkinControllerInstance::Serialize(Serialization::NascentBlockSerializer& serializer) const
 {
     ::Serialize(serializer, _id);
     ::Serialize(serializer, _localToWorldId);
     serializer.SerializeSubBlock(AsPointer(_materials.begin()), AsPointer(_materials.end()));
     ::Serialize(serializer, _materials.size());
     ::Serialize(serializer, _levelOfDetail);
 }
Example #2
0
 std::vector<uint64> NascentModelCommandStream::GetInputInterface() const
 {
     std::vector<uint64> inputInterface(_transformationMachineOutputs.size());
     unsigned c=0;
     for (auto i=_transformationMachineOutputs.begin(); i!=_transformationMachineOutputs.end(); ++i, ++c)
         inputInterface[c] = Hash64(AsPointer(i->_name.begin()), AsPointer(i->_name.end()));
     return std::move(inputInterface);
 }
Example #3
0
    void NascentAnimationSet::Serialize(Serialization::NascentBlockSerializer& serializer) const
    {
        serializer.SerializeSubBlock(AsPointer(_animationDrivers.begin()), AsPointer(_animationDrivers.end()));
        serializer.SerializeValue(_animationDrivers.size());
        serializer.SerializeSubBlock(AsPointer(_constantDrivers.begin()), AsPointer(_constantDrivers.end()));
        serializer.SerializeValue(_constantDrivers.size());
        serializer.SerializeSubBlock(AsPointer(_constantData.begin()), AsPointer(_constantData.end()));

            //      List of animations...

        auto outputAnimations = std::make_unique<AnimationDesc[]>(_animations.size());
        for (size_t c=0; c<_animations.size(); ++c) {
            AnimationDesc&o = outputAnimations[c];
            const Animation&i = _animations[c];
            o._name = Hash64(AsPointer(i._name.begin()), AsPointer(i._name.end()));
            o._beginDriver = i._begin; o._endDriver = i._end;
            o._beginConstantDriver = i._constantBegin; o._endConstantDriver = i._constantEnd;
            o._beginTime = i._startTime; o._endTime = i._endTime;
        }
        std::sort(outputAnimations.get(), &outputAnimations[_animations.size()], CompareAnimationName());
        serializer.SerializeSubBlock(outputAnimations.get(), &outputAnimations[_animations.size()]);
        serializer.SerializeValue(_animations.size());

            //      Output interface...

        ConsoleRig::DebuggerOnlyWarning("Animation set output interface:\n");
        auto parameterNameHashes = std::make_unique<uint64[]>(_parameterInterfaceDefinition.size());
        for (size_t c=0; c<_parameterInterfaceDefinition.size(); ++c) {
            ConsoleRig::DebuggerOnlyWarning("  [%i] %s\n", c, _parameterInterfaceDefinition[c].c_str());
            parameterNameHashes[c] = Hash64(AsPointer(_parameterInterfaceDefinition[c].begin()), AsPointer(_parameterInterfaceDefinition[c].end()));
        }
        serializer.SerializeSubBlock(parameterNameHashes.get(), &parameterNameHashes[_parameterInterfaceDefinition.size()]);
        serializer.SerializeValue(_parameterInterfaceDefinition.size());
    }
Example #4
0
    void DeviceContext::Bind(const ShaderProgram& shaderProgram, const BoundClassInterfaces& dynLinkage)
    {
        auto& vsDyn = dynLinkage.GetClassInstances(ShaderStage::Vertex);
        _underlying->VSSetShader(shaderProgram.GetVertexShader().GetUnderlying(), 
            (ID3D::ClassInstance*const*)AsPointer(vsDyn.cbegin()), (unsigned)vsDyn.size());

        auto& psDyn = dynLinkage.GetClassInstances(ShaderStage::Pixel);
        _underlying->PSSetShader(shaderProgram.GetPixelShader().GetUnderlying(), 
            (ID3D::ClassInstance*const*)AsPointer(psDyn.cbegin()), (unsigned)psDyn.size());

        _underlying->GSSetShader(shaderProgram.GetGeometryShader().GetUnderlying(), nullptr, 0);
    }
Example #5
0
    void AccessorSerialize(
        OutputStreamFormatter& formatter,
        const void* obj, const ClassAccessors& props)
    {
        using CharType = utf8;
        auto charTypeCat = ImpliedTyping::TypeOf<CharType>()._type;
        CharType buffer[ParsingBufferSize];

        for (size_t i=0; i<props.GetPropertyCount(); ++i) {
            const auto& p = props.GetPropertyByIndex(i);
            if (p._castTo) {
                p._castTo(
                    obj, buffer, sizeof(buffer), 
                    ImpliedTyping::TypeDesc(charTypeCat, dimof(buffer)), true);

                formatter.WriteAttribute(
                    AsPointer(p._name.cbegin()), AsPointer(p._name.cend()), 
                    buffer, XlStringEnd(buffer));
            }

            if (p._castToArray) {
                for (size_t e=0; e<p._fixedArrayLength; ++e) {
                    p._castToArray(
                        obj, e, buffer, sizeof(buffer), 
                        ImpliedTyping::TypeDesc(charTypeCat, dimof(buffer)), true);

                    StringMeld<256, CharType> name;
                    name << p._name.c_str() << "[" << e << "]";
                    formatter.WriteAttribute(name.get(), buffer);
                }
            }
        }

        for (size_t i=0; i<props.GetChildListCount(); ++i) {
            const auto& childList = props.GetChildListByIndex(i);
            auto count = childList._getCount(obj);
            for (size_t e=0; e<count; ++e) {
                const auto* child = childList._getByIndex(obj, e);
                auto eleId = formatter.BeginElement(childList._name);
                AccessorSerialize(formatter, child, *childList._childProps);
                formatter.EndElement(eleId);
            }
        }
    }
Example #6
0
 void PushString(
     std::basic_streambuf<OutChar>& stream,
     StringSection<InChar> input)
 {
         //  String conversion process results in several redundant allocations. It's not perfectly
         //  efficient
     using OutputString = std::basic_string<OutChar>;
     auto converted = Conversion::Convert<OutputString>(input.AsString());
     stream.sputn(AsPointer(converted.begin()), converted.size());    
 }
 static void SerializeToFileJustChunk(
     ColladaConversion::NascentChunkArray chunks,
     const char destinationFilename[],
     const ConsoleRig::LibVersionDesc& versionInfo)
 {
     BasicFile outputFile(destinationFilename, "wb");
     for (unsigned i=0; i<(unsigned)chunks->size(); ++i) {
         auto& c = (*chunks)[i];
         outputFile.Write(AsPointer(c._data.begin()), c._data.size(), 1);
     }
 }
Example #8
0
    void DirectorySearchRules::ResolveFile(ResChar destination[], unsigned destinationCount, const ResChar baseName[]) const
    {
        ResChar tempBuffer[MaxPath];

        auto splitter = MakeFileNameSplitter(baseName);
        bool baseFileExist = false;
        if (!splitter.ParametersWithDivider().Empty()) {
            XlCopyString(tempBuffer, splitter.AllExceptParameters());
            baseFileExist = DoesFileExist(tempBuffer);
        } else {
            baseFileExist = DoesFileExist(baseName);
        }

            // by definition, we always check the unmodified file name first
        if (!baseFileExist) {
            const ResChar* b = _buffer;
            if (!_bufferOverflow.empty()) {
                b = AsPointer(_bufferOverflow.begin());
            }

                // We want to support the case were destination == baseName
                // But that cases requires another temporary buffer, because we
                // don't want to trash "baseName" while searching for matches
            ResChar* workingBuffer = (baseName!=destination) ? destination : tempBuffer;
            unsigned workingBufferSize = (baseName!=destination) ? destinationCount : unsigned(dimof(tempBuffer));

            for (unsigned c=0; c<_startPointCount; ++c) {
                XlConcatPath(workingBuffer, workingBufferSize, &b[_startOffsets[c]], 
                    splitter.AllExceptParameters().begin(), splitter.AllExceptParameters().end());
                if (DoesFileExist(workingBuffer)) {
                    SplitPath<ResChar>(workingBuffer).Simplify().Rebuild(workingBuffer, workingBufferSize);
                    if (workingBuffer != destination) {
                        auto workingBufferLen = std::min((ptrdiff_t)XlStringLen(workingBuffer), ptrdiff_t(destinationCount) - 1);
                        auto colonLen = (ptrdiff_t)splitter.ParametersWithDivider().Length();
                        auto colonCopy = std::min(ptrdiff_t(destinationCount) - workingBufferLen - 1, colonLen);
                        assert((workingBufferLen + colonCopy) < ptrdiff_t(destinationCount));
                        if (colonCopy > 0)
                            XlMoveMemory(&destination[workingBufferLen], splitter.ParametersWithDivider().begin(), colonCopy);
                        destination[workingBufferLen + colonCopy] = '\0';
                        assert(workingBufferLen < (ptrdiff_t(destinationCount)-1));
                        XlCopyMemory(destination, workingBuffer, workingBufferLen);
                    } else {
                        XlCatString(destination, destinationCount, splitter.ParametersWithDivider());
                    }
                    return;
                }
            }
        }

        if (baseName != destination)
            XlCopyString(destination, destinationCount, baseName);
        SplitPath<ResChar>(destination).Simplify().Rebuild(destination, destinationCount);
    }
Example #9
0
    void DirectorySearchRules::AddSearchDirectory(StringSection<ResChar> dir)
    {
            //  Attempt to fit this directory into our buffer.
            //  note that we have limited space in the buffer, but we can't really
            //  rely on all directory names remaining small and convenient... If we 
            //  overflow our fixed size buffer, we can use the dynamically 
            //  allocated "_bufferOverflow"
        assert((_startPointCount+1) <= dimof(_startOffsets));
        if ((_startPointCount+1) > dimof(_startOffsets)) {
                //  limited number of directories that can be pushed into a single "search rules"
                //  this allows us to avoid a little bit of awkward dynamic memory allocation
            return; 
        }

            // Check for duplicates
            //  Duplicates are bad because they will increase the number of search operations
        if (HasDirectory(dir)) return;

        unsigned allocationLength = (unsigned)(dir.Length() + 1);
        if (_bufferOverflow.empty() && (_bufferUsed + allocationLength <= dimof(_buffer))) {
                // just append this new string to our buffer, and add a new start offset
            XlCopyMemory(&_buffer[_bufferUsed], dir.begin(), (allocationLength-1) * sizeof(ResChar));
            _buffer[_bufferUsed+allocationLength-1] = '\0';
        } else {
            if (_bufferOverflow.empty()) {
                _bufferOverflow.resize(_bufferUsed + allocationLength);
                XlCopyMemory(AsPointer(_bufferOverflow.begin()), _buffer, _bufferUsed * sizeof(ResChar));
                XlCopyMemory(PtrAdd(AsPointer(_bufferOverflow.begin()), _bufferUsed * sizeof(ResChar)), dir.begin(), (allocationLength-1) * sizeof(ResChar));
                _bufferOverflow[_bufferUsed+allocationLength-1] = '\0';
            } else {
                assert(_bufferOverflow.size() == allocationLength);
                auto i = _bufferOverflow.insert(_bufferOverflow.end(), dir.begin(), dir.end());
                _bufferOverflow.insert(i + dir.Length(), 0);
            }
        }

        _startOffsets[_startPointCount++] = _bufferUsed;
        _bufferUsed += allocationLength;
    }
Example #10
0
    void DirectorySearchRules::Merge(const DirectorySearchRules& mergeFrom)
    {
            // Merge in the settings from the given search rules (if the directories
            // don't already exist here)
            // We should really do a better job of comparing directories. Where strings
            // resolve to the same directory, we should consider them identical
        const ResChar* b = mergeFrom._buffer;
        if (!mergeFrom._bufferOverflow.empty())
            b = AsPointer(mergeFrom._bufferOverflow.begin());

        for (unsigned c=0; c<mergeFrom._startPointCount; ++c)
            AddSearchDirectory(&b[mergeFrom._startOffsets[c]]);
    }
 static void SerializeToFileJustChunk(
     RenderCore::ColladaConversion::NascentModel& model, 
     RenderCore::ColladaConversion::OCModelSerializeFunction fn,
     const char destinationFilename[],
     const ConsoleRig::LibVersionDesc& versionInfo)
 {
     auto chunks = (model.*fn)();
 
     BasicFile outputFile(destinationFilename, "wb");
     for (unsigned i=0; i<(unsigned)chunks->size(); ++i) {
         auto& c = (*chunks)[i];
         outputFile.Write(AsPointer(c._data.begin()), c._data.size(), 1);
     }
 }
Example #12
0
    bool DirectorySearchRules::HasDirectory(StringSection<ResChar> dir)
    {
        const ResChar* b = _buffer;
        if (!_bufferOverflow.empty()) {
            b = AsPointer(_bufferOverflow.begin());
        }

            // note --  just doing a string insensitive compare here...
            //          we should really do a more sophisticated path compare
            //          to get a more accurate result
            //          Actually, it might be better to store the paths in some
            //          format that is more convenient for comparisons and combining
            //          paths.
        for (unsigned c=0; c<_startPointCount; ++c)
            if (XlEqStringI(dir, &b[_startOffsets[c]]))
                return true;

        return false;
    }
Example #13
0
    void DivergentAssetBase::AssetIdentifier::OnChange()
    {
        // We need to mark the target file invalidated.
        // this is a little strange, because the target file
        // hasn't actually changed. 
        // 
        // But this is required because some dependent assets
        // don't have a dependency on the asset itself (just
        // on the underlying file). Invalidating the file ensures
        // that we invoke a update on all assets that require it.

        if (_targetFilename.empty()) return;

        auto fn = _targetFilename;
        auto paramStart = fn.find_last_of(':');
		auto end = fn.cend();
        if (paramStart != std::basic_string<ResChar>::npos)
			end = fn.cbegin() + paramStart;

        Services::GetAsyncMan().GetIntermediateStore().ShadowFile(MakeStringSection(AsPointer(fn.cbegin()), AsPointer(end)));
    }
Example #14
0
 void NascentModelCommandStream::Serialize(Serialization::NascentBlockSerializer& serializer) const
 {
     serializer.SerializeSubBlock(AsPointer(_geometryInstances.begin()), AsPointer(_geometryInstances.end()));
     serializer.SerializeValue(_geometryInstances.size());
     serializer.SerializeSubBlock(AsPointer(_skinControllerInstances.begin()), AsPointer(_skinControllerInstances.end()));
     serializer.SerializeValue(_skinControllerInstances.size());
         
         //
         //      Turn our list of input matrices into hash values, and write out the
         //      run-time input interface definition...
         //
     ConsoleRig::DebuggerOnlyWarning("Command stream input interface:\n");
     auto inputInterface = GetInputInterface();
     serializer.SerializeSubBlock(AsPointer(inputInterface.cbegin()), AsPointer(inputInterface.cend()));
     serializer.SerializeValue(_transformationMachineOutputs.size());
 }
Example #15
0
    void    NascentAnimationSet::MergeAnimation(
        const NascentAnimationSet& animation, const char name[],
        const std::vector<Assets::RawAnimationCurve>& sourceCurves, 
        std::vector<Assets::RawAnimationCurve>& destinationCurves)
    {
            //
            //      Merge the animation drivers in the given input animation, and give 
            //      them the supplied name
            //
        float minTime = FLT_MAX, maxTime = -FLT_MAX;
        size_t startIndex = _animationDrivers.size();
        size_t constantStartIndex = _constantDrivers.size();
        for (auto i=animation._animationDrivers.cbegin(); i!=animation._animationDrivers.end(); ++i) {
            if (i->_curveIndex >= sourceCurves.size()) continue;
            const auto* animCurve = &sourceCurves[i->_curveIndex];
            if (animCurve) {
                float curveStart = animCurve->StartTime();
                float curveEnd = animCurve->EndTime();
                minTime = std::min(minTime, curveStart);
                maxTime = std::max(maxTime, curveEnd);

                const std::string& name = animation._parameterInterfaceDefinition[i->_parameterIndex];
                destinationCurves.push_back(Assets::RawAnimationCurve(*animCurve));
                AddAnimationDriver(
                    name, unsigned(destinationCurves.size()-1), 
                    i->_samplerType, i->_samplerOffset);
            }
        }

        for (auto i=animation._constantDrivers.cbegin(); i!=animation._constantDrivers.end(); ++i) {
            const std::string& name = animation._parameterInterfaceDefinition[i->_parameterIndex];
            AddConstantDriver(name, PtrAdd(AsPointer(animation._constantData.begin()), i->_dataOffset), i->_samplerType, i->_samplerOffset);
        }

        _animations.push_back(Animation(name, 
            (unsigned)startIndex, (unsigned)_animationDrivers.size(), 
            (unsigned)constantStartIndex, (unsigned)_constantDrivers.size(),
            minTime, maxTime));
    }
Example #16
0
    void DirectorySearchRules::ResolveDirectory(
            ResChar destination[], unsigned destinationCount, 
            const ResChar baseName[]) const
    {
            //  We have a problem with basic paths (like '../')
            //  These will match for most directories -- which means that
            //  there is some ambiguity. Let's prefer to use the first
            //  registered path for simple relative paths like this.
        bool useBaseName = 
            (baseName[0] != '.' && DoesDirectoryExist(baseName));

        if (!useBaseName) {
            const ResChar* b = _buffer;
            if (!_bufferOverflow.empty()) {
                b = AsPointer(_bufferOverflow.begin());
            }

            const auto* baseEnd = XlStringEnd(baseName);
            
            ResChar tempBuffer[MaxPath];
            ResChar* workingBuffer = (baseName!=destination) ? destination : tempBuffer;
            unsigned workingBufferSize = (baseName!=destination) ? destinationCount : unsigned(dimof(tempBuffer));

            for (unsigned c=0; c<_startPointCount; ++c) {
                XlConcatPath(workingBuffer, workingBufferSize, &b[_startOffsets[c]], baseName, baseEnd);
                if (DoesDirectoryExist(workingBuffer)) {
                    if (workingBuffer != destination)
                        XlCopyString(destination, destinationCount, workingBuffer);
                    return;
                }
            }
        }

        if (baseName != destination)
            XlCopyString(destination, destinationCount, baseName);
    }
Example #17
0
    static ::Assets::CompilerHelper::CompileResult CompileMaterialScaffold(
        const ::Assets::ResChar sourceMaterial[], const ::Assets::ResChar sourceModel[],
        const ::Assets::ResChar destination[])
    {
            // Parameters must be stripped off the source model filename before we get here.
            // the parameters are irrelevant to the compiler -- so if they stay on the request
            // name, will we end up with multiple assets that are equivalent
        assert(MakeFileNameSplitter(sourceModel).ParametersWithDivider().Empty());

            // note -- we can throw pending & invalid from here...
        auto& modelMat = ::Assets::GetAssetComp<RawMatConfigurations>(sourceModel);
            
        std::vector<::Assets::DependentFileState> deps;

            //  for each configuration, we want to build a resolved material
            //  Note that this is a bit crazy, because we're going to be loading
            //  and re-parsing the same files over and over again!
        SerializableVector<std::pair<MaterialGuid, ResolvedMaterial>> resolved;
        SerializableVector<std::pair<MaterialGuid, std::string>> resolvedNames;
        resolved.reserve(modelMat._configurations.size());

        auto searchRules = ::Assets::DefaultDirectorySearchRules(sourceModel);
        ::Assets::ResChar resolvedSourceMaterial[MaxPath];
        ResolveMaterialFilename(resolvedSourceMaterial, dimof(resolvedSourceMaterial), searchRules, sourceMaterial);
        searchRules.AddSearchDirectoryFromFilename(resolvedSourceMaterial);

        AddDep(deps, sourceModel);        // we need need a dependency (even if it's a missing file)

        using Meld = StringMeld<MaxPath, ::Assets::ResChar>;
        for (auto i=modelMat._configurations.cbegin(); i!=modelMat._configurations.cend(); ++i) {

            ResolvedMaterial resMat;
            std::basic_stringstream<::Assets::ResChar> resName;
            auto guid = MakeMaterialGuid(AsPointer(i->cbegin()), AsPointer(i->cend()));

                // Our resolved material comes from 3 separate inputs:
                //  1) model:configuration
                //  2) material:*
                //  3) material:configuration
                //
                // Some material information is actually stored in the model
                // source data. This is just for art-pipeline convenience --
                // generally texture assignments (and other settings) are 
                // set in the model authoring tool (eg, 3DS Max). The .material
                // files actually only provide overrides for settings that can't
                // be set within 3rd party tools.
                // 
                // We don't combine the model and material information until
                // this step -- this gives us some flexibility to use the same
                // model with different material files. The material files can
                // also override settings from 3DS Max (eg, change texture assignments
                // etc). This provides a path for reusing the same model with
                // different material settings (eg, when we want one thing to have
                // a red version and a blue version)
            
            TRY {
                    // resolve in model:configuration
                auto configName = Conversion::Convert<::Assets::rstring>(*i);
                Meld meld; meld << sourceModel << ":" << configName;
                resName << meld;
                auto& rawMat = RawMaterial::GetAsset(meld);
                rawMat._asset.Resolve(resMat, searchRules, &deps);
            } CATCH (const ::Assets::Exceptions::InvalidAsset&) {
            } CATCH_END

            if (resolvedSourceMaterial[0] != '\0') {
                AddDep(deps, resolvedSourceMaterial);        // we need need a dependency (even if it's a missing file)

                TRY {
                        // resolve in material:*
                    Meld meld; meld << resolvedSourceMaterial << ":*";
                    resName << ";" << meld;
                    auto& rawMat = RawMaterial::GetAsset(meld);
                    rawMat._asset.Resolve(resMat, searchRules, &deps);
                } CATCH (const ::Assets::Exceptions::InvalidAsset&) {
                } CATCH_END

                TRY {
                        // resolve in material:configuration
                    Meld meld; meld << resolvedSourceMaterial << ":" << Conversion::Convert<::Assets::rstring>(*i);
                    resName << ";" << meld;
                    auto& rawMat = RawMaterial::GetAsset(meld);
                    rawMat._asset.Resolve(resMat, searchRules, &deps);
                } CATCH (const ::Assets::Exceptions::InvalidAsset&) {
                } CATCH_END
            }

            resolved.push_back(std::make_pair(guid, std::move(resMat)));
            resolvedNames.push_back(std::make_pair(guid, resName.str()));
        }
Example #18
0
    static Identifier DeserializeEntity(
        InputStreamFormatter<utf8>& formatter,
        IEntityInterface& interf,
        DocumentId docId)
    {
        using Blob = InputStreamFormatter<utf8>::Blob;
        using Section = InputStreamFormatter<utf8>::InteriorSection;
        
        utf8 tempBuffer[256];
        
        auto beginLoc = formatter.GetLocation();
        Section objType = { nullptr, nullptr };
        if (!formatter.TryBeginElement(objType))
            Throw(FormatException("Error in begin element in entity file", formatter.GetLocation()));

        XlCopyNString(tempBuffer, objType._start, objType._end - objType._start);
        auto typeId = interf.GetTypeId((const char*)tempBuffer);

        std::vector<PropertyInitializer> inits;
        std::vector<char> initsBuffer;
        initsBuffer.reserve(256);

        std::vector<Identifier> children;

        for (;;) {
            switch (formatter.PeekNext()) {
            case Blob::BeginElement:
                {
                    auto child = DeserializeEntity(formatter, interf, docId);
                    if (child.Object())
                        children.push_back(child);
                }
                break;

            case Blob::AttributeName:
                {
                    Section name, value;
                    if (!formatter.TryAttribute(name, value))
                        Throw(FormatException("Error in begin element in entity file", formatter.GetLocation()));

                        // parse the value and add it as a property initializer
                    char intermediateBuffer[64];
                    auto type = ImpliedTyping::Parse(
                        (const char*)value._start, (const char*)value._end,
                        intermediateBuffer, dimof(intermediateBuffer));

                    size_t bufferOffset = initsBuffer.size();
                    
                    if (type._type == ImpliedTyping::TypeCat::Void) {
                        type._type = ImpliedTyping::TypeCat::UInt8;
                        type._arrayCount = uint16(value._end - value._start);
                        type._typeHint = ImpliedTyping::TypeHint::String;
                        initsBuffer.insert(initsBuffer.end(), value._start, value._end);
                    } else {
                        auto size = std::min(type.GetSize(), (unsigned)sizeof(intermediateBuffer));
                        initsBuffer.insert(initsBuffer.end(), intermediateBuffer, PtrAdd(intermediateBuffer, size));
                    }
               
                    XlCopyNString(tempBuffer, name._start, name._end - name._start);
                    auto id = interf.GetPropertyId(typeId, (const char*)tempBuffer);

                    PropertyInitializer i;
                    i._prop = id;
                    i._elementType = unsigned(type._type);
                    i._arrayCount = type._arrayCount;
                    i._src = (const void*)bufferOffset;

                    inits.push_back(i);
                }
                break;

            case Blob::EndElement:
            default:
                if (!formatter.TryEndElement())
                    Throw(FormatException("Expecting end element in entity deserialisation", formatter.GetLocation()));

                if (typeId != ~ObjectTypeId(0x0)) {
                    for (auto&i:inits) i._src = PtrAdd(AsPointer(initsBuffer.cbegin()), size_t(i._src));

                    auto id = interf.AssignObjectId(docId, typeId);
                    Identifier identifier(docId, id, typeId);
                    if (!interf.CreateObject(identifier, AsPointer(inits.cbegin()), inits.size()))
                        Throw(FormatException("Error while creating object in entity deserialisation", beginLoc));

                    for (const auto&c:children)
                        interf.SetParent(c, identifier, -1);

                    typeId = ~ObjectTypeId(0x0);
                    initsBuffer.clear();

                    return identifier;
                }

                return Identifier();
            }
        }
    }
Example #19
0
 const uint8* AsyncLoadOperation::GetBuffer() const { return  AsPointer(_buffer.get()); }