示例#1
0
/*****************************************************************************
 * ItemChange: Playlist item change callback
 *****************************************************************************/
static void playlist_on_current_index_changed(vlc_playlist_t *playlist,
                                              ssize_t index, void *userdata)
{
    VLC_UNUSED(index);

    intf_thread_t *intf = userdata;
    intf_sys_t *sys = intf->p_sys;

    sys->b_meta_read = false;

    vlc_player_t *player = vlc_playlist_GetPlayer(playlist);
    input_item_t *item = vlc_player_GetCurrentMedia(player);
    if (!item)
        return;

    if (vlc_player_GetVideoTrackCount(player))
    {
        msg_Dbg(intf, "Not an audio-only input, not submitting");
        return;
    }

    sys->time_total_pauses = 0;
    time(&sys->p_current_song.date);                /* to be sent to last.fm */
    sys->p_current_song.i_start = vlc_tick_now();   /* only used locally */

    if (input_item_IsPreparsed(item))
        ReadMetaData(intf);
    /* if the input item was not preparsed, we'll do it in player_on_state_changed()
     * callback, when "state" == VLC_PLAYER_STATE_PLAYING */
}
bool CCheckpointSystem::GetMetaData(const char* fileName, SCheckpointData &metaData, bool bRepairId /*=true*/)
{
	XmlNodeRef data = ReadXML(fileName);
	if(!data)
		return false;

	//process meta data
	return ReadMetaData(data, metaData, bRepairId);
}
/*****************************************************************************
 * ItemChange: Playlist item change callback
 *****************************************************************************/
static int ItemChange( vlc_object_t *p_this, const char *psz_var,
                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
    input_thread_t      *p_input;
    intf_thread_t       *p_intf     = ( intf_thread_t* ) p_data;
    intf_sys_t          *p_sys      = p_intf->p_sys;
    input_item_t        *p_item;

    VLC_UNUSED( p_this ); VLC_UNUSED( psz_var );
    VLC_UNUSED( oldval ); VLC_UNUSED( newval );

    p_sys->b_state_cb       = false;
    p_sys->b_meta_read      = false;
    p_sys->b_submit         = false;

    p_input = playlist_CurrentInput( pl_Get( p_intf ) );

    if( !p_input || p_input->b_dead )
        return VLC_SUCCESS;

    p_item = input_GetItem( p_input );
    if( !p_item )
    {
        vlc_object_release( p_input );
        return VLC_SUCCESS;
    }

    if( var_CountChoices( p_input, "video-es" ) )
    {
        msg_Dbg( p_this, "Not an audio-only input, not submitting");
        vlc_object_release( p_input );
        return VLC_SUCCESS;
    }

    p_sys->time_total_pauses = 0;
    time( &p_sys->p_current_song.date );        /* to be sent to last.fm */
    p_sys->p_current_song.i_start = mdate();    /* only used locally */

    var_AddCallback( p_input, "intf-event", PlayingChange, p_intf );
    p_sys->b_state_cb = true;

    if( input_item_IsPreparsed( p_item ) )
        ReadMetaData( p_intf );
    /* if the input item was not preparsed, we'll do it in PlayingChange()
     * callback, when "state" == PLAYING_S */

    vlc_object_release( p_input );
    return VLC_SUCCESS;
}
/*****************************************************************************
 * PlayingChange: Playing status change callback
 *****************************************************************************/
