Esempio n. 1
0
    std::shared_ptr<DependencyValidation> Store::MakeDependencyValidation(const ResChar intermediateFileName[]) const
    {
            //  When we process a file, we write a little text file to the
            //  ".deps" directory. This contains a list of dependency files, and
            //  the state of those files when this file was compiled.
            //  If the current files don't match the state that's recorded in
            //  the .deps file, then we can assume that it is out of date and
            //  must be recompiled.

        ResChar buffer[MaxPath];
        MakeDepFileName(buffer, _baseDirectory.c_str(), intermediateFileName);
        if (!DoesFileExist(buffer)) return nullptr;

        Data data;
        data.LoadFromFile(buffer);

        auto* basePath = data.StrAttribute("BasePath");
        auto validation = std::make_shared<DependencyValidation>();
        auto* dependenciesBlock = data.ChildWithValue("Dependencies");
        if (dependenciesBlock) {
            for (auto* dependency = dependenciesBlock->child; dependency; dependency = dependency->next) {
                auto* depName = dependency->value;
                if (!depName || !depName[0]) continue;

                auto dateLow = (unsigned)dependency->IntAttribute("ModTimeL");
                auto dateHigh = (unsigned)dependency->IntAttribute("ModTimeH");
                    
                std::shared_ptr<RetainedFileRecord> record;
                if (basePath && basePath[0]) {
                    XlConcatPath(buffer, dimof(buffer), basePath, depName, XlStringEnd(depName));
                    record = GetRetainedFileRecord(buffer);
                } else
                    record = GetRetainedFileRecord(depName);

                RegisterAssetDependency(validation, record);

                if (record->_state._status == DependentFileState::Status::Shadowed) {
                    LogInfo << "Asset (" << intermediateFileName << ") is invalidated because dependency (" << depName << ") is marked shadowed";
                    return nullptr;
                }

                if (!record->_state._timeMarker) {
                    LogInfo
                        << "Asset (" << intermediateFileName 
                        << ") is invalidated because of missing dependency (" << depName << ")";
                    return nullptr;
                } else if (record->_state._timeMarker != ((uint64(dateHigh) << 32ull) | uint64(dateLow))) {
                    LogInfo
                        << "Asset (" << intermediateFileName 
                        << ") is invalidated because of file data on dependency (" << depName << ")";
                    return nullptr;
                }
            }
        }

        return validation;
    }
Esempio n. 2
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);
    }
Esempio n. 3
0
    static void SetWorkingDirectory()
    {
            //
            //      For convenience, set the working directory to be ../Working 
            //              (relative to the application path)
            //
        nchar_t appPath     [MaxPath];
        nchar_t appDir      [MaxPath];
        nchar_t workingDir  [MaxPath];

        XlGetProcessPath    (appPath, dimof(appPath));
        XlDirname           (appDir, dimof(appDir), appPath);
        const auto* fn = a2n("..\\Working");
        XlConcatPath        (workingDir, dimof(workingDir), appDir, fn, XlStringEnd(fn));
        XlChDir             (workingDir);
    }
Esempio n. 4
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);
    }