rocket/ogl_editor/src/TrackData.c
2013-01-04 14:41:41 +01:00

288 lines
7.7 KiB
C

#include "TrackData.h"
#include "Commands.h"
#include "rlog.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TrackData_createGetTrack(TrackData* trackData, const char* name)
{
int index = sync_find_track(&trackData->syncData, name);
if (index < 0)
{
index = sync_create_track(&trackData->syncData, name);
memset(&trackData->tracks[index], 0, sizeof(Track));
trackData->tracks[index].index = index;
trackData->tracks[index].color = TrackData_getNextColor(trackData);
}
if (trackData->syncData.tracks)
Commands_init(trackData->syncData.tracks, trackData);
return index;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static uint32_t s_colors[] =
{
0xffb27474,
0xffb28050,
0xffa9b250,
0xff60b250,
0xff4fb292,
0xff4f71b2,
0xff8850b2,
0xffb25091,
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint32_t TrackData_getNextColor(TrackData* trackData)
{
return s_colors[(trackData->lastColor++) & 0x7];
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int findSeparator(const char* name)
{
int i, len = strlen(name);
for (i = 0; i < len; ++i)
{
if (name[i] == ':')
return i;
}
return -1;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static Group* findOrCreateGroup(const char* name, TrackData* trackData)
{
Group* group;
int i, group_count = trackData->groupCount;
Group* groups = trackData->groups;
for (i = 0; i < group_count; ++i)
{
group = &groups[i];
if (!group->name)
continue;
if (!strcmp(name, group->name))
return &groups[i];
}
group = &groups[trackData->groupCount++];
memset(group, 0, sizeof(Group));
group->type = GROUP_TYPE_GROUP;
group->name = strdup(name);
group->displayName = strdup(name);
group->displayName[strlen(name)-1] = 0;
group->trackCount = 0;
return group;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TrackData_linkTrack(int index, const char* name, TrackData* trackData)
{
int found;
char group_name[256];
Group* group;
Group* groups = trackData->groups;
Track* track = &trackData->tracks[index];
if (track->group)
return;
found = findSeparator(name);
if (found == -1)
{
Group* group = &groups[trackData->groupCount++];
memset(group, 0, sizeof(Group));
group->type = GROUP_TYPE_TRACK;
group->t.track = track;
group->trackCount = 1;
track->group = group;
track->displayName = strdup(name);
return;
}
memset(group_name, 0, sizeof(group_name));
memcpy(group_name, name, found + 1);
group = findOrCreateGroup(group_name, trackData);
if (group->trackCount == 0)
group->t.tracks = (Track**)malloc(sizeof(Track**));
else
group->t.tracks = (Track**)realloc(group->t.tracks, sizeof(Track**) * (group->trackCount + 1));
group->t.tracks[group->trackCount] = track;
group->trackCount++;
track->group = group;
track->displayName = strdup(&name[found + 1]);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TrackData_linkGroups(TrackData* trackData)
{
int i, track_count;
struct sync_data* sync = &trackData->syncData;
for (i = 0, track_count = sync->num_tracks; i < track_count; ++i)
TrackData_linkTrack(i, sync->tracks[i]->name, trackData);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TrackData_setActiveTrack(TrackData* trackData, int track)
{
const int current_track = trackData->activeTrack;
trackData->tracks[current_track].selected = false;
trackData->tracks[track].selected = true;
trackData->activeTrack = track;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool TrackData_hasBookmark(TrackData* trackData, int row)
{
int middle, first, last;
int* bookmarks = trackData->bookmarks;
if (!bookmarks)
return false;
first = 0;
last = trackData->bookmarkCount - 1;
middle = (first + last) / 2;
while (first <= last)
{
if (bookmarks[middle] < row)
first = middle + 1;
else if (bookmarks[middle] == row)
return true;
else
last = middle - 1;
middle = (first + last) / 2;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int compare(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
static void sortArray(int* bookmarks, int count)
{
qsort(bookmarks, count, sizeof(int), compare);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TrackData_toggleBookmark(TrackData* trackData, int row)
{
int i, count = trackData->bookmarkCount;
int* bookmarks = trackData->bookmarks;
if (!bookmarks)
{
bookmarks = trackData->bookmarks = malloc(sizeof(int));
*bookmarks = row;
trackData->bookmarkCount++;
return;
}
for (i = 0; i < count; ++i)
{
if (bookmarks[i] == row)
{
bookmarks[i] = 0;
sortArray(bookmarks, count);
return;
}
}
// look for empty slot
for (i = 0; i < count; ++i)
{
if (bookmarks[i] == 0)
{
bookmarks[i] = row;
sortArray(bookmarks, count);
return;
}
}
// no slot found so we will resize the array and add the bookmark at the end
bookmarks = trackData->bookmarks = realloc(bookmarks, sizeof(int) * (count + 1));
bookmarks[count] = row;
sortArray(bookmarks, count + 1);
trackData->bookmarkCount = count + 1;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TrackData_getNextBookmark(TrackData* trackData, int row)
{
int i, count = trackData->bookmarkCount;
int* bookmarks = trackData->bookmarks;
if (!bookmarks)
return trackData->endRow;
for (i = 0; i < count; ++i)
{
const int v = bookmarks[i];
if (v > row)
return v;
}
return trackData->endRow;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TrackData_getPrevBookmark(TrackData* trackData, int row)
{
int i, count = trackData->bookmarkCount - 1;
int* bookmarks = trackData->bookmarks;
if (!bookmarks)
return trackData->startRow;
for (i = count; i >= 0; --i)
{
const int v = bookmarks[i];
if (v < row)
return v;
}
return trackData->startRow;
}