static int PlayingChange( vlc_object_t *p_this, const char *psz_var,
                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
    VLC_UNUSED( oldval );

    intf_thread_t   *p_intf = ( intf_thread_t* ) p_data;
    intf_sys_t      *p_sys  = p_intf->p_sys;
    input_thread_t  *p_input = ( input_thread_t* )p_this;
    vlc_value_t     state_value;

    VLC_UNUSED( p_this ); VLC_UNUSED( psz_var );

    if( newval.i_int != INPUT_EVENT_STATE ) return VLC_SUCCESS;

    if( var_CountChoices( p_input, "video-es" ) )
    {
        msg_Dbg( p_this, "Not an audio-only input, not submitting");
        return VLC_SUCCESS;
    }

    state_value.i_int = 0;

    var_Get( p_input, "state", &state_value );


    if( !p_sys->b_meta_read && state_value.i_int >= PLAYING_S )
    {
        ReadMetaData( p_intf );
        return VLC_SUCCESS;
    }


    if( state_value.i_int >= END_S )
        AddToQueue( p_intf );
    else if( state_value.i_int == PAUSE_S )
        p_sys->time_pause = mdate();
    else if( p_sys->time_pause > 0 && state_value.i_int == PLAYING_S )
    {
        p_sys->time_total_pauses += ( mdate() - p_sys->time_pause );
        p_sys->time_pause = 0;
    }

    return VLC_SUCCESS;
}
示例#5
0
/*****************************************************************************
 * ItemChange: Playlist item change callback
 *****************************************************************************/
static int ItemChange(vlc_object_t *p_this, const char *psz_var,
                       vlc_value_t oldval, vlc_value_t newval, void *p_data)
{
    input_thread_t      *p_input;
    intf_thread_t       *p_intf     = (intf_thread_t*) p_data;
    intf_sys_t          *p_sys      = p_intf->p_sys;
    input_item_t        *p_item;

    VLC_UNUSED(p_this); VLC_UNUSED(psz_var);
    VLC_UNUSED(oldval); VLC_UNUSED(newval);

    p_sys->b_state_cb       = false;
    p_sys->b_meta_read      = false;
    p_sys->b_submit         = false;

    p_input = playlist_CurrentInput(pl_Get(p_intf));

    if (!p_input || p_input->b_dead)
        return VLC_SUCCESS;

    p_item = input_GetItem(p_input);
    if (!p_item)
    {
        vlc_object_release(p_input);
        return VLC_SUCCESS;
    }

    p_sys->time_total_pauses = 0;
    time(&p_sys->p_current_item.date);        /* to be sent to upstream */
    p_sys->p_current_item.i_start = mdate();  /* used to calculate run
                                               * time as fallback       */

    var_AddCallback(p_input, "intf-event", PlayingChange, p_intf);
    p_sys->b_state_cb = true;

    if (input_item_IsPreparsed(p_item))
        ReadMetaData(p_intf);

    vlc_object_release(p_input);
    return VLC_SUCCESS;
}
示例#6
0
/*****************************************************************************
 * PlayingChange: Playing status change callback
 *****************************************************************************/
static int PlayingChange(vlc_object_t *p_this, const char *psz_var,
                       vlc_value_t oldval, vlc_value_t newval, void *p_data)
{

    VLC_UNUSED(oldval);

    intf_thread_t   *p_intf = (intf_thread_t*) p_data;
    intf_sys_t      *p_sys  = p_intf->p_sys;
    input_thread_t  *p_input = (input_thread_t*)p_this;
    int             state;

    VLC_UNUSED(psz_var);

    if (newval.i_int != INPUT_EVENT_STATE) return VLC_SUCCESS;

    state = var_GetInteger(p_input, "state");

    if (!p_sys->b_meta_read && state >= PLAYING_S)
    {
        ReadMetaData(p_intf);
        return VLC_SUCCESS;
    }

    if (state >= END_S)
    {
        AddToQueue(p_intf);
    }
    else if (state == PAUSE_S)
    {
        p_sys->time_pause = mdate();
    }
    else if (p_sys->time_pause > 0 && state == PLAYING_S)
    {
        p_sys->time_total_pauses += (mdate() - p_sys->time_pause);
        p_sys->time_pause = 0;
    }

    return VLC_SUCCESS;
}
示例#7
0
static void player_on_state_changed(vlc_player_t *player,
                                    enum vlc_player_state state, void *data)
{
    intf_thread_t *intf = data;
    intf_sys_t *sys = intf->p_sys;

    if (vlc_player_GetVideoTrackCount(player))
    {
        msg_Dbg(intf, "Not an audio-only input, not submitting");
        return;
    }

