MediaPlayer: Fix playlist manipulation on x86_64
Fixes a problem on x86_64 with removing, shuffling, and moving multiple playlist items. Instead of casting directly between an array of addr_t and int32 values, an int32 array is filled manually. Commands are passed BLists instead of int32 arrays. Fixes #15737 #16698 Change-Id: I5f67cd511ba10b16bd52d87cda380dd15ce7ee67 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3553 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
@@ -22,16 +22,16 @@ using std::nothrow;
|
|||||||
|
|
||||||
|
|
||||||
CopyPLItemsCommand::CopyPLItemsCommand(Playlist* playlist,
|
CopyPLItemsCommand::CopyPLItemsCommand(Playlist* playlist,
|
||||||
const int32* indices, int32 count, int32 toIndex)
|
BList indices, int32 toIndex)
|
||||||
:
|
:
|
||||||
PLItemsCommand(),
|
PLItemsCommand(),
|
||||||
fPlaylist(playlist),
|
fPlaylist(playlist),
|
||||||
fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
|
fCount(indices.CountItems()),
|
||||||
|
fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
|
||||||
fToIndex(toIndex),
|
fToIndex(toIndex),
|
||||||
fCount(count),
|
|
||||||
fItemsCopied(false)
|
fItemsCopied(false)
|
||||||
{
|
{
|
||||||
if (!indices || !fPlaylist || !fItems) {
|
if (indices.IsEmpty() || !fPlaylist || !fItems) {
|
||||||
// indicate a bad object state
|
// indicate a bad object state
|
||||||
delete[] fItems;
|
delete[] fItems;
|
||||||
fItems = NULL;
|
fItems = NULL;
|
||||||
@@ -42,7 +42,8 @@ CopyPLItemsCommand::CopyPLItemsCommand(Playlist* playlist,
|
|||||||
|
|
||||||
// init original entries and
|
// init original entries and
|
||||||
for (int32 i = 0; i < fCount; i++) {
|
for (int32 i = 0; i < fCount; i++) {
|
||||||
PlaylistItem* item = fPlaylist->ItemAt(indices[i]);
|
PlaylistItem* item =
|
||||||
|
fPlaylist->ItemAt((int32)(addr_t)indices.ItemAt(i));
|
||||||
if (item != NULL)
|
if (item != NULL)
|
||||||
fItems[i] = item->Clone();
|
fItems[i] = item->Clone();
|
||||||
if (fItems[i] == NULL) {
|
if (fItems[i] == NULL) {
|
||||||
|
|||||||
@@ -6,14 +6,16 @@
|
|||||||
#define COPY_PL_ITEMS_COMMAND_H
|
#define COPY_PL_ITEMS_COMMAND_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
#include "PLItemsCommand.h"
|
#include "PLItemsCommand.h"
|
||||||
|
|
||||||
|
|
||||||
class CopyPLItemsCommand : public PLItemsCommand {
|
class CopyPLItemsCommand : public PLItemsCommand {
|
||||||
public:
|
public:
|
||||||
CopyPLItemsCommand(
|
CopyPLItemsCommand(
|
||||||
Playlist* playlist,
|
Playlist* playlist,
|
||||||
const int32* indices,
|
BList indices,
|
||||||
int32 count,
|
|
||||||
int32 toIndex);
|
int32 toIndex);
|
||||||
virtual ~CopyPLItemsCommand();
|
virtual ~CopyPLItemsCommand();
|
||||||
|
|
||||||
@@ -26,9 +28,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Playlist* fPlaylist;
|
Playlist* fPlaylist;
|
||||||
|
int32 fCount;
|
||||||
PlaylistItem** fItems;
|
PlaylistItem** fItems;
|
||||||
int32 fToIndex;
|
int32 fToIndex;
|
||||||
int32 fCount;
|
|
||||||
bool fItemsCopied;
|
bool fItemsCopied;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,30 +23,30 @@ using std::nothrow;
|
|||||||
|
|
||||||
|
|
||||||
MovePLItemsCommand::MovePLItemsCommand(Playlist* playlist,
|
MovePLItemsCommand::MovePLItemsCommand(Playlist* playlist,
|
||||||
const int32* indices, int32 count, int32 toIndex)
|
BList indices, int32 toIndex)
|
||||||
:
|
:
|
||||||
PLItemsCommand(),
|
PLItemsCommand(),
|
||||||
fPlaylist(playlist),
|
fPlaylist(playlist),
|
||||||
fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
|
fCount(indices.CountItems()),
|
||||||
fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
|
fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
|
||||||
fToIndex(toIndex),
|
fIndices(fCount > 0 ? new (nothrow) int32[fCount] : NULL),
|
||||||
fCount(count)
|
fToIndex(toIndex)
|
||||||
{
|
{
|
||||||
if (!indices || !fPlaylist || !fItems || !fIndices) {
|
if (indices.IsEmpty()) {
|
||||||
// indicate a bad object state
|
// indicate a bad object state
|
||||||
delete[] fItems;
|
delete fItems;
|
||||||
fItems = NULL;
|
fItems = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(fItems, 0, sizeof(PlaylistItem*) * fCount);
|
memset(fItems, 0, sizeof(PlaylistItem*) * fCount);
|
||||||
memcpy(fIndices, indices, fCount * sizeof(int32));
|
|
||||||
|
|
||||||
// init original entry indices and
|
// init original entry indices and
|
||||||
// adjust toIndex compensating for items that
|
// adjust toIndex compensating for items that
|
||||||
// are removed before that index
|
// are removed before that index
|
||||||
int32 itemsBeforeIndex = 0;
|
int32 itemsBeforeIndex = 0;
|
||||||
for (int32 i = 0; i < fCount; i++) {
|
for (int32 i = 0; i < fCount; i++) {
|
||||||
|
fIndices[i] = (int32)(addr_t)indices.ItemAt(i);
|
||||||
fItems[i] = fPlaylist->ItemAt(fIndices[i]);
|
fItems[i] = fPlaylist->ItemAt(fIndices[i]);
|
||||||
if (fItems[i] == NULL) {
|
if (fItems[i] == NULL) {
|
||||||
// indicate a bad object state
|
// indicate a bad object state
|
||||||
|
|||||||
@@ -6,14 +6,16 @@
|
|||||||
#define MOVE_PL_ITEMS_COMMAND_H
|
#define MOVE_PL_ITEMS_COMMAND_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
#include "PLItemsCommand.h"
|
#include "PLItemsCommand.h"
|
||||||
|
|
||||||
|
|
||||||
class MovePLItemsCommand : public PLItemsCommand {
|
class MovePLItemsCommand : public PLItemsCommand {
|
||||||
public:
|
public:
|
||||||
MovePLItemsCommand(
|
MovePLItemsCommand(
|
||||||
Playlist* playlist,
|
Playlist* playlist,
|
||||||
const int32* indices,
|
BList indices,
|
||||||
int32 count,
|
|
||||||
int32 toIndex);
|
int32 toIndex);
|
||||||
virtual ~MovePLItemsCommand();
|
virtual ~MovePLItemsCommand();
|
||||||
|
|
||||||
@@ -26,10 +28,10 @@ class MovePLItemsCommand : public PLItemsCommand {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Playlist* fPlaylist;
|
Playlist* fPlaylist;
|
||||||
|
int32 fCount;
|
||||||
PlaylistItem** fItems;
|
PlaylistItem** fItems;
|
||||||
int32* fIndices;
|
int32* fIndices;
|
||||||
int32 fToIndex;
|
int32 fToIndex;
|
||||||
int32 fCount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MOVE_PL_ITEMS_COMMAND_H
|
#endif // MOVE_PL_ITEMS_COMMAND_H
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ void
|
|||||||
PlaylistListView::MoveItems(const BList& indices, int32 toIndex)
|
PlaylistListView::MoveItems(const BList& indices, int32 toIndex)
|
||||||
{
|
{
|
||||||
fCommandStack->Perform(new (nothrow) MovePLItemsCommand(fPlaylist,
|
fCommandStack->Perform(new (nothrow) MovePLItemsCommand(fPlaylist,
|
||||||
(int32*)indices.Items(), indices.CountItems(), toIndex));
|
indices, toIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ void
|
|||||||
PlaylistListView::CopyItems(const BList& indices, int32 toIndex)
|
PlaylistListView::CopyItems(const BList& indices, int32 toIndex)
|
||||||
{
|
{
|
||||||
fCommandStack->Perform(new (nothrow) CopyPLItemsCommand(fPlaylist,
|
fCommandStack->Perform(new (nothrow) CopyPLItemsCommand(fPlaylist,
|
||||||
(int32*)indices.Items(), indices.CountItems(), toIndex));
|
indices, toIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -563,7 +563,7 @@ PlaylistListView::Randomize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
fCommandStack->Perform(new (nothrow) RandomizePLItemsCommand(fPlaylist,
|
fCommandStack->Perform(new (nothrow) RandomizePLItemsCommand(fPlaylist,
|
||||||
(int32*)indices.Items(), indices.CountItems()));
|
indices));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -589,7 +589,7 @@ void
|
|||||||
PlaylistListView::RemoveItemList(const BList& indices, bool intoTrash)
|
PlaylistListView::RemoveItemList(const BList& indices, bool intoTrash)
|
||||||
{
|
{
|
||||||
fCommandStack->Perform(new (nothrow) RemovePLItemsCommand(fPlaylist,
|
fCommandStack->Perform(new (nothrow) RemovePLItemsCommand(fPlaylist,
|
||||||
(int32*)indices.Items(), indices.CountItems(), intoTrash));
|
indices, intoTrash));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ RandomizePLItemsCommand::RandomizePLItemsCommand(Playlist* playlist,
|
|||||||
:
|
:
|
||||||
PLItemsCommand(),
|
PLItemsCommand(),
|
||||||
fPlaylist(playlist),
|
fPlaylist(playlist),
|
||||||
fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
|
fCount(indices.CountItems()),
|
||||||
fListIndices(count > 0 ? new (nothrow) int32[count] : NULL),
|
fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
|
||||||
fRandomInternalIndices(count > 0 ? new (nothrow) int32[count] : NULL),
|
fListIndices(fCount > 0 ? new (nothrow) int32[fCount] : NULL),
|
||||||
fCount(count)
|
fRandomInternalIndices(fCount > 0 ? new (nothrow) int32[fCount] : NULL)
|
||||||
{
|
{
|
||||||
if (!indices || !fPlaylist || !fItems || !fListIndices
|
if (indices.IsEmpty() || !fPlaylist || !fItems || !fListIndices
|
||||||
|| !fRandomInternalIndices) {
|
|| !fRandomInternalIndices) {
|
||||||
// indicate a bad object state
|
// indicate a bad object state
|
||||||
delete[] fItems;
|
delete[] fItems;
|
||||||
@@ -41,12 +41,12 @@ RandomizePLItemsCommand::RandomizePLItemsCommand(Playlist* playlist,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(fListIndices, indices, fCount * sizeof(int32));
|
|
||||||
memset(fItems, 0, fCount * sizeof(PlaylistItem*));
|
memset(fItems, 0, fCount * sizeof(PlaylistItem*));
|
||||||
|
|
||||||
// put the available indices into a "set"
|
// put the available indices into a "set"
|
||||||
BList indexSet;
|
BList indexSet;
|
||||||
for (int32 i = 0; i < fCount; i++) {
|
for (int32 i = 0; i < fCount; i++) {
|
||||||
|
fIndices[i] = (int32)(addr_t)indices.ItemAt(i);
|
||||||
fItems[i] = fPlaylist->ItemAt(fListIndices[i]);
|
fItems[i] = fPlaylist->ItemAt(fListIndices[i]);
|
||||||
if (fItems[i] == NULL || !indexSet.AddItem((void*)(addr_t)i)) {
|
if (fItems[i] == NULL || !indexSet.AddItem((void*)(addr_t)i)) {
|
||||||
// indicate a bad object state
|
// indicate a bad object state
|
||||||
|
|||||||
@@ -6,14 +6,16 @@
|
|||||||
#define RANDOMIZE_PL_ITEMS_COMMAND_H
|
#define RANDOMIZE_PL_ITEMS_COMMAND_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
#include "PLItemsCommand.h"
|
#include "PLItemsCommand.h"
|
||||||
|
|
||||||
|
|
||||||
class RandomizePLItemsCommand : public PLItemsCommand {
|
class RandomizePLItemsCommand : public PLItemsCommand {
|
||||||
public:
|
public:
|
||||||
RandomizePLItemsCommand(
|
RandomizePLItemsCommand(
|
||||||
Playlist* playlist,
|
Playlist* playlist,
|
||||||
const int32* indices,
|
BList indices);
|
||||||
int32 count);
|
|
||||||
virtual ~RandomizePLItemsCommand();
|
virtual ~RandomizePLItemsCommand();
|
||||||
|
|
||||||
virtual status_t InitCheck();
|
virtual status_t InitCheck();
|
||||||
@@ -27,10 +29,10 @@ private:
|
|||||||
status_t _Sort(bool random);
|
status_t _Sort(bool random);
|
||||||
|
|
||||||
Playlist* fPlaylist;
|
Playlist* fPlaylist;
|
||||||
|
int32 fCount;
|
||||||
PlaylistItem** fItems;
|
PlaylistItem** fItems;
|
||||||
int32* fListIndices;
|
int32* fListIndices;
|
||||||
int32* fRandomInternalIndices;
|
int32* fRandomInternalIndices;
|
||||||
int32 fCount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RANDOMIZE_PL_ITEMS_COMMAND_H
|
#endif // RANDOMIZE_PL_ITEMS_COMMAND_H
|
||||||
|
|||||||
@@ -24,29 +24,29 @@ using std::nothrow;
|
|||||||
|
|
||||||
|
|
||||||
RemovePLItemsCommand::RemovePLItemsCommand(Playlist* playlist,
|
RemovePLItemsCommand::RemovePLItemsCommand(Playlist* playlist,
|
||||||
const int32* indices, int32 count, bool moveFilesToTrash)
|
BList indices, bool moveFilesToTrash)
|
||||||
:
|
:
|
||||||
PLItemsCommand(),
|
PLItemsCommand(),
|
||||||
fPlaylist(playlist),
|
fPlaylist(playlist),
|
||||||
fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
|
fCount(indices.CountItems()),
|
||||||
fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
|
fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
|
||||||
fCount(count),
|
fIndices(fCount > 0 ? new (nothrow) int32[fCount] : NULL),
|
||||||
fMoveFilesToTrash(moveFilesToTrash),
|
fMoveFilesToTrash(moveFilesToTrash),
|
||||||
fMoveErrorShown(false),
|
fMoveErrorShown(false),
|
||||||
fItemsRemoved(false)
|
fItemsRemoved(false)
|
||||||
{
|
{
|
||||||
if (!indices || !fPlaylist || !fItems || !fIndices) {
|
if (indices.IsEmpty()) {
|
||||||
// indicate a bad object state
|
// indicate a bad object state
|
||||||
delete[] fItems;
|
delete[] fItems;
|
||||||
fItems = NULL;
|
fItems = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(fIndices, indices, fCount * sizeof(int32));
|
|
||||||
memset(fItems, 0, fCount * sizeof(PlaylistItem*));
|
memset(fItems, 0, fCount * sizeof(PlaylistItem*));
|
||||||
|
|
||||||
// init original entry indices
|
// init original entry indices
|
||||||
for (int32 i = 0; i < fCount; i++) {
|
for (int32 i = 0; i < fCount; i++) {
|
||||||
|
fIndices[i] = (int32)(addr_t)indices.ItemAt(i);
|
||||||
fItems[i] = fPlaylist->ItemAt(fIndices[i]);
|
fItems[i] = fPlaylist->ItemAt(fIndices[i]);
|
||||||
if (fItems[i] == NULL) {
|
if (fItems[i] == NULL) {
|
||||||
delete[] fItems;
|
delete[] fItems;
|
||||||
|
|||||||
@@ -6,14 +6,16 @@
|
|||||||
#define REMOVE_PL_ITEMS_COMMAND_H
|
#define REMOVE_PL_ITEMS_COMMAND_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
#include "PLItemsCommand.h"
|
#include "PLItemsCommand.h"
|
||||||
|
|
||||||
|
|
||||||
class RemovePLItemsCommand : public PLItemsCommand {
|
class RemovePLItemsCommand : public PLItemsCommand {
|
||||||
public:
|
public:
|
||||||
RemovePLItemsCommand(
|
RemovePLItemsCommand(
|
||||||
Playlist* playlist,
|
Playlist* playlist,
|
||||||
const int32* indices,
|
BList indices,
|
||||||
int32 count,
|
|
||||||
bool moveFilesToTrash = false);
|
bool moveFilesToTrash = false);
|
||||||
virtual ~RemovePLItemsCommand();
|
virtual ~RemovePLItemsCommand();
|
||||||
|
|
||||||
@@ -26,9 +28,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Playlist* fPlaylist;
|
Playlist* fPlaylist;
|
||||||
|
int32 fCount;
|
||||||
PlaylistItem** fItems;
|
PlaylistItem** fItems;
|
||||||
int32* fIndices;
|
int32* fIndices;
|
||||||
int32 fCount;
|
|
||||||
bool fMoveFilesToTrash;
|
bool fMoveFilesToTrash;
|
||||||
bool fMoveErrorShown;
|
bool fMoveErrorShown;
|
||||||
bool fItemsRemoved;
|
bool fItemsRemoved;
|
||||||
|
|||||||
Reference in New Issue
Block a user