PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/xbmc/PartyModeManager.cpp

https://github.com/weitao2012/android-1
C++ | 698 lines | 560 code | 78 blank | 60 comment | 104 complexity | 651e5412ef5973f65ee2a61a7d03c07e MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*
  2. * Copyright (C) 2005-2008 Team XBMC
  3. * http://www.xbmc.org
  4. *
  5. * This Program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2, or (at your option)
  8. * any later version.
  9. *
  10. * This Program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with XBMC; see the file COPYING. If not, write to
  17. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18. * http://www.gnu.org/copyleft/gpl.html
  19. *
  20. */
  21. #include "threads/SystemClock.h"
  22. #include "PartyModeManager.h"
  23. #include "PlayListPlayer.h"
  24. #include "music/MusicDatabase.h"
  25. #include "music/windows/GUIWindowMusicPlaylist.h"
  26. #include "video/VideoDatabase.h"
  27. #include "playlists/SmartPlayList.h"
  28. #include "dialogs/GUIDialogProgress.h"
  29. #include "GUIUserMessages.h"
  30. #include "guilib/GUIWindowManager.h"
  31. #include "dialogs/GUIDialogOK.h"
  32. #include "playlists/PlayList.h"
  33. #include "settings/Settings.h"
  34. #include "utils/TimeUtils.h"
  35. #include "utils/log.h"
  36. using namespace std;
  37. using namespace PLAYLIST;
  38. #define QUEUE_DEPTH 10
  39. CPartyModeManager::CPartyModeManager(void)
  40. {
  41. m_bIsVideo = false;
  42. m_bEnabled = false;
  43. m_strCurrentFilterMusic.Empty();
  44. m_strCurrentFilterVideo.Empty();
  45. ClearState();
  46. }
  47. CPartyModeManager::~CPartyModeManager(void)
  48. {
  49. }
  50. bool CPartyModeManager::Enable(PartyModeContext context /*= PARTYMODECONTEXT_MUSIC*/, const CStdString& strXspPath /*= ""*/)
  51. {
  52. // Filter using our PartyMode xml file
  53. CSmartPlaylist playlist;
  54. CStdString partyModePath;
  55. bool playlistLoaded;
  56. m_bIsVideo = context == PARTYMODECONTEXT_VIDEO;
  57. if (!strXspPath.IsEmpty()) //if a path to a smartplaylist is supplied use it
  58. partyModePath = strXspPath;
  59. else if (m_bIsVideo)
  60. partyModePath = g_settings.GetUserDataItem("PartyMode-Video.xsp");
  61. else
  62. partyModePath = g_settings.GetUserDataItem("PartyMode.xsp");
  63. playlistLoaded=playlist.Load(partyModePath);
  64. if ( playlistLoaded )
  65. {
  66. m_type = playlist.GetType();
  67. if (context == PARTYMODECONTEXT_UNKNOWN)
  68. {
  69. //get it from the xsp file
  70. m_bIsVideo = (m_type.Equals("video") || m_type.Equals("mixed"));
  71. }
  72. if (m_type.Equals("mixed"))
  73. playlist.SetType("songs");
  74. if (m_type.Equals("mixed"))
  75. playlist.SetType("video");
  76. playlist.SetType(m_type);
  77. }
  78. else
  79. {
  80. m_strCurrentFilterMusic.Empty();
  81. m_strCurrentFilterVideo.Empty();
  82. m_type = m_bIsVideo ? "musicvideos" : "songs";
  83. }
  84. CGUIDialogProgress* pDialog = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
  85. int iHeading = (m_bIsVideo ? 20250 : 20121);
  86. int iLine0 = (m_bIsVideo ? 20251 : 20123);
  87. pDialog->SetHeading(iHeading);
  88. pDialog->SetLine(0, iLine0);
  89. pDialog->SetLine(1, "");
  90. pDialog->SetLine(2, "");
  91. pDialog->StartModal();
  92. ClearState();
  93. unsigned int time = XbmcThreads::SystemClockMillis();
  94. vector< pair<int,int> > songIDs;
  95. if (m_type.Equals("songs") || m_type.Equals("mixed"))
  96. {
  97. CMusicDatabase db;
  98. if (db.Open())
  99. {
  100. set<CStdString> playlists;
  101. if ( playlistLoaded )
  102. {
  103. m_strCurrentFilterMusic = playlist.GetWhereClause(db, playlists);
  104. if (!m_strCurrentFilterMusic.empty())
  105. m_strCurrentFilterMusic = "WHERE " + m_strCurrentFilterMusic;
  106. }
  107. CLog::Log(LOGINFO, "PARTY MODE MANAGER: Registering filter:[%s]", m_strCurrentFilterMusic.c_str());
  108. m_iMatchingSongs = (int)db.GetSongIDs(m_strCurrentFilterMusic, songIDs);
  109. if (m_iMatchingSongs < 1 && m_type.Equals("songs"))
  110. {
  111. pDialog->Close();
  112. db.Close();
  113. OnError(16031, (CStdString)"Party mode found no matching songs. Aborting.");
  114. return false;
  115. }
  116. }
  117. else
  118. {
  119. pDialog->Close();
  120. OnError(16033, (CStdString)"Party mode could not open database. Aborting.");
  121. return false;
  122. }
  123. db.Close();
  124. }
  125. if (m_type.Equals("musicvideos") || m_type.Equals("mixed"))
  126. {
  127. vector< pair<int,int> > songIDs2;
  128. CVideoDatabase db;
  129. if (db.Open())
  130. {
  131. set<CStdString> playlists;
  132. if ( playlistLoaded )
  133. {
  134. m_strCurrentFilterVideo = playlist.GetWhereClause(db, playlists);
  135. if (!m_strCurrentFilterVideo.empty())
  136. m_strCurrentFilterVideo = "WHERE " + m_strCurrentFilterVideo;
  137. }
  138. CLog::Log(LOGINFO, "PARTY MODE MANAGER: Registering filter:[%s]", m_strCurrentFilterVideo.c_str());
  139. m_iMatchingSongs += (int)db.GetMusicVideoIDs(m_strCurrentFilterVideo, songIDs2);
  140. if (m_iMatchingSongs < 1)
  141. {
  142. pDialog->Close();
  143. db.Close();
  144. OnError(16031, (CStdString)"Party mode found no matching songs. Aborting.");
  145. return false;
  146. }
  147. }
  148. else
  149. {
  150. pDialog->Close();
  151. OnError(16033, (CStdString)"Party mode could not open database. Aborting.");
  152. return false;
  153. }
  154. db.Close();
  155. songIDs.insert(songIDs.end(),songIDs2.begin(),songIDs2.end());
  156. }
  157. // calculate history size
  158. if (m_iMatchingSongs < 50)
  159. m_songsInHistory = 0;
  160. else
  161. m_songsInHistory = (int)(m_iMatchingSongs/2);
  162. if (m_songsInHistory > 200)
  163. m_songsInHistory = 200;
  164. CLog::Log(LOGINFO,"PARTY MODE MANAGER: Matching songs = %i, History size = %i", m_iMatchingSongs, m_songsInHistory);
  165. CLog::Log(LOGINFO,"PARTY MODE MANAGER: Party mode enabled!");
  166. int iPlaylist = m_bIsVideo ? PLAYLIST_VIDEO : PLAYLIST_MUSIC;
  167. g_playlistPlayer.ClearPlaylist(iPlaylist);
  168. g_playlistPlayer.SetShuffle(iPlaylist, false);
  169. g_playlistPlayer.SetRepeat(iPlaylist, PLAYLIST::REPEAT_NONE);
  170. pDialog->SetLine(0, (m_bIsVideo ? 20252 : 20124));
  171. pDialog->Progress();
  172. // add initial songs
  173. if (!AddInitialSongs(songIDs))
  174. {
  175. pDialog->Close();
  176. return false;
  177. }
  178. CLog::Log(LOGDEBUG, "%s time for song fetch: %u",
  179. __FUNCTION__, XbmcThreads::SystemClockMillis() - time);
  180. // start playing
  181. g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
  182. Play(0);
  183. pDialog->Close();
  184. // open now playing window
  185. if (m_type.Equals("songs"))
  186. {
  187. if (g_windowManager.GetActiveWindow() != WINDOW_MUSIC_PLAYLIST)
  188. g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST);
  189. }
  190. // done
  191. m_bEnabled = true;
  192. return true;
  193. }
  194. void CPartyModeManager::Disable()
  195. {
  196. if (!IsEnabled())
  197. return;
  198. m_bEnabled = false;
  199. CLog::Log(LOGINFO,"PARTY MODE MANAGER: Party mode disabled.");
  200. }
  201. void CPartyModeManager::OnSongChange(bool bUpdatePlayed /* = false */)
  202. {
  203. if (!IsEnabled())
  204. return;
  205. Process();
  206. if (bUpdatePlayed)
  207. m_iSongsPlayed++;
  208. }
  209. void CPartyModeManager::AddUserSongs(CPlayList& tempList, bool bPlay /* = false */)
  210. {
  211. if (!IsEnabled())
  212. return;
  213. // where do we add?
  214. int iAddAt = -1;
  215. if (m_iLastUserSong < 0 || bPlay)
  216. iAddAt = 1; // under the currently playing song
  217. else
  218. iAddAt = m_iLastUserSong + 1; // under the last user added song
  219. int iNewUserSongs = tempList.size();
  220. CLog::Log(LOGINFO,"PARTY MODE MANAGER: Adding %i user selected songs at %i", iNewUserSongs, iAddAt);
  221. int iPlaylist = PLAYLIST_MUSIC;
  222. if (m_bIsVideo)
  223. iPlaylist = PLAYLIST_VIDEO;
  224. g_playlistPlayer.GetPlaylist(iPlaylist).Insert(tempList, iAddAt);
  225. // update last user added song location
  226. if (m_iLastUserSong < 0)
  227. m_iLastUserSong = 0;
  228. m_iLastUserSong += iNewUserSongs;
  229. if (bPlay)
  230. Play(1);
  231. }
  232. void CPartyModeManager::AddUserSongs(CFileItemList& tempList, bool bPlay /* = false */)
  233. {
  234. if (!IsEnabled())
  235. return;
  236. // where do we add?
  237. int iAddAt = -1;
  238. if (m_iLastUserSong < 0 || bPlay)
  239. iAddAt = 1; // under the currently playing song
  240. else
  241. iAddAt = m_iLastUserSong + 1; // under the last user added song
  242. int iNewUserSongs = tempList.Size();
  243. CLog::Log(LOGINFO,"PARTY MODE MANAGER: Adding %i user selected songs at %i", iNewUserSongs, iAddAt);
  244. int iPlaylist = PLAYLIST_MUSIC;
  245. if (m_bIsVideo)
  246. iPlaylist = PLAYLIST_VIDEO;
  247. g_playlistPlayer.GetPlaylist(iPlaylist).Insert(tempList, iAddAt);
  248. // update last user added song location
  249. if (m_iLastUserSong < 0)
  250. m_iLastUserSong = 0;
  251. m_iLastUserSong += iNewUserSongs;
  252. if (bPlay)
  253. Play(1);
  254. }
  255. void CPartyModeManager::Process()
  256. {
  257. ReapSongs();
  258. MovePlaying();
  259. AddRandomSongs();
  260. UpdateStats();
  261. SendUpdateMessage();
  262. }
  263. bool CPartyModeManager::AddRandomSongs(int iSongs /* = 0 */)
  264. {
  265. int iPlaylist = PLAYLIST_MUSIC;
  266. if (m_bIsVideo)
  267. iPlaylist = PLAYLIST_VIDEO;
  268. CPlayList& playlist = g_playlistPlayer.GetPlaylist(iPlaylist);
  269. int iMissingSongs = QUEUE_DEPTH - playlist.size();
  270. if (iSongs <= 0)
  271. iSongs = iMissingSongs;
  272. // distribute between types if mixed
  273. int iSongsToAdd=iSongs;
  274. int iVidsToAdd=iSongs;
  275. if (m_type.Equals("mixed"))
  276. {
  277. if (iSongs == 1)
  278. {
  279. if (rand() % 10 < 7) // 70 % chance of grabbing a song
  280. iVidsToAdd = 0;
  281. else
  282. iSongsToAdd = 0;
  283. }
  284. if (iSongs > 1) // grab 70 % songs, 30 % mvids
  285. {
  286. iSongsToAdd = (int).7f*iSongs;
  287. iVidsToAdd = (int).3f*iSongs;
  288. while (iSongsToAdd+iVidsToAdd < iSongs) // correct any rounding by adding songs
  289. iSongsToAdd++;
  290. }
  291. }
  292. // add songs to fill queue
  293. if (m_type.Equals("songs") || m_type.Equals("mixed"))
  294. {
  295. CMusicDatabase database;
  296. if (database.Open())
  297. {
  298. // Method:
  299. // 1. Grab a random entry from the database using a where clause
  300. // 2. Iterate on iSongs.
  301. // Note: At present, this method is faster than the alternative, which is to grab
  302. // all valid songids, then select a random number of them (as done in AddInitialSongs()).
  303. // The reason for this is simply the number of songs we are requesting - we generally
  304. // only want one here. Any more than about 3 songs and it is more efficient
  305. // to use the technique in AddInitialSongs. As it's unlikely that we'll require
  306. // more than 1 song at a time here, this method is faster.
  307. bool error(false);
  308. for (int i = 0; i < iSongsToAdd; i++)
  309. {
  310. pair<CStdString,CStdString> whereClause = GetWhereClauseWithHistory();
  311. CFileItemPtr item(new CFileItem);
  312. int songID;
  313. if (database.GetRandomSong(item.get(), songID, whereClause.first))
  314. { // success
  315. Add(item);
  316. AddToHistory(1,songID);
  317. }
  318. else
  319. {
  320. error = true;
  321. break;
  322. }
  323. }
  324. if (error)
  325. {
  326. database.Close();
  327. OnError(16034, (CStdString)"Cannot get songs from database. Aborting.");
  328. return false;
  329. }
  330. }
  331. else
  332. {
  333. OnError(16033, (CStdString)"Party mode could not open database. Aborting.");
  334. return false;
  335. }
  336. database.Close();
  337. }
  338. if (m_type.Equals("musicvideos") || m_type.Equals("mixed"))
  339. {
  340. CVideoDatabase database;
  341. if (database.Open())
  342. {
  343. // Method:
  344. // 1. Grab a random entry from the database using a where clause
  345. // 2. Iterate on iSongs.
  346. // Note: At present, this method is faster than the alternative, which is to grab
  347. // all valid songids, then select a random number of them (as done in AddInitialSongs()).
  348. // The reason for this is simply the number of songs we are requesting - we generally
  349. // only want one here. Any more than about 3 songs and it is more efficient
  350. // to use the technique in AddInitialSongs. As it's unlikely that we'll require
  351. // more than 1 song at a time here, this method is faster.
  352. bool error(false);
  353. for (int i = 0; i < iVidsToAdd; i++)
  354. {
  355. pair<CStdString,CStdString> whereClause = GetWhereClauseWithHistory();
  356. CFileItemPtr item(new CFileItem);
  357. int songID;
  358. if (database.GetRandomMusicVideo(item.get(), songID, whereClause.second))
  359. { // success
  360. Add(item);
  361. AddToHistory(2,songID);
  362. }
  363. else
  364. {
  365. error = true;
  366. break;
  367. }
  368. }
  369. if (error)
  370. {
  371. database.Close();
  372. OnError(16034, (CStdString)"Cannot get songs from database. Aborting.");
  373. return false;
  374. }
  375. }
  376. else
  377. {
  378. OnError(16033, (CStdString)"Party mode could not open database. Aborting.");
  379. return false;
  380. }
  381. database.Close();
  382. }
  383. return true;
  384. }
  385. void CPartyModeManager::Add(CFileItemPtr &pItem)
  386. {
  387. int iPlaylist = m_bIsVideo ? PLAYLIST_VIDEO : PLAYLIST_MUSIC;
  388. if (pItem->HasMusicInfoTag())
  389. {
  390. CMusicDatabase database;
  391. database.Open();
  392. database.SetPropertiesForFileItem(*pItem);
  393. }
  394. CPlayList& playlist = g_playlistPlayer.GetPlaylist(iPlaylist);
  395. playlist.Add(pItem);
  396. CLog::Log(LOGINFO,"PARTY MODE MANAGER: Adding randomly selected song at %i:[%s]", playlist.size() - 1, pItem->GetPath().c_str());
  397. m_iMatchingSongsPicked++;
  398. }
  399. bool CPartyModeManager::ReapSongs()
  400. {
  401. int iPlaylist = m_bIsVideo ? PLAYLIST_VIDEO : PLAYLIST_MUSIC;
  402. // reap any played songs
  403. int iCurrentSong = g_playlistPlayer.GetCurrentSong();
  404. int i=0;
  405. while (i < g_playlistPlayer.GetPlaylist(iPlaylist).size())
  406. {
  407. if (i < iCurrentSong)
  408. {
  409. g_playlistPlayer.GetPlaylist(iPlaylist).Remove(i);
  410. iCurrentSong--;
  411. if (i <= m_iLastUserSong)
  412. m_iLastUserSong--;
  413. }
  414. else
  415. i++;
  416. }
  417. g_playlistPlayer.SetCurrentSong(iCurrentSong);
  418. return true;
  419. }
  420. bool CPartyModeManager::MovePlaying()
  421. {
  422. // move current song to the top if its not there
  423. int iCurrentSong = g_playlistPlayer.GetCurrentSong();
  424. int iPlaylist = m_bIsVideo ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
  425. if (iCurrentSong > 0)
  426. {
  427. CLog::Log(LOGINFO,"PARTY MODE MANAGER: Moving currently playing song from %i to 0", iCurrentSong);
  428. CPlayList &playlist = g_playlistPlayer.GetPlaylist(iPlaylist);
  429. CPlayList playlistTemp;
  430. playlistTemp.Add(playlist[iCurrentSong]);
  431. playlist.Remove(iCurrentSong);
  432. for (int i=0; i<playlist.size(); i++)
  433. playlistTemp.Add(playlist[i]);
  434. playlist.Clear();
  435. for (int i=0; i<playlistTemp.size(); i++)
  436. playlist.Add(playlistTemp[i]);
  437. }
  438. g_playlistPlayer.SetCurrentSong(0);
  439. return true;
  440. }
  441. void CPartyModeManager::SendUpdateMessage()
  442. {
  443. CGUIMessage msg(GUI_MSG_PLAYLIST_CHANGED, 0, 0);
  444. g_windowManager.SendThreadMessage(msg);
  445. }
  446. void CPartyModeManager::Play(int iPos)
  447. {
  448. // move current song to the top if its not there
  449. g_playlistPlayer.Play(iPos);
  450. CLog::Log(LOGINFO,"PARTY MODE MANAGER: Playing song at %i", iPos);
  451. Process();
  452. }
  453. void CPartyModeManager::OnError(int iError, const CStdString& strLogMessage)
  454. {
  455. // open error dialog
  456. CGUIDialogOK::ShowAndGetInput(257, 16030, iError, 0);
  457. CLog::Log(LOGERROR, "PARTY MODE MANAGER: %s", strLogMessage.c_str());
  458. m_bEnabled = false;
  459. SendUpdateMessage();
  460. }
  461. int CPartyModeManager::GetSongsPlayed()
  462. {
  463. if (!IsEnabled())
  464. return -1;
  465. return m_iSongsPlayed;
  466. }
  467. int CPartyModeManager::GetMatchingSongs()
  468. {
  469. if (!IsEnabled())
  470. return -1;
  471. return m_iMatchingSongs;
  472. }
  473. int CPartyModeManager::GetMatchingSongsPicked()
  474. {
  475. if (!IsEnabled())
  476. return -1;
  477. return m_iMatchingSongsPicked;
  478. }
  479. int CPartyModeManager::GetMatchingSongsLeft()
  480. {
  481. if (!IsEnabled())
  482. return -1;
  483. return m_iMatchingSongsLeft;
  484. }
  485. int CPartyModeManager::GetRelaxedSongs()
  486. {
  487. if (!IsEnabled())
  488. return -1;
  489. return m_iRelaxedSongs;
  490. }
  491. int CPartyModeManager::GetRandomSongs()
  492. {
  493. if (!IsEnabled())
  494. return -1;
  495. return m_iRandomSongs;
  496. }
  497. void CPartyModeManager::ClearState()
  498. {
  499. m_iLastUserSong = -1;
  500. m_iSongsPlayed = 0;
  501. m_iMatchingSongs = 0;
  502. m_iMatchingSongsPicked = 0;
  503. m_iMatchingSongsLeft = 0;
  504. m_iRelaxedSongs = 0;
  505. m_iRandomSongs = 0;
  506. m_songsInHistory = 0;
  507. m_history.clear();
  508. }
  509. void CPartyModeManager::UpdateStats()
  510. {
  511. m_iMatchingSongsLeft = m_iMatchingSongs - m_iMatchingSongsPicked;
  512. m_iRandomSongs = m_iMatchingSongsPicked;
  513. m_iRelaxedSongs = 0; // unsupported at this stage
  514. }
  515. bool CPartyModeManager::AddInitialSongs(vector<pair<int,int> > &songIDs)
  516. {
  517. int iPlaylist = m_bIsVideo ? PLAYLIST_VIDEO : PLAYLIST_MUSIC;
  518. CPlayList& playlist = g_playlistPlayer.GetPlaylist(iPlaylist);
  519. int iMissingSongs = QUEUE_DEPTH - playlist.size();
  520. if (iMissingSongs > 0)
  521. {
  522. // generate iMissingSongs random ids from songIDs
  523. if (iMissingSongs > (int)songIDs.size())
  524. return false; // can't do it if we have less songs than we need
  525. vector<pair<int,int> > chosenSongIDs;
  526. GetRandomSelection(songIDs, iMissingSongs, chosenSongIDs);
  527. CStdString sqlWhereMusic = "where songview.idSong in (";
  528. CStdString sqlWhereVideo = "idMVideo in (";
  529. for (vector< pair<int,int> >::iterator it = chosenSongIDs.begin(); it != chosenSongIDs.end(); it++)
  530. {
  531. CStdString song;
  532. song.Format("%i,", it->second);
  533. if (it->first == 1)
  534. sqlWhereMusic += song;
  535. if (it->first == 2)
  536. sqlWhereVideo += song;
  537. }
  538. // add songs to fill queue
  539. CFileItemList items;
  540. if (sqlWhereMusic.size() > 26)
  541. {
  542. sqlWhereMusic[sqlWhereMusic.size() - 1] = ')'; // replace the last comma with closing bracket
  543. CMusicDatabase database;
  544. database.Open();
  545. database.GetSongsByWhere("", sqlWhereMusic, items);
  546. }
  547. if (sqlWhereVideo.size() > 19)
  548. {
  549. sqlWhereVideo[sqlWhereVideo.size() - 1] = ')'; // replace the last comma with closing bracket
  550. CVideoDatabase database;
  551. database.Open();
  552. database.GetMusicVideosByWhere("videodb://3/2/", sqlWhereVideo, items);
  553. }
  554. m_history = chosenSongIDs;
  555. items.Randomize(); //randomizing the initial list or they will be in database order
  556. for (int i = 0; i < items.Size(); i++)
  557. {
  558. CFileItemPtr item(items[i]);
  559. Add(item);
  560. // TODO: Allow "relaxed restrictions" later?
  561. }
  562. }
  563. return true;
  564. }
  565. pair<CStdString,CStdString> CPartyModeManager::GetWhereClauseWithHistory() const
  566. {
  567. CStdString historyWhereMusic;
  568. CStdString historyWhereVideo;
  569. // now add this on to the normal where clause
  570. if (m_history.size())
  571. {
  572. if (m_strCurrentFilterMusic.IsEmpty())
  573. historyWhereMusic = "where songview.idSong not in (";
  574. else
  575. historyWhereMusic = m_strCurrentFilterMusic + " and songview.idSong not in (";
  576. if (m_strCurrentFilterVideo.IsEmpty())
  577. historyWhereVideo = "idMVideo not in (";
  578. else
  579. historyWhereVideo = m_strCurrentFilterVideo + " and idMVideo not in (";
  580. for (unsigned int i = 0; i < m_history.size(); i++)
  581. {
  582. CStdString number;
  583. number.Format("%i,", m_history[i].second);
  584. if (m_history[i].first == 1)
  585. historyWhereMusic += number;
  586. if (m_history[i].first == 2)
  587. historyWhereVideo += number;
  588. }
  589. historyWhereMusic.TrimRight(",");
  590. historyWhereMusic += ")";
  591. historyWhereVideo.TrimRight(",");
  592. historyWhereVideo += ")";
  593. }
  594. return make_pair(historyWhereMusic,historyWhereVideo);
  595. }
  596. void CPartyModeManager::AddToHistory(int type, int songID)
  597. {
  598. while (m_history.size() >= m_songsInHistory && m_songsInHistory)
  599. m_history.erase(m_history.begin());
  600. m_history.push_back(make_pair<int,int>(type,songID));
  601. }
  602. void CPartyModeManager::GetRandomSelection(vector< pair<int,int> >& in, unsigned int number, vector< pair<int,int> >& out)
  603. {
  604. // only works if we have < 32768 in the in vector
  605. for (unsigned int i = 0; i < number; i++)
  606. {
  607. int num = rand() % in.size();
  608. out.push_back(in[num]);
  609. in.erase(in.begin() + num);
  610. }
  611. }
  612. bool CPartyModeManager::IsEnabled(PartyModeContext context /* = PARTYMODECONTEXT_UNKNOWN */) const
  613. {
  614. if (!m_bEnabled) return false;
  615. if (context == PARTYMODECONTEXT_VIDEO)
  616. return m_bIsVideo;
  617. if (context == PARTYMODECONTEXT_MUSIC)
  618. return !m_bIsVideo;
  619. return true; // unknown, but we're enabled
  620. }