Help - Search - Members - Calendar
Full Version: Use static_api_ptr_t<metadb_io_v2>()->update_info_async
Hydrogenaudio Forums > Hosted Forums > foobar2000 > Development - (fb2k)
cjard
All

So, I'm having a play about with writing a foobar plugin that updates tags.. I'm finding it pretty hard going because I'm a C# guy and the C++ ide is far less helpful, combined with my understanding of pointers/de/referencing being pretty ropey and the doxygen docs being a bit alien to me

When I use file_info_update_helper I get warnings about metadb_io being deprecated. I'm not entirely sure whether this is a problem; if there is a better method for me to use, I'd like to use it, but I can't figure out how to use metadb_io_v2::update_info_async_simple with lists/arrays of items (it's the other thing I want to do because right now, I just call it once per loop of all my items passing in pfc::list_single_ref_t - this means progress bars don't work and I just doesnt sit right with me as 'the right way to do it' )

If anyone could give me some guidance on using the recommended method, and how to pass a list of items I'd much apprecaite it.. Here's the crux of the code I've done for this:
CODE
   void renumber_tracks(unsigned discnumber, metadb_handle_list items){

    discnumber++;

    file_info_impl finfo;
    metadb_handle_ptr item;

    int tmpint = 0;
    int lowest = 9999;
    int highest = -9999;
    int numtrk = 0;
    const char *tmpstrc;



    //find the lowest track number here already
    for(int i = 0; i < (int)items.get_count(); i++)
    {
      item = items.get_item(i);

      item->get_info(finfo);

      tmpstrc = finfo.meta_get("TRACKNUMBER", 0);

      if(sscanf_s(tmpstrc, "%d", &tmpint)  == EOF ) {
        uMessageBox(NULL, "Cannot proceed: A track number is not numeric", "Problem", MB_OK  | MB_ICONERROR);
        return;
      }
      if(tmpint < lowest)
        lowest = tmpint;
      if(tmpint > highest)
        highest = tmpint;
      numtrk++;
    }

    char tmpstr[4];


    for(int i = 0; i < (int)items.get_count(); i++)
    {
      item = items.get_item(i);

      item->get_info(finfo);

      tmpstrc = finfo.meta_get("TRACKNUMBER", 0);

      if(sscanf_s(tmpstrc, "%d", &tmpint)  == EOF ) {
        uMessageBox(NULL, "Cannot proceed: A track number is not numeric", "Problem", MB_OK  | MB_ICONERROR);
        return;
      }

      tmpint -= lowest;
      tmpint++;

      sprintf_s(tmpstr, "%02d", tmpint);
      finfo.meta_set("TRACKNUMBER", tmpstr);
      //uMessageBox(NULL, tmpstr, "TRACKNUMBER", MB_OK);

      sprintf_s(tmpstr, "%02d", discnumber);
      finfo.meta_set("DISCNUMBER", tmpstr);
      //uMessageBox(NULL, tmpstr, "DISCNUMBER", MB_OK);

      sprintf_s(tmpstr, "%02d", numtrk);
      finfo.meta_set("TOTALTRACKS", tmpstr);
      //uMessageBox(NULL, tmpstr, "TOTALTRACKS", MB_OK);

      static_api_ptr_t<metadb_io_v2>()->update_info_async_simple(
        pfc::list_single_ref_t<metadb_handle_ptr>(item),
        pfc::list_single_ref_t<const file_info*>(&finfo),
        core_api::get_main_window(), NULL, NULL
        );
    }

  }


Comments/criticism welcome

Thanks!
Yirkha
(Warning: All my code untested.)

CODE
   void renumber_tracks(unsigned discnumber, metadb_handle_list items)
Better use references to avoid useless copying of the whole contents, also const-correctness is a good thing.
CODE
   void renumber_tracks(unsigned discnumber, const metadb_handle_list &items)


The same goes for info handling, it's is faster when just the pointer to the internal structure is used instead of copying, for example:
CODE
{
  in_metadb_sync_fromhandle lock(item);
  const file_info *info;
  if (item->get_info_locked(info)) {
    tmpstrc = info->meta_get("TRACKNUMBER", 0);
    ...
  }
}
Note the database must be locked during *_locked operations.


For your main question, create a list of info instances, fill them with the correct information, then just call update_info_async_simple() at the end.
CODE
  pfc::list_t<file_info_impl> info;
  info.set_size(items.get_count());

  for(int i = 0; i < (int)items.get_count(); i++) {
      item = items.get_item(i);
      item->get_info(info[i]);

...
      info[i].meta_set("TRACKNUMBER", tmpstr);
...
  }

  static_api_ptr_t<metadb_io_v2>()->update_info_async_simple(
    items,
    pfc::ptr_list_const_array_t<const file_info, file_info_impl *>(info.get_ptr(), info.get_count()), // *changed from info to the wrapper object
    core_api::get_main_window(), NULL, NULL
  );


Edit: Changed *marked lines in the code for it to be closer to a working code. (v2)
cjard
Yirkha, implemented all your bits apart from the locking (will get to that one..) - many thanks, your untested code worked right out of the box! Nice one smile.gif
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.