Changeset db1f217 in lilv


Ignore:
Timestamp:
10/28/15 21:29:33 (22 months ago)
Author:
David Robillard <d@…>
Branches:
master
Children:
32a4463
Parents:
efc94d3
Message:

Support reloading bundles

git-svn-id: http://svn.drobilla.net/lad/trunk/lilv@5797 a436a847-0d15-0410-975c-d299462d15a1

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • NEWS

    rfa730d2 rdb1f217  
    11lilv (0.22.1) unstable; 
    22 
     3  * Unload contained resources when bundle is unloaded 
     4  * Support re-loading plugins 
    35  * Fix Python bindings 
    46  * Fix documentation installation 
    57  * Fix outdated comment references to lilv_uri_to_path() 
    68 
    7  -- David Robillard <d@drobilla.net>  Wed, 28 Oct 2015 14:31:05 -0400 
     9 -- David Robillard <d@drobilla.net>  Thu, 29 Oct 2015 00:23:04 -0400 
    810 
    911lilv (0.22.0) stable; 
  • lilv/lilv.h

    rfa730d2 rdb1f217  
    578578*/ 
    579579LILV_API void 
    580 lilv_world_load_bundle(LilvWorld* world, 
    581                        LilvNode* bundle_uri); 
     580lilv_world_load_bundle(LilvWorld*      world, 
     581                       const LilvNode* bundle_uri); 
    582582 
    583583/** 
     
    610610*/ 
    611611LILV_API int 
    612 lilv_world_unload_bundle(LilvWorld* world, LilvNode* bundle_uri); 
     612lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri); 
    613613 
    614614/** 
  • src/lilv_internal.h

    r27c4df1 rdb1f217  
    11/* 
    2   Copyright 2007-2014 David Robillard <http://drobilla.net> 
     2  Copyright 2007-2015 David Robillard <http://drobilla.net> 
    33 
    44  Permission to use, copy, modify, and/or distribute this software for any 
     
    283283LilvUIs*           lilv_uis_new(void); 
    284284 
    285 LilvNode* lilv_world_get_manifest_uri(LilvWorld* world, LilvNode* bundle_uri); 
     285LilvNode* lilv_world_get_manifest_uri(LilvWorld*      world, 
     286                                      const LilvNode* bundle_uri); 
    286287 
    287288const uint8_t* lilv_world_blank_node_prefix(LilvWorld* world); 
  • src/world.c

    r842e254 rdb1f217  
    11/* 
    2   Copyright 2007-2014 David Robillard <http://drobilla.net> 
     2  Copyright 2007-2015 David Robillard <http://drobilla.net> 
    33 
    44  Permission to use, copy, modify, and/or distribute this software for any 
     
    372372 
    373373static void 
    374 lilv_world_add_plugin(LilvWorld*       world, 
    375                       const SordNode*  plugin_node, 
    376                       const LilvNode*  manifest_uri, 
    377                       void*            dynmanifest, 
    378                       const SordNode*  bundle_node) 
    379 { 
    380     LilvNode* plugin_uri = lilv_node_new_from_node(world, plugin_node); 
    381  
    382     const LilvPlugin* last = lilv_plugins_get_by_uri(world->plugins, 
    383                                                      plugin_uri); 
    384     if (last) { 
    385         LILV_ERRORF("Duplicate plugin <%s>\n", lilv_node_as_uri(plugin_uri)); 
    386         LILV_ERRORF("... found in %s\n", lilv_node_as_string( 
    387                         lilv_plugin_get_bundle_uri(last))); 
    388         LILV_ERRORF("... and      %s\n", sord_node_get_string(bundle_node)); 
    389         lilv_node_free(plugin_uri); 
    390         return; 
    391     } 
    392  
    393     // Create LilvPlugin 
    394     LilvNode*   bundle_uri = lilv_node_new_from_node(world, bundle_node); 
    395     LilvPlugin* plugin     = lilv_plugin_new(world, plugin_uri, bundle_uri); 
    396  
    397     // Add manifest as plugin data file (as if it were rdfs:seeAlso) 
    398     zix_tree_insert((ZixTree*)plugin->data_uris, 
    399                     lilv_node_duplicate(manifest_uri), 
    400                     NULL); 
     374lilv_world_add_plugin(LilvWorld*      world, 
     375                      const SordNode* plugin_node, 
     376                      const LilvNode* manifest_uri, 
     377                      void*           dynmanifest, 
     378                      const SordNode* bundle) 
     379{ 
     380    LilvNode*   plugin_uri = lilv_node_new_from_node(world, plugin_node); 
     381    LilvPlugin* plugin     = (LilvPlugin*)lilv_plugins_get_by_uri( 
     382        world->plugins, plugin_uri); 
     383 
     384    if (plugin) { 
     385        // Existing plugin, if this is different bundle, ignore it 
     386        // (use the first plug found in LV2_PATH) 
     387        const LilvNode* last_bundle    = lilv_plugin_get_bundle_uri(plugin); 
     388        const char*     plugin_uri_str = lilv_node_as_uri(plugin_uri); 
     389        if (sord_node_equals(bundle, last_bundle->node)) { 
     390            LILV_WARNF("Reloading plugin <%s>\n", plugin_uri_str); 
     391            plugin->loaded = false; 
     392            lilv_node_free(plugin_uri); 
     393        } else { 
     394            LILV_ERRORF("Duplicate plugin <%s>\n", plugin_uri_str); 
     395            LILV_ERRORF("... found in %s\n", lilv_node_as_string(last_bundle)); 
     396            LILV_ERRORF("... and      %s\n", sord_node_get_string(bundle)); 
     397            lilv_node_free(plugin_uri); 
     398            return; 
     399        } 
     400    } else { 
     401        // Add new plugin to the world 
     402        plugin = lilv_plugin_new( 
     403            world, plugin_uri, lilv_node_new_from_node(world, bundle)); 
     404 
     405        // Add manifest as plugin data file (as if it were rdfs:seeAlso) 
     406        zix_tree_insert((ZixTree*)plugin->data_uris, 
     407                        lilv_node_duplicate(manifest_uri), 
     408                        NULL); 
     409 
     410        // Add plugin to world plugin sequence 
     411        zix_tree_insert((ZixTree*)world->plugins, plugin, NULL); 
     412    } 
     413 
    401414 
    402415#ifdef LILV_DYN_MANIFEST 
    403416    // Set dynamic manifest library URI, if applicable 
    404417    if (dynmanifest) { 
    405         plugin->dynmanifest = (LilvDynManifest*)dynmanifest; 
     418        plug->dynmanifest = (LilvDynManifest*)dynmanifest; 
    406419        ++((LilvDynManifest*)dynmanifest)->refs; 
    407420    } 
     
    421434    } 
    422435    sord_iter_free(files); 
    423  
    424     // Add plugin to world plugin sequence 
    425     zix_tree_insert((ZixTree*)world->plugins, plugin, NULL); 
    426436} 
    427437 
     
    571581 
    572582LilvNode* 
    573 lilv_world_get_manifest_uri(LilvWorld* world, LilvNode* bundle_uri) 
     583lilv_world_get_manifest_uri(LilvWorld* world, const LilvNode* bundle_uri) 
    574584{ 
    575585    SerdNode manifest_uri = lilv_new_uri_relative_to_base( 
     
    582592 
    583593LILV_API void 
    584 lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri) 
     594lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri) 
    585595{ 
    586596    if (!lilv_node_is_uri(bundle_uri)) { 
     
    634644 
    635645static int 
    636 lilv_world_drop_graph(LilvWorld* world, LilvNode* graph) 
     646lilv_world_drop_graph(LilvWorld* world, const LilvNode* graph) 
    637647{ 
    638648    SordIter* i = sord_search(world->model, NULL, NULL, NULL, graph->node); 
     
    652662/** Remove loaded_files entry so file will be reloaded if requested. */ 
    653663static int 
    654 lilv_world_unload_file(LilvWorld* world, LilvNode* file) 
     664lilv_world_unload_file(LilvWorld* world, const LilvNode* file) 
    655665{ 
    656666    ZixTreeIter* iter; 
     
    663673 
    664674LILV_API int 
    665 lilv_world_unload_bundle(LilvWorld* world, LilvNode* bundle_uri) 
     675lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri) 
    666676{ 
    667677    if (!bundle_uri) { 
     
    669679    } 
    670680 
    671     // Remove loaded_files entry for manifest.ttl 
    672     LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri); 
    673     lilv_world_unload_file(world, manifest); 
    674     lilv_node_free(manifest); 
     681    // Unload any files, including manifest.ttl 
     682    LilvNodes* files = lilv_nodes_new(); 
     683    LILV_FOREACH(nodes, i, world->loaded_files) { 
     684        const LilvNode* file = lilv_nodes_get(world->loaded_files, i); 
     685        if (!strncmp(lilv_node_as_string(file), 
     686                     lilv_node_as_string(bundle_uri), 
     687                     strlen(lilv_node_as_string(bundle_uri)))) { 
     688            zix_tree_insert((ZixTree*)files, 
     689                            lilv_node_duplicate(file), 
     690                            NULL); 
     691        } 
     692    } 
     693 
     694    LILV_FOREACH(nodes, i, files) { 
     695        const LilvNode* file = lilv_nodes_get(world->plugins, i); 
     696        lilv_world_unload_file(world, file); 
     697    } 
     698 
     699    lilv_nodes_free(files); 
    675700 
    676701    // Drop everything in bundle graph 
  • test/lilv_test.c

    re57faf2 rdb1f217  
    160160    test_count++;\ 
    161161    if (!(check)) {\ 
    162         assert(false);\ 
    163162        error_count++;\ 
    164         fprintf(stderr, "lilv_test.c:%d: error: %s\n", __LINE__, #check);\ 
     163        fprintf(stderr, "lilv_test.c:%d: error: test `%s' failed\n", __LINE__, #check);\ 
     164        assert(check);\ 
    165165    }\ 
    166166} while (0) 
     
    19411941/*****************************************************************************/ 
    19421942 
     1943static int 
     1944test_reload_bundle(void) 
     1945{ 
     1946    // Create a simple plugin bundle 
     1947    create_bundle(MANIFEST_PREFIXES 
     1948                  ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n", 
     1949                  BUNDLE_PREFIXES 
     1950                  ":plug a lv2:Plugin ; " 
     1951                  PLUGIN_NAME("First name") " ."); 
     1952 
     1953    if (!init_world()) { 
     1954        return 0; 
     1955    } 
     1956 
     1957    init_uris(); 
     1958    lilv_world_load_specifications(world); 
     1959 
     1960    // Load bundle 
     1961    LilvNode* bundle_uri = lilv_new_uri(world, bundle_dir_uri); 
     1962    lilv_world_load_bundle(world, bundle_uri); 
     1963 
     1964    // Check that plugin is present 
     1965    const LilvPlugins* plugins = lilv_world_get_all_plugins(world); 
     1966    const LilvPlugin*  plug    = lilv_plugins_get_by_uri(plugins, plugin_uri_value); 
     1967    TEST_ASSERT(plug); 
     1968 
     1969    // Check that plugin name is correct 
     1970    LilvNode* name = lilv_plugin_get_name(plug); 
     1971    TEST_ASSERT(!strcmp(lilv_node_as_string(name), "First name")); 
     1972    lilv_node_free(name); 
     1973 
     1974    // Unload bundle from world and delete it 
     1975    lilv_world_unload_bundle(world, bundle_uri); 
     1976    delete_bundle(); 
     1977 
     1978    // Create a new version of the same bundle, but with a different name 
     1979    create_bundle(MANIFEST_PREFIXES 
     1980                  ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n", 
     1981                  BUNDLE_PREFIXES 
     1982                  ":plug a lv2:Plugin ; " 
     1983                  PLUGIN_NAME("Second name") " ."); 
     1984 
     1985    // Load new bundle 
     1986    lilv_world_load_bundle(world, bundle_uri); 
     1987 
     1988    // TODO: Mechanism to actually remove plugin from world list 
     1989 
     1990    // Check that plugin is present again 
     1991    const LilvPlugin* plug2 = lilv_plugins_get_by_uri(plugins, plugin_uri_value); 
     1992    TEST_ASSERT(plug2); 
     1993 
     1994    // Check that plugin now has new name 
     1995    LilvNode* name2 = lilv_plugin_get_name(plug2); 
     1996    TEST_ASSERT(name2); 
     1997    TEST_ASSERT(!strcmp(lilv_node_as_string(name2), "Second name")); 
     1998    lilv_node_free(name2); 
     1999 
     2000    lilv_node_free(bundle_uri); 
     2001    lilv_world_free(world); 
     2002    world = NULL; 
     2003 
     2004    return 1; 
     2005} 
     2006 
     2007/*****************************************************************************/ 
     2008 
    19432009/* add tests here */ 
    19442010static struct TestCase tests[] = { 
     
    19642030    TEST_CASE(world), 
    19652031    TEST_CASE(state), 
     2032    TEST_CASE(reload_bundle), 
    19662033    { NULL, NULL } 
    19672034}; 
Note: See TracChangeset for help on using the changeset viewer.