Pertama-tama, tidak jelas dari deskripsi Anda tentang apa yang telah Anda lakukan, tetapi Anda membutuhkan PlaylistSongs
tabel yang berisi a PlaylistId
dan a SongId
, yang menggambarkan lagu mana yang termasuk daftar putar mana.
Dalam tabel ini Anda harus menambahkan informasi pemesanan.
Mekanisme favorit saya adalah dengan bilangan real. Saya menerapkannya baru-baru ini, dan itu berfungsi seperti pesona. Saat Anda ingin memindahkan lagu ke posisi tertentu, Anda menghitung Ordering
nilai baru sebagai rata-rata Ordering
nilai lagu sebelumnya dan lagu berikutnya. Jika Anda menggunakan bilangan real 64-bit, Anda akan kehabisan presisi pada waktu yang sama ketika neraka akan membeku, tetapi jika Anda benar-benar menulis perangkat lunak Anda untuk anak cucu, maka pertimbangkan untuk menetapkan ulang bilangan bulat bulat yang bagusOrdering
nilai untuk semua lagu di masing-masing daftar putar sesekali.
Sebagai bonus tambahan, berikut adalah kode yang saya tulis yang mengimplementasikan ini. Tentu saja Anda tidak dapat menggunakannya sebagaimana adanya, dan itu akan terlalu sulit bagi saya sekarang untuk membersihkannya untuk Anda, jadi saya hanya mempostingnya agar Anda mendapatkan ide darinya.
Kelasnya adalah ParameterTemplate
(apa pun, jangan tanya!) Metode ini mendapatkan daftar templat parameter yang dimiliki templat ini dari induknya ActivityTemplate
. (Terserah, jangan tanya!) Kode berisi beberapa penjaga terhadap kehabisan presisi. Pembagi digunakan untuk pengujian: unit test menggunakan pembagi besar sehingga kehabisan presisi dengan cepat, dan dengan demikian memicu kode pelindung presisi. Metode kedua adalah publik dan "hanya untuk penggunaan internal; jangan meminta" sehingga kode pengujian dapat memohonnya. (Itu tidak bisa paket-pribadi karena kode pengujian saya tidak dalam paket yang sama dengan kode yang diuji.) Bidang yang mengontrol pemesanan disebut Ordering
, diakses melalui getOrdering()
dan setOrdering()
. Anda tidak melihat SQL apa pun karena saya menggunakan Object-Relational Mapping via Hibernate.
/**
* Moves this {@link ParameterTemplate} to the given index in the list of {@link ParameterTemplate}s of the parent {@link ActivityTemplate}.
*
* The index must be greater than or equal to zero, and less than or equal to the number of entries in the list. Specifying an index of zero will move this item to the top of
* the list. Specifying an index which is equal to the number of entries will move this item to the end of the list. Any other index will move this item to the position
* specified, also moving other items in the list as necessary. The given index cannot be equal to the current index of the item, nor can it be equal to the current index plus
* one. If the given index is below the current index of the item, then the item will be moved so that its new index will be equal to the given index. If the given index is
* above the current index, then the new index of the item will be the given index minus one.
*
* NOTE: this method flushes the persistor and refreshes the parent node so as to guarantee that the changes will be immediately visible in the list of {@link
* ParameterTemplate}s of the parent {@link ActivityTemplate}.
*
* @param toIndex the desired new index of this {@link ParameterTemplate} in the list of {@link ParameterTemplate}s of the parent {@link ActivityTemplate}.
*/
public void moveAt( int toIndex )
{
moveAt( toIndex, 2.0 );
}
/**
* For internal use only; do not invoke.
*/
public boolean moveAt( int toIndex, double divisor )
{
MutableList<ParameterTemplate<?>> parameterTemplates = getLogicDomain().getMutableCollections().newArrayList();
parameterTemplates.addAll( getParentActivityTemplate().getParameterTemplates() );
assert parameterTemplates.getLength() >= 1; //guaranteed since at the very least, this parameter template must be in the list.
int fromIndex = parameterTemplates.indexOf( this );
assert 0 <= toIndex;
assert toIndex <= parameterTemplates.getLength();
assert 0 <= fromIndex;
assert fromIndex < parameterTemplates.getLength();
assert fromIndex != toIndex;
assert fromIndex != toIndex - 1;
double order;
if( toIndex == 0 )
{
order = parameterTemplates.fetchFirstElement().getOrdering() - 1.0;
}
else if( toIndex == parameterTemplates.getLength() )
{
order = parameterTemplates.fetchLastElement().getOrdering() + 1.0;
}
else
{
double prevOrder = parameterTemplates.get( toIndex - 1 ).getOrdering();
parameterTemplates.moveAt( fromIndex, toIndex );
double nextOrder = parameterTemplates.get( toIndex + (toIndex > fromIndex ? 0 : 1) ).getOrdering();
assert prevOrder <= nextOrder;
order = (prevOrder + nextOrder) / divisor;
if( order <= prevOrder || order >= nextOrder ) //if the accuracy of the double has been exceeded
{
parameterTemplates.clear();
parameterTemplates.addAll( getParentActivityTemplate().getParameterTemplates() );
for( int i = 0; i < parameterTemplates.getLength(); i++ )
parameterTemplates.get( i ).setOrdering( i * 1.0 );
rocs3dDomain.getPersistor().flush();
rocs3dDomain.getPersistor().refresh( getParentActivityTemplate() );
moveAt( toIndex );
return true;
}
}
setOrdering( order );
rocs3dDomain.getPersistor().flush();
rocs3dDomain.getPersistor().refresh( getParentActivityTemplate() );
assert getParentActivityTemplate().getParameterTemplates().indexOf( this ) == (toIndex > fromIndex ? toIndex - 1 : toIndex);
return false;
}