Пример #1
0
// ----------------------------------------------------------------------------
//
void DefinitionReader::readFixtureDefinitions( LPCSTR directory )
{
    CFileFind finder;
    
    CString directory_search( directory );
    directory_search.Append( "\\*" );

    BOOL working = finder.FindFile( directory_search );
    if ( !working ) 
        throw StudioException( "Unable to find fixture definition directory '%s'", directory );

    while ( working ) {
        working = finder.FindNextFile();
        if ( finder.IsDots() )
            continue;

        CString file_name = finder.GetFilePath();
        if ( finder.IsDirectory() )
            readFixtureDefinitions( file_name );

        CString test_name( file_name );
        if ( test_name.MakeLower().Find( ".xml" ) == -1 )
            continue;

        // Check for definition file
        TiXmlDocument doc;
        if ( !doc.LoadFile( file_name ) )
            throw StudioException( "Error reading fixture definition '%s'", file_name );

        try {
            TiXmlElement* root = doc.FirstChildElement( "fixture_definitions" );
            LPCSTR author = read_text_element( root, "author" );
            LPCSTR version = read_text_element( root, "version" );

            FixtureDefinitionPtrArray fixture_definitions = read_xml_list<FixtureDefinition>( root, "fixture" );

            //DefinitionWriter writer;
            //writer.writeFixtureDefinition( file_name, author, version, fixture_definitions );

            for ( FixtureDefinition* definition : fixture_definitions ) {
                definition->setSourceFile( file_name );
                definition->m_author = author;
                definition->m_version = version;

                FixtureDefinition::addFixtureDefinition( definition );
                delete definition;
            }
        }
        catch ( StudioException e ) {
            throw StudioException( "%s: %s", file_name, e.what() );
        }
    }
    
    finder.Close();
}
Пример #2
0
// ----------------------------------------------------------------------------
//
bool HttpRestServices::edit_venue_new( CString& response, LPCSTR data, DWORD size, LPCSTR content_type )
{
    SimpleJsonParser parser;
    CString reset_what;

    try {
        parser.parse( data );
        reset_what = parser.get<CString>( "reset_what" );
    }
    catch ( std::exception& e ) {
        throw StudioException( "JSON parser error (%s) data (%s)", e.what(), data );
    }

    if ( reset_what == "new" ) {
        studio.newVenue();
    }
    else if ( reset_what == "chases" ) {
        studio.getVenue()->deleteAllChases();
    }
    else if ( reset_what == "groups" ) {
        studio.getVenue()->deleteAllFixtureGroups();
    }
    else if ( reset_what == "scenes" ) {
        studio.getVenue()->deleteAllScenes();
    }
    else
        return false;

    return true;
}
Пример #3
0
// ----------------------------------------------------------------------------
//
static bool music_matcher_load( Venue* venue, LPCSTR data, boolean clearFirst ) {
    SimpleJsonParser parser;

    std::vector<MusicSceneSelector> selections;

    try {
        parser.parse( data );

        JsonNodePtrArray selection_parsers = parser.getObjects();

        for ( JsonNode* selection : selection_parsers ) {
            UID selection_id = selection->get<UID>( "id" );
            CString selection_name = selection->get<CString>( "track" );
            CString selection_link = selection->get<CString>( "link" );
            MusicSelectorType selection_type = (MusicSelectorType)selection->get<int>( "type" );

            selections.push_back( MusicSceneSelector( selection_name, selection_link, selection_type, selection_id ) );
        }
    }
    catch ( std::exception& e ) {
        throw StudioException( "JSON parser error (%s) data (%s)", e.what(), data );
    }

    // Reload the selection map
    if ( clearFirst )
        venue->clearMusicMappings();

    venue->addMusicMappings( selections );

    return true;
}
Пример #4
0
// ----------------------------------------------------------------------------
//
bool HttpRestServices::edit_scene_copy_fixtures( CString& response, LPCSTR data, DWORD size, LPCSTR content_type ) {

    if ( !studio.getVenue() || !studio.getVenue()->isRunning() )
        return false;

    SimpleJsonParser parser;
    bool clear;
    bool keep_groups;
    ULONG scene_id;
    UIDArray actors;

    try {
        parser.parse( data );

        clear = parser.get<bool>( "clear" );
        scene_id = parser.get<unsigned long>( "scene_id" );
        keep_groups = parser.get<bool>( "keep_groups" );
        actors = parser.get<UIDArray>( "fixture_ids" );
    }
    catch ( std::exception& e ) {
        DMXStudio::log( StudioException( "JSON parser error (%s) data (%s)", e.what(), data ) );
        return false;
    }

    studio.getVenue()->moveDefaultFixturesToScene(scene_id, actors, keep_groups, clear );

    return true;
}
Пример #5
0
// ----------------------------------------------------------------------------
//
bool HttpRestServices::player_login( Venue* venue, DMXHttpSession* session, CString& response, LPCSTR data, DWORD size, LPCSTR content_type )
{
    SimpleJsonParser parser;
    CString username;
    CString password;

    try {
        parser.parse( data );

        username = parser.get<CString>( "username" );
        password = parser.get<CString>( "password" );
    }
    catch ( std::exception& e ) {
        throw StudioException( "JSON parser error (%s) data (%s)", e.what(), data );
    }

    JsonBuilder json( response );
    json.startObject();

    if ( studio.getMusicPlayer()->signon( username, password ) ) {
        json.add( "logged_in", true );
    }
    else {
        CString login_error = studio.getMusicPlayer()->getLastPlayerError();

        if ( login_error.IsEmpty() )
            login_error = "Login failed";

        json.add( "logged_in", false );
        json.add( "login_error", login_error );
    }

    json.endObject();
    return true;
}
Пример #6
0
// ----------------------------------------------------------------------------
//
Venue* VenueReader::readFromString( LPCSTR xml_data )
{
    TiXmlDocument doc;
    if ( !doc.Parse( xml_data ) )
        throw StudioException( "Error parsing venue '%s' (%s)", xml_data, doc.ErrorDesc() );

    return read( doc.FirstChildElement(), (Venue *)NULL );
}
Пример #7
0
// ----------------------------------------------------------------------------
//
Venue* VenueReader::readFromFile( LPCSTR input_file )
{
    TiXmlDocument doc;
    if ( !doc.LoadFile( input_file ) )
        throw StudioException( "Error reading venue '%s' (%s)", input_file, doc.ErrorDesc() );

    return read( doc.FirstChildElement(), (Venue *)NULL );
}
Пример #8
0
// ----------------------------------------------------------------------------
//
CString DMXStudio::getUserDocumentDirectory()
{
    char input_file[MAX_PATH]; 
    HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, input_file); 
    if ( result != S_OK )
        throw StudioException( "Error %d finding document directory", result );
    return CString( input_file );
}
Пример #9
0
// ----------------------------------------------------------------------------
//
AnalyzeInfo* SpotifyEngine::loadTrackAnalysis( LPCSTR spotify_id )
{
    TrackAnalysisCache::iterator it = m_track_analysis_cache.find( spotify_id );
    if ( it != m_track_analysis_cache.end() )
        return (it)->second;

    // See if it existing on disk - if available, load into the cache and return
    CString filename = makeTrackAnalysisFileName( m_trackAnalysisContainer, spotify_id );

    if ( GetFileAttributes( filename ) == INVALID_FILE_ATTRIBUTES )
        return NULL;

    FILE* hFile = _fsopen( filename, "rt", _SH_DENYWR );
    if ( hFile == NULL ) {
        log( "Unable to read track analysis from %s", filename );
        return NULL;
    }

    // Get file size
    fseek( hFile, 0L, SEEK_END );
    size_t size = ftell( hFile );
    rewind( hFile );

    CString data;
    fread( data.GetBufferSetLength(size), 1, size, hFile );
    fclose( hFile );
        
    SimpleJsonParser parser;

    try {
        parser.parse( data );

        CString spotify_id = parser.get<CString>( "link" );

        SimpleJsonParser amplitute_parser = parser.get<SimpleJsonParser>( "amplitude" );

        size_t data_count = amplitute_parser.get<size_t>( "data_count" );
        UINT duration_ms = amplitute_parser.get<size_t>( "duration_ms" );
        std::vector<uint16_t> amplitude_data = amplitute_parser.getArray<uint16_t>( "data" );

        AnalyzeInfo* info = (AnalyzeInfo*)calloc( sizeof(AnalyzeInfo) + (sizeof(uint16_t) * data_count), 1 );
        for ( size_t i=0; i < data_count; i++ )
            info->data[i] = amplitude_data[i];

        strncpy_s( info->link, spotify_id, sizeof(info->link) );
        info->data_count = data_count;
        info->duration_ms = duration_ms;
        m_track_analysis_cache[info->link] = info;

        return info;
    }
    catch ( std::exception& e ) {
        log( StudioException( "JSON parser error (%s) data (%s)", e.what(), data ) );
        return NULL;
    }
}
Пример #10
0
// ----------------------------------------------------------------------------
//
void DefinitionReader::readFixtureDefinitions( )
{
    TCHAR definitions_root[MAX_PATH]; 

    GetCurrentDirectory( MAX_PATH, definitions_root );
    strcat_s( definitions_root, "\\FixtureDefinitions" );

    DWORD attributes = GetFileAttributes( definitions_root );

    if ( attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY) )
        throw StudioException( "Unable to find fixture definition directory '%s'", definitions_root );

    readFixtureDefinitions( definitions_root );

    size_t definitions = FixtureDefinition::FixtureDefinitions.size();

    if ( definitions == 0 )
        throw StudioException( "No fixture definitions found in '%s'", definitions_root );

    DMXStudio::log_status( "Found %d fixture personality definitions", definitions );
}
Пример #11
0
// ----------------------------------------------------------------------------
//
bool HttpRestServices::edit_venue_load( CString& response, LPCSTR data, DWORD size, LPCSTR content_type )
{
    SimpleJsonParser parser;
    CString venue_filename;

    try {
        parser.parse( data );
        venue_filename = parser.get<CString>( "venue_filename" );
        venue_filename.Replace( "\\\\", "\\" );
    }
    catch ( std::exception& e ) {
        throw StudioException( "JSON parser error (%s) data (%s)", e.what(), data );
    }

    return studio.loadVenueFromFile( (LPCSTR)venue_filename );
}
Пример #12
0
// ----------------------------------------------------------------------------
//
bool HttpRestServices::edit_venue_update( CString& response, LPCSTR data, DWORD size, LPCSTR content_type ) {

    Venue* venue = studio.getVenue();
    if ( !venue )
        return false;

    SimpleJsonParser parser;

    try {
        parser.parse( data );

        CString name = parser.get<CString>( "name" );
        CString description = parser.get<CString>( "description" );
        CString dmx_port = parser.get<CString>( "dmx_port" );
        CString audio_capture_device = parser.get<CString>( "audio_capture_device" );
        int dmx_packet_delay_ms = parser.get<int>( "dmx_packet_delay_ms" );
        int dmx_minimum_delay_ms = parser.get<int>( "dmx_minimum_delay_ms" );
        int audio_sample_size = parser.get<int>( "audio_sample_size" );
        float audio_boost = parser.get<float>( "audio_boost" );
        float audio_boost_floor = parser.get<float>( "audio_boost_floor" );
        int auto_blackout = parser.get<int>( "auto_blackout" );

        // There may be a better solution for this, but we need to kill all attached sound devices before the reset
        m_sound_sampler.detach();

        venue->close();

        venue->setName( name );
        venue->setDescription( description );
        venue->setDmxPort( dmx_port );
        venue->setDmxPacketDelayMS( dmx_packet_delay_ms );
        venue->setDmxMinimumDelayMS( dmx_minimum_delay_ms );
        venue->setAudioCaptureDevice( audio_capture_device );
        venue->setAudioBoost( audio_boost );
        venue->setAudioBoostFloor( audio_boost_floor );
        venue->setAudioSampleSize( audio_sample_size );
        venue->setAutoBlackout( auto_blackout );

        venue->open();
    }
    catch ( std::exception& e ) {
        throw StudioException( "JSON parser error (%s) data (%s)", e.what(), data );
    }

    return true;
}
Пример #13
0
// ----------------------------------------------------------------------------
//
void DMXStudio::writeVenueToFile( LPCSTR output_file )
{
    // Create the path if it does not exist
    CString path( output_file ); 
    int pos = path.ReverseFind( '\\' ); 
 
    if ( pos != -1) {
        path = path.Left( pos+1 );      
        if ( !PathFileExists( path ) )
            if ( !CreateDirectory( path, NULL ) )	// TODO - need to created entire path
                throw StudioException( "Cannot create directory '%s' (ERROR %lu)", 
                                       path, GetLastError() );
    }

    CSingleLock lock( &m_venue_mutex, TRUE );

    VenueWriter writer;
    writer.writeToFile( m_venue, output_file );
}
Пример #14
0
// ----------------------------------------------------------------------------
//
bool DMXStudio::handleEvent( const Event& event )
{
    if ( isDebug() ) {
        CString output( "EVENT " );
        output.Append( (LPCSTR)EventBus::eventAsString( event ) );
        log_status( output );
    }

    if ( event.m_source == ES_VENUE ) {
        if ( event.m_action == EA_START )
            log_status( "Venue started [%s]", event.m_text );
        else if ( event.m_action == EA_STOP )
            log_status( "Venue stopped [%s]", event.m_text );
        else if ( event.m_action == EA_ERROR )
            log( StudioException( event.m_text ) );
    }

    return false;
}
Пример #15
0
// ----------------------------------------------------------------------------
//
bool HttpRestServices::edit_scene( CString& response, LPCSTR data, EditMode mode ) {
    if ( !studio.getVenue() || !studio.getVenue()->isRunning() )
        return false;

    SimpleJsonParser parser;
    UID scene_id;
    CString name, description;
    SceneNumber number;
    BPMRating bpm_rating;
    bool keep_groups;
    Scene* scene = NULL;
    UIDArray actors;
    PARSER_LIST animationParsers;
    std::vector<AbstractAnimation*> animations;
    Acts acts;

    try {
        parser.parse( data );

        scene_id = parser.get<ULONG>( "id" );
        name = parser.get<CString>( "name" );
        description = parser.get<CString>( "description" );
        number = parser.get<ULONG>( "number" );
        bpm_rating = (BPMRating)parser.get<UINT>( "bpm_rating" );
        keep_groups = parser.get<bool>( "keep_groups" );
        actors = parser.get<UIDArray>( "actors" );
        animationParsers = parser.get<PARSER_LIST>("animations");
        acts = parser.get<Acts>( "acts" );

        for ( PARSER_LIST::iterator it=animationParsers.begin(); it != animationParsers.end(); ++it ) {
            CString class_name = (*it).get<CString>( "class_name" );
            UIDArray animation_actors = (*it).get<UIDArray>( "actors" );
            SimpleJsonParser signalParser = (*it).get<SimpleJsonParser>( "signal" );
            SimpleJsonParser animationParser = (*it).get<SimpleJsonParser>( class_name );
            AnimationSignal signal = parseAnimationSignal( signalParser );

            ANIMATION_PARSER_FUNC anim_parser_func = animation_parsers[ class_name ];
            if ( anim_parser_func == NULL )
                throw std::exception( "Unknown animation class name from client" );

            animations.push_back( anim_parser_func( animationParser, signal, animation_actors ) );
        }
    }
    catch ( std::exception& e ) {
        throw StudioException( "JSON parser error (%s) data (%s)", e.what(), data );
    }

    if ( scene_id != 0 ) {
        scene = studio.getVenue()->getScene( scene_id );
        if ( !scene )
            return false;
    }

    // Make sure number is unique
    if ( mode != UPDATE || (scene && number != scene->getNumber()) ) {
        if ( studio.getVenue()->getSceneByNumber( number ) != NULL )
            return false;
    }

    switch ( mode ) {
    case NEW: {
        scene_id = studio.getVenue()->allocUID();
        Scene new_scene;
        new_scene.setUID( scene_id );
        studio.getVenue()->addScene( new_scene );
        scene = studio.getVenue()->getScene( scene_id );
        studio.getVenue()->moveDefaultFixturesToScene( scene_id, actors, keep_groups, true );
        break;
    }

    case COPY: {
        scene_id = studio.getVenue()->allocUID();
        Scene new_scene( *scene );
        new_scene.setUID( scene_id );
        studio.getVenue()->addScene( new_scene );
        scene = studio.getVenue()->getScene( scene_id );
    }

    // Fall through

    case UPDATE:
        // Verify actors - remove any that have been deselected
        UIDArray active_actors = scene->getActorUIDs();
        for ( UIDArray::iterator it=active_actors.begin(); it != active_actors.end(); ++it ) {
            if ( std::find( actors.begin(), actors.end(), *it ) == actors.end() )
                scene->removeActor( *it );
        }
        break;
    }

    scene->setName( name );
    scene->setSceneNumber( number );
    scene->setBPMRating( bpm_rating );
    scene->setDescription( description );
    scene->setActs( acts );

    scene->clearAnimations();
    for ( std::vector<AbstractAnimation*>::iterator it=animations.begin(); it != animations.end(); ++it )
        scene->addAnimation( *it );

    if ( mode != UPDATE )            // Switch to new scene
        studio.getVenue()->selectScene( scene->getUID() );
    else if ( studio.getVenue()->getCurrentSceneUID() == scene->getUID() )
        studio.getVenue()->loadScene( );

    return true;
}