    if (!sys->b_meta_read && state >= VLC_PLAYER_STATE_PLAYING)
    {
        ReadMetaData(intf);
        return;
    }

    switch (state)
    {
        case VLC_PLAYER_STATE_STOPPED:
            AddToQueue(intf);
            break;
        case VLC_PLAYER_STATE_PAUSED:
            sys->time_pause = vlc_tick_now();
            break;
        case VLC_PLAYER_STATE_PLAYING:
            if (sys->time_pause > 0)
            {
                sys->time_total_pauses += vlc_tick_now() - sys->time_pause;
                sys->time_pause = 0;
            }
            break;
        default:
            break;
    }
}
//-*****************************************************************************
ProtoObjectReader::ProtoObjectReader( hid_t iParent,
                                      const std::string &iParentFullPathName,
                                      const std::string &iName )
{
    // Validate.
    ABCA_ASSERT( iParent >= 0,
                 "Invalid group passed into ProtoObjectReader ctor" );

    // Open the HDF5 group corresponding to this object.
    m_group = H5Gopen2( iParent, iName.c_str(), H5P_DEFAULT );
    ABCA_ASSERT( m_group >= 0,
                 "Could not open object group named: "
                 << iName << " in parent: " << iParentFullPathName );

    // Read the meta data.
    // Metadata is always named ".prop.meta" for objects,
    // as it is shared with the underlying property.
    AbcA::MetaData mdata;
    ReadMetaData( m_group, ".prop.meta", mdata );

    std::string fullChildName;

    if ( iParentFullPathName == "/" )
    {
        fullChildName = "/" + iName;
    }
    else
    {
        fullChildName = iParentFullPathName + "/" + iName;
    }

    if ( fullChildName == "/ABC" ) { fullChildName = "/"; }

    m_header = AbcA::ObjectHeader( iName,
                                   fullChildName,
                                   mdata );
}
示例#9
0
//-*****************************************************************************
const AbcA::ObjectHeader &
OrData::getChildHeader( AbcA::ObjectReaderPtr iParent, size_t i )
{
    ABCA_ASSERT( i < m_children.size(),
        "Out of range index in OrData::getChildHeader: " << i );

    Alembic::Util::scoped_lock l( m_childObjectsMutex );
    if ( ! m_children[i].loadedMetaData )
    {
        H5Node group = OpenGroup( m_group,
            m_children[i].header->getName().c_str() );
;
        ABCA_ASSERT( group.isValidObject(),
        "Could not open object group: "
        << m_children[i].header->getFullName() );

        ReadMetaData( group, ".prop.meta",
            m_children[i].header->getMetaData() );

        CloseObject( group );
    }

    return *( m_children[i].header );
}
示例#10
0
bool IODicom<T>::Read(PGCore::BaseDataObject *oDataObject, const IOParams &iParams,
                      PGCore::BaseDataObject *oMetaDataObject/* = 0*/)
{
    // read meta data first
    if (!oMetaDataObject) {
        LOG0("IO/IODicom::Read: metadata object null");
        return false;
    }

    if (iParams.SourceType()!=kPgIOSourceTypeFile)
    {
        LOG0("IO/IODicom::Read: Expecting single file path.");
        return false;
    }

    if (!ReadMetaData(oMetaDataObject, iParams))
    {
        LOG0("IO/IODicom::Read: ReadMetaData failed.");
        return false;
    }

    if (!oDataObject)
    {
        LOG0("IO/IODicom::Read: Invalid input image.");
        return false;
    }

    // cast to image type here
    PGCore::Image<T> *oImage = (static_cast<PGCore::Image < T > *>(oDataObject));
    if (!oImage)
    {
        LOG0("IO/IODicom::Read: Invalid input image.");
        return false;
    }

    PGCore::MetaData<T> *oMetaData = (static_cast<PGCore::MetaData< T > *>(oMetaDataObject));
    if (!oMetaData)
    {
        LOG0("IO/IOBase::Read: Invalid output container for metadata.");
        return false;
    }

    int frameCount = oMetaData->GetFrameCount();
    int frameIndex = 0;

    if (frameCount>1)
    {
        frameIndex = iParams.GetActiveFrameIndex();
        if (frameIndex<0 || frameIndex>(frameCount-1))
        {
            LOG2("IO/IODicom::Read: Invalid frame index: %d/%d", frameIndex, frameCount);
            return false;
        }
    }


    //calculate the full size of the scalars
    const PGMath::Vector3D<int>& oSize = oMetaData->GetSize();
    long ix=oSize.Y(), iy=oSize.X();
    oImage->SetDimensions(ix, iy);

    T* oBuf = oImage->GetBuffer();
    if (!oBuf)
    {
        LOG0("IO/IODicom::Read: Invalid image buffer.");
        return false;
    }

    bool needConversion = false;
    int nBitsPerPixel = oMetaData->GetNumberOfBits();
    if (nBitsPerPixel!=8*sizeof(T))
    {
        LOG2("IO/IODicom::Read:Warning: Pixel type mismatch. Need %d bits per pixel, but reporting %d.", nBitsPerPixel, 8*sizeof(T));
        needConversion = true;
        //return false;
    }

    int oByteCount = (nBitsPerPixel/8) * ix * iy;
    long offset = frameIndex*ix*iy;
    unsigned char *iBuf=0;

#ifdef _PG_GDDCM_

#else
    // read pixel data
    //DcmFileFormat fileformat;
    DcmDataset *dataset = m_fileformat.getDataset();
    if (!dataset)
    {
        LOG0("IO/IODicom::Read: Cannot fetch pixel data");
        return false;
    }

    switch (nBitsPerPixel)
    {
    case 8:
        dataset->findAndGetUint8Array(DCM_PixelData, (const Uint8 *&) iBuf);
        if (frameCount>1)
        {
            iBuf = (unsigned char *)((Uint8 *)iBuf + offset);
        }
        break;

    case 16:
        dataset->findAndGetUint16Array(DCM_PixelData, (const Uint16 *&) iBuf);
        if (frameCount>1)
        {
            iBuf = (unsigned char *)((Uint16 *)iBuf + offset);
        }
        break;

    default:
        LOG0("IO/IODicom::Read: failed to fetch image buffer.");
        return false;
    }
#endif

    if (iBuf==0)
    {
        LOG0("IO/IODicom::Read: Invalid image buffer.");
        return false;
    }

    // we have to copy the data into the buffer already allocated
    if (!needConversion)
    {
        memcpy(oBuf, iBuf, oByteCount);
    } else
    {
        // first create a local image
        PGCore::Image<unsigned char> ucharImage;
        PGCore::Image<short> shortImage;

        unsigned char* localBuf = 0;
        switch (nBitsPerPixel)
        {
        case 8:
            ucharImage.SetDimensions(ix, iy);
            localBuf = (unsigned char *)ucharImage.GetBuffer();
            break;

        case 16:
            shortImage.SetDimensions(ix, iy);
            localBuf = (unsigned char *)shortImage.GetBuffer();
            break;

        default:
            break;
        }

        if (localBuf==0)
        {
            LOG0("IO/IODicom::Read: Invalid local image buffer.");
            return false;
        }

        // copy buffer locally
        memcpy(localBuf, iBuf, oByteCount);

        // now convert the pixels
        long i=0;
        while (i<ix*iy)
        {
            *(oBuf++) = T(*(localBuf++));
            i++;
        }
    }


    if (GetSmoothFlag())
    {
        PGCore::GaussianKernel<double, T> gausskernel(1.0f);
        PGCore::Image<T> sImage;
        gausskernel.Convolve(*oImage, sImage);
        *oImage = sImage;
        LOG0("\tIODicom::Smooth: Image DONE.");
    }

    //LOG0("IO/IODicom::Read: Image DONE.");
    //fclose(fptr);
    if (frameCount>1)
    {
        std::vector<PGMath::Vector3D<float>> orXVecs = oMetaData->GetImageOrientationsPatientX();
        std::vector<PGMath::Vector3D<float>> orYVecs = oMetaData->GetImageOrientationsPatientY();

        if (orXVecs.empty() || orYVecs.empty())
        {
            LOG0("\tIODicom::Read: empty orientation vectors.");
            return false;
        }

        PGMath::Vector3D<float> orZVec = orXVecs[0] ^ orYVecs[0];

        orZVec = orZVec*frameIndex;

        std::vector<PGMath::Vector3D<float>> posVecs;
        posVecs.push_back(orZVec);

        oMetaData->SetImagePositionsPatient(posVecs);
    }

    return true;
}
示例#11
0
//-*****************************************************************************
void
ReadPropertyHeader( H5Node & iParent,
                    const std::string & iPropName,
                    AbcA::PropertyHeader & oHeader,
                    bool & oIsScalarLike,
                    uint32_t & oNumSamples,
                    uint32_t & oFirstChangedIndex,
                    uint32_t & oLastChangedIndex,
                    uint32_t & oTimeSamplingIndex )
{
    uint32_t info[5] = {0, 0, 0, 0, 0};
    size_t numFields = 0;
    size_t fieldsUsed = 1;

    // 0000 0000 0000 0000 0000 0000 0000 0011
    static const uint32_t ptypeMask = 0x0003;

    // 0000 0000 0000 0000 0000 0000 0011 1100
    static const uint32_t podMask = 0x003c;

    // 0000 0000 0000 0000 0000 0000 0100 0000
    static const uint32_t hasTsidxMask = 0x0040;

    // 0000 0000 0000 0000 0000 0000 1000 0000
    static const uint32_t noRepeatsMask = 0x0080;

    // 0000 0000 0000 0000 1111 1111 0000 0000
    static const uint32_t extentMask = 0xff00;

    ReadSmallArray(iParent.getObject(), iPropName + ".info", H5T_STD_U32LE,
                   H5T_NATIVE_UINT32, 5, numFields, (void *) info );

    AbcA::MetaData metaData;
    ReadMetaData( iParent, iPropName + ".meta", metaData );

    if ( numFields == 1 && info[0] == 0 )
    {
        oHeader = AbcA::PropertyHeader( iPropName, metaData );
    }
    else
    {
        // low two bits are the property type
        char ipt = info[0] & ptypeMask;

        // first bit is either scalar, or scalar like
        oIsScalarLike = ipt & 1;

        // is scalar like is set for this array attribute
        if (ipt == 3)
        {
            oHeader.setPropertyType( AbcA::kArrayProperty );
        }
        else
        {
            oHeader.setPropertyType( ( AbcA::PropertyType )ipt );
        }

        // Read the pod type out of bits 2-5
        char podt = ( char )( ( info[0] & podMask ) >> 2 );
        if ( podt != ( char )kBooleanPOD &&

             podt != ( char )kUint8POD &&
             podt != ( char )kInt8POD &&

             podt != ( char )kUint16POD &&
             podt != ( char )kInt16POD &&

             podt != ( char )kUint32POD &&
             podt != ( char )kInt32POD &&

             podt != ( char )kUint64POD &&
             podt != ( char )kInt64POD &&

             podt != ( char )kFloat16POD &&
             podt != ( char )kFloat32POD &&
             podt != ( char )kFloat64POD &&

             podt != ( char )kStringPOD &&
             podt != ( char )kWstringPOD )
        {
            ABCA_THROW( "Read invalid POD type: " << ( int )podt );
        }

        // bit 6 is the hint about whether time sampling index was written
        // at the end
        bool hasTsidx = ( (info[0] & hasTsidxMask ) >> 6 ) == 1;
        oTimeSamplingIndex = 0;

        if ( hasTsidx && numFields > 1 )
        {
            oTimeSamplingIndex = info[numFields - 1];
            fieldsUsed ++;
        }

        // bit 7 is a hint about whether first and last changed index
        // are intrinsically 1, and numSamples - 1
        // (no repeated data from the start or the end)
        bool noRepeats = ( (info[0] & noRepeatsMask ) >> 7 ) == 1;

        // Time Sampling Index could be written, but the number of samples
        // may not be.
        if ( numFields > fieldsUsed )
        {
            oNumSamples = info[1];

            if ( numFields >= 4 )
            {
                oFirstChangedIndex = info[2];
                oLastChangedIndex = info[3];
            }
            else if ( noRepeats )
            {
                oFirstChangedIndex = 1;
                oLastChangedIndex = oNumSamples - 1;
            }
            else
            {
                oFirstChangedIndex = 0;
                oLastChangedIndex = 0;
            }
        }
        else
        {
            oNumSamples = 0;
            oFirstChangedIndex = 0;
            oLastChangedIndex = 0;

            // if smp0 exists then we have 1 sample
            std::string smpName = iPropName + ".smp0";
            if ( oHeader.getPropertyType() == AbcA::kArrayProperty &&
                 ObjectExists( iParent, smpName ) )
            {
                oNumSamples = 1;
            }
            else if ( oHeader.getPropertyType() == AbcA::kScalarProperty &&
                      AttrExists( iParent, smpName ) )
            {
                oNumSamples = 1;
            }
        }

        // Read the extent out of bits 8-15
        uint8_t extent = ( uint8_t )( ( info[0] & extentMask ) >> 8 );
        if ( extent == 0 )
        {
            ABCA_THROW( "Degenerate extent 0" );
        }

        // bits 16-31 are currently not being used

        // the time sampling will be set on oHeader by the calling function
        // since we don't have access to the archive here.
        oHeader.setName( iPropName );
        oHeader.setMetaData( metaData );
        oHeader.setDataType(
            AbcA::DataType( ( Util::PlainOldDataType ) podt, extent ) );
    }
}
//-*****************************************************************************
ArImpl::ArImpl( const std::string &iFileName,
                AbcA::ReadArraySampleCachePtr iCache,
                const bool iCacheHierarchy )
  : m_fileName( iFileName )
  , m_file( -1 )
  , m_readArraySampleCache( iCache )
{
    // OPEN THE FILE!
    htri_t exi = H5Fis_hdf5( m_fileName.c_str() );
    ABCA_ASSERT( exi == 1, "Nonexistent or not an Alembic file: "
        << m_fileName );

    m_file = H5Fopen( m_fileName.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT );
    ABCA_ASSERT( m_file >= 0,
                 "Could not open file: " << m_fileName );

    // get the version using HDF5 native calls
    int version = -INT_MAX;
    if (H5Aexists(m_file, "abc_version"))
    {
        size_t numRead = 0;
        ReadSmallArray(m_file, "abc_version",  H5T_STD_I32LE, H5T_NATIVE_INT32,
            1, numRead, &version);
    }
    ABCA_ASSERT(version >= -8 && version <= ALEMBIC_HDF5_FILE_VERSION,
        "Unsupported file version detected: " << version);

    // if it isn't there, it's pre 1.0
    int fileVersion = 9999;
    if (H5Aexists( m_file, "abc_release_version" ))
    {
        size_t numRead = 0;
        ReadSmallArray( m_file, "abc_release_version", H5T_STD_I32LE,
            H5T_NATIVE_INT32, 1, numRead, &fileVersion );
    }
    m_archiveVersion = fileVersion;

    HDF5HierarchyReader reader( m_file, m_H5H, iCacheHierarchy );
    H5Node node = m_H5H.createNode( m_file );
    H5Node abcRoot = OpenGroup( node, "ABC" );

    AbcA::MetaData metaData;
    ReadMetaData( abcRoot, ".prop.meta", metaData );
    m_header.reset( new AbcA::ObjectHeader( "ABC", "/", metaData ) );

    m_data.reset( new OrData( m_header, node, m_archiveVersion ) );
    CloseObject( abcRoot );
    ReadTimeSamples( m_file, m_timeSamples );

    if ( H5Aexists( m_file, "abc_max_samples" ) )
    {
        hid_t aid = H5Aopen( m_file, "abc_max_samples", H5P_DEFAULT );

        if ( aid < 0 )
        {
            return;
        }

        AttrCloser attrCloser( aid );

        // figure out how big it is
        hid_t sid = H5Aget_space( aid );

        if ( sid < 0 )
        {
            return;
        }

        DspaceCloser dspaceCloser( sid );

        hssize_t numPoints = H5Sget_simple_extent_npoints( sid );

        if ( numPoints < 1 )
        {
            return;
        }

        m_maxSamples.resize( numPoints );

        // do the read
        H5Aread( aid, H5T_NATIVE_LLONG, &( m_maxSamples.front() ) );

    }
}
bool CCheckpointSystem::LoadGame(const char* fileName)
{
	//make sure not not save/load recursively or multiple times at once
	if(CHECKPOINT_SAVE_XML_NODE || CHECKPOINT_LOAD_XML_NODE)
		return false;

	//set extension
	FixedCheckpointString file(fileName);
	SetFilenameExtension(file);

	CHECKPOINT_LOAD_XML_NODE = ReadXML(file.c_str());
	if(!CHECKPOINT_LOAD_XML_NODE)
		return false;

	CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_COMMENT, "Loading checkpoint %s", file.c_str());

	//check for EntityId errors
	CHECKPOINT_RESAVE_NECESSARY = false;

	//process meta data
	SCheckpointData metaData;
	if(!ReadMetaData(CHECKPOINT_LOAD_XML_NODE, metaData))
		return false;

	//check version number
	if(metaData.m_versionNumber != CHECKPOINT_VERSION_NUMBER)
	{
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Checkpoint version number (%i) does not match current version (%i). Please reexport all checkpoints of this level to prevent errors!", metaData.m_versionNumber, CHECKPOINT_VERSION_NUMBER);
	}
 
	//check for level mismatch
	CryFixedStringT<32> curlevelName = CCryAction::GetCryAction()->GetLevelName();
	RepairLevelName(curlevelName);
	if(curlevelName.empty() || stricmp(metaData.m_levelName.c_str(), curlevelName.c_str()))
	{
		if(!LoadCheckpointMap(metaData, curlevelName))
			return false;
	}
	else
	{
		//reset the dynamic parts of the engine
		ResetEngine();
	}

	//read actor data and respawn AI
	// TODO For now, not restoring actor info (AI) - If this happens later, support needs to be added for entity pools
	//RespawnAI(CHECKPOINT_LOAD_XML_NODE);

	//load gametokens again
	ReadGameTokens(CHECKPOINT_LOAD_XML_NODE);

	//let game read
	if (m_pGameHandler)
	{
		m_pGameHandler->OnReadData(CHECKPOINT_LOAD_XML_NODE);
	}

	//resets some gameplay data like action filters etc.
	RestartGameplay();

	//load external entities, that are controlled by flowgraph
	LoadExternalEntities(CHECKPOINT_LOAD_XML_NODE);

	//inform listeners
	UpdateListener(metaData, false);

	//trigger flowgraph node
	OnCheckpointLoaded(metaData);

	//draw text message on screen
	//static const ColorF color (0.0f, 0.85f, 0.2f, 1.0f);
	//g_pGame->GetIGameFramework()->GetIPersistantDebug()->Add2DText("Checkpoint loaded", 2.5f, color, 2.0f);

	//checkpoint file sanity check
	if(CHECKPOINT_RESAVE_NECESSARY)
	{
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "Checkpoint file contained obsolete or wrong data, trying to re-save checkpoint.");
		//resave checkpoint to fix changed entity Ids
		SaveGame(metaData.m_checkPointId, fileName);
		//make sure the script entity is aware of the activity
		OnCheckpointLoaded(metaData);
	}

	CHECKPOINT_LOAD_XML_NODE = NULL;

	//when a checkpoint was loaded, it becomes the most recent checkpoint
	g_lastSavedCheckpoint = fileName;

	//make sure the scripts are clean
	//CXP : this caused a crash after some reloads, which hints to problems in the gamerules script
	//gEnv->pScriptSystem->ForceGarbageCollection();

	return true;
}