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 <waddlesplash@gmail.com>
This commit is contained in:
parent
b966e83785
commit
1cfb79d74a
@ -22,16 +22,16 @@ using std::nothrow;
|
||||
|
||||
|
||||
CopyPLItemsCommand::CopyPLItemsCommand(Playlist* playlist,
|
||||
const int32* indices, int32 count, int32 toIndex)
|
||||
BList indices, int32 toIndex)
|
||||
:
|
||||
PLItemsCommand(),
|
||||
fPlaylist(playlist),
|
||||
fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
|
||||
fCount(indices.CountItems()),
|
||||
fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
|
||||
fToIndex(toIndex),
|
||||
fCount(count),
|
||||
fItemsCopied(false)
|
||||
{
|
||||
if (!indices || !fPlaylist || !fItems) {
|
||||
if (indices.IsEmpty() || !fPlaylist || !fItems) {
|
||||
// indicate a bad object state
|
||||
delete[] fItems;
|
||||
fItems = NULL;
|
||||
@ -42,7 +42,8 @@ CopyPLItemsCommand::CopyPLItemsCommand(Playlist* playlist,
|
||||
|
||||
// init original entries and
|
||||
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)
|
||||
fItems[i] = item->Clone();
|
||||
if (fItems[i] == NULL) {
|
||||
|
@ -6,14 +6,16 @@
|
||||
#define COPY_PL_ITEMS_COMMAND_H
|
||||
|
||||
|
||||
#include <List.h>
|
||||
|
||||
#include "PLItemsCommand.h"
|
||||
|
||||
|
||||
class CopyPLItemsCommand : public PLItemsCommand {
|
||||
public:
|
||||
CopyPLItemsCommand(
|
||||
Playlist* playlist,
|
||||
const int32* indices,
|
||||
int32 count,
|
||||
BList indices,
|
||||
int32 toIndex);
|
||||
virtual ~CopyPLItemsCommand();
|
||||
|
||||
@ -26,9 +28,9 @@ public:
|
||||
|
||||
private:
|
||||
Playlist* fPlaylist;
|
||||
int32 fCount;
|
||||
PlaylistItem** fItems;
|
||||
int32 fToIndex;
|
||||
int32 fCount;
|
||||
bool fItemsCopied;
|
||||
};
|
||||
|
||||
|
@ -23,30 +23,30 @@ using std::nothrow;
|
||||
|
||||
|
||||
MovePLItemsCommand::MovePLItemsCommand(Playlist* playlist,
|
||||
const int32* indices, int32 count, int32 toIndex)
|
||||
BList indices, int32 toIndex)
|
||||
:
|
||||
PLItemsCommand(),
|
||||
fPlaylist(playlist),
|
||||
fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
|
||||
fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
|
||||
fToIndex(toIndex),
|
||||
fCount(count)
|
||||
fCount(indices.CountItems()),
|
||||
fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
|
||||
fIndices(fCount > 0 ? new (nothrow) int32[fCount] : NULL),
|
||||
fToIndex(toIndex)
|
||||
{
|
||||
if (!indices || !fPlaylist || !fItems || !fIndices) {
|
||||
if (indices.IsEmpty()) {
|
||||
// indicate a bad object state
|
||||
delete[] fItems;
|
||||
delete fItems;
|
||||
fItems = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
memset(fItems, 0, sizeof(PlaylistItem*) * fCount);
|
||||
memcpy(fIndices, indices, fCount * sizeof(int32));
|
||||
|
||||
// init original entry indices and
|
||||
// adjust toIndex compensating for items that
|
||||
// are removed before that index
|
||||
int32 itemsBeforeIndex = 0;
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
fIndices[i] = (int32)(addr_t)indices.ItemAt(i);
|
||||
fItems[i] = fPlaylist->ItemAt(fIndices[i]);
|
||||
if (fItems[i] == NULL) {
|
||||
// indicate a bad object state
|
||||
|
@ -6,14 +6,16 @@
|
||||
#define MOVE_PL_ITEMS_COMMAND_H
|
||||
|
||||
|
||||
#include <List.h>
|
||||
|
||||
#include "PLItemsCommand.h"
|
||||
|
||||
|
||||
class MovePLItemsCommand : public PLItemsCommand {
|
||||
public:
|
||||
MovePLItemsCommand(
|
||||
Playlist* playlist,
|
||||
const int32* indices,
|
||||
int32 count,
|
||||
BList indices,
|
||||
int32 toIndex);
|
||||
virtual ~MovePLItemsCommand();
|
||||
|
||||
@ -26,10 +28,10 @@ class MovePLItemsCommand : public PLItemsCommand {
|
||||
|
||||
private:
|
||||
Playlist* fPlaylist;
|
||||
int32 fCount;
|
||||
PlaylistItem** fItems;
|
||||
int32* fIndices;
|
||||
int32 fToIndex;
|
||||
int32 fCount;
|
||||
};
|
||||
|
||||
#endif // MOVE_PL_ITEMS_COMMAND_H
|
||||
|
@ -483,7 +483,7 @@ void
|
||||
PlaylistListView::MoveItems(const BList& indices, int32 toIndex)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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,
|
||||
(int32*)indices.Items(), indices.CountItems()));
|
||||
indices));
|
||||
}
|
||||
|
||||
|
||||
@ -589,7 +589,7 @@ void
|
||||
PlaylistListView::RemoveItemList(const BList& indices, bool intoTrash)
|
||||
{
|
||||
fCommandStack->Perform(new (nothrow) RemovePLItemsCommand(fPlaylist,
|
||||
(int32*)indices.Items(), indices.CountItems(), intoTrash));
|
||||
indices, intoTrash));
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,12 +28,12 @@ RandomizePLItemsCommand::RandomizePLItemsCommand(Playlist* playlist,
|
||||
:
|
||||
PLItemsCommand(),
|
||||
fPlaylist(playlist),
|
||||
fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
|
||||
fListIndices(count > 0 ? new (nothrow) int32[count] : NULL),
|
||||
fRandomInternalIndices(count > 0 ? new (nothrow) int32[count] : NULL),
|
||||
fCount(count)
|
||||
fCount(indices.CountItems()),
|
||||
fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
|
||||
fListIndices(fCount > 0 ? new (nothrow) int32[fCount] : NULL),
|
||||
fRandomInternalIndices(fCount > 0 ? new (nothrow) int32[fCount] : NULL)
|
||||
{
|
||||
if (!indices || !fPlaylist || !fItems || !fListIndices
|
||||
if (indices.IsEmpty() || !fPlaylist || !fItems || !fListIndices
|
||||
|| !fRandomInternalIndices) {
|
||||
// indicate a bad object state
|
||||
delete[] fItems;
|
||||
@ -41,12 +41,12 @@ RandomizePLItemsCommand::RandomizePLItemsCommand(Playlist* playlist,
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(fListIndices, indices, fCount * sizeof(int32));
|
||||
memset(fItems, 0, fCount * sizeof(PlaylistItem*));
|
||||
|
||||
// put the available indices into a "set"
|
||||
BList indexSet;
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
fIndices[i] = (int32)(addr_t)indices.ItemAt(i);
|
||||
fItems[i] = fPlaylist->ItemAt(fListIndices[i]);
|
||||
if (fItems[i] == NULL || !indexSet.AddItem((void*)(addr_t)i)) {
|
||||
// indicate a bad object state
|
||||
|
@ -6,14 +6,16 @@
|
||||
#define RANDOMIZE_PL_ITEMS_COMMAND_H
|
||||
|
||||
|
||||
#include <List.h>
|
||||
|
||||
#include "PLItemsCommand.h"
|
||||
|
||||
|
||||
class RandomizePLItemsCommand : public PLItemsCommand {
|
||||
public:
|
||||
RandomizePLItemsCommand(
|
||||
Playlist* playlist,
|
||||
const int32* indices,
|
||||
int32 count);
|
||||
BList indices);
|
||||
virtual ~RandomizePLItemsCommand();
|
||||
|
||||
virtual status_t InitCheck();
|
||||
@ -27,10 +29,10 @@ private:
|
||||
status_t _Sort(bool random);
|
||||
|
||||
Playlist* fPlaylist;
|
||||
int32 fCount;
|
||||
PlaylistItem** fItems;
|
||||
int32* fListIndices;
|
||||
int32* fRandomInternalIndices;
|
||||
int32 fCount;
|
||||
};
|
||||
|
||||
#endif // RANDOMIZE_PL_ITEMS_COMMAND_H
|
||||
|
@ -24,29 +24,29 @@ using std::nothrow;
|
||||
|
||||
|
||||
RemovePLItemsCommand::RemovePLItemsCommand(Playlist* playlist,
|
||||
const int32* indices, int32 count, bool moveFilesToTrash)
|
||||
BList indices, bool moveFilesToTrash)
|
||||
:
|
||||
PLItemsCommand(),
|
||||
fPlaylist(playlist),
|
||||
fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
|
||||
fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
|
||||
fCount(count),
|
||||
fCount(indices.CountItems()),
|
||||
fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
|
||||
fIndices(fCount > 0 ? new (nothrow) int32[fCount] : NULL),
|
||||
fMoveFilesToTrash(moveFilesToTrash),
|
||||
fMoveErrorShown(false),
|
||||
fItemsRemoved(false)
|
||||
{
|
||||
if (!indices || !fPlaylist || !fItems || !fIndices) {
|
||||
if (indices.IsEmpty()) {
|
||||
// indicate a bad object state
|
||||
delete[] fItems;
|
||||
fItems = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(fIndices, indices, fCount * sizeof(int32));
|
||||
memset(fItems, 0, fCount * sizeof(PlaylistItem*));
|
||||
|
||||
// init original entry indices
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
fIndices[i] = (int32)(addr_t)indices.ItemAt(i);
|
||||
fItems[i] = fPlaylist->ItemAt(fIndices[i]);
|
||||
if (fItems[i] == NULL) {
|
||||
delete[] fItems;
|
||||
|
@ -6,14 +6,16 @@
|
||||
#define REMOVE_PL_ITEMS_COMMAND_H
|
||||
|
||||
|
||||
#include <List.h>
|
||||
|
||||
#include "PLItemsCommand.h"
|
||||
|
||||
|
||||
class RemovePLItemsCommand : public PLItemsCommand {
|
||||
public:
|
||||
RemovePLItemsCommand(
|
||||
Playlist* playlist,
|
||||
const int32* indices,
|
||||
int32 count,
|
||||
BList indices,
|
||||
bool moveFilesToTrash = false);
|
||||
virtual ~RemovePLItemsCommand();
|
||||
|
||||
@ -26,9 +28,9 @@ public:
|
||||
|
||||
private:
|
||||
Playlist* fPlaylist;
|
||||
int32 fCount;
|
||||
PlaylistItem** fItems;
|
||||
int32* fIndices;
|
||||
int32 fCount;
|
||||
bool fMoveFilesToTrash;
|
||||
bool fMoveErrorShown;
|
||||
bool fItemsRemoved;
|
||||
|
Loading…
x
Reference in New Issue
Block a user