mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-23 02:11:38 +00:00
501e4bb91a
svn-id: r38961
114 lines
3.9 KiB
C++
114 lines
3.9 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
/* Heap-like managed structure */
|
|
|
|
#ifndef SCI_ENGINE_HEAPMGR_H
|
|
#define SCI_ENGINE_HEAPMGR_H
|
|
|
|
#include "sci/tools.h"
|
|
#include "sci/sci_memory.h"
|
|
|
|
namespace Sci {
|
|
|
|
#define HEAPENTRY_INVALID -1
|
|
|
|
// FIXME: We write (i == 0 || i > 0) instead of (i >= 0) to silence certain annoying warnings:
|
|
// generated by GCC: "comparison is always true due to limited range of data type".
|
|
#define ENTRY_IS_VALID(t, i) ((i == 0 || i > 0) && (i) < (t)->max_entry && (t)->table[(i)].next_free == (i))
|
|
|
|
#define DECLARE_HEAPENTRY(ENTRY) \
|
|
struct ENTRY##Entry { \
|
|
int next_free; /* Only used for free entries */ \
|
|
ENTRY entry; \
|
|
}; \
|
|
\
|
|
struct ENTRY##Table { \
|
|
int entries_nr; /* Number of entries allocated */ \
|
|
int first_free; /* Beginning of a singly linked list for entries */ \
|
|
int entries_used; /* Statistical information */ \
|
|
int max_entry; /* Highest entry used */ \
|
|
ENTRY##Entry *table; \
|
|
}; \
|
|
\
|
|
void init_##ENTRY##_table(ENTRY##Table *table); \
|
|
int alloc_##ENTRY##_entry(ENTRY##Table *table); \
|
|
void free_##ENTRY##_entry(ENTRY##Table *table, int index);
|
|
|
|
|
|
|
|
#define DEFINE_HEAPENTRY_WITH_CLEANUP(ENTRY, INITIAL, INCREMENT, CLEANUP_FN) \
|
|
void init_##ENTRY##_table(ENTRY##Table *table) { \
|
|
table->entries_nr = INITIAL; \
|
|
table->max_entry = 0; \
|
|
table->entries_used = 0; \
|
|
table->first_free = HEAPENTRY_INVALID; \
|
|
table->table = (ENTRY##Entry *)sci_malloc(sizeof(ENTRY##Entry) * INITIAL);\
|
|
memset(table->table, 0, sizeof(ENTRY##Entry) * INITIAL); \
|
|
} \
|
|
\
|
|
void free_##ENTRY##_entry(ENTRY##Table *table, int index) { \
|
|
ENTRY##Entry *e = table->table + index; \
|
|
\
|
|
if (index < 0 || index >= table->max_entry) { \
|
|
fprintf(stderr, "heapmgr: Attempt to release" \
|
|
" invalid table index %d!\n", index); \
|
|
BREAKPOINT(); \
|
|
} \
|
|
CLEANUP_FN(&(e->entry)); \
|
|
\
|
|
e->next_free = table->first_free; \
|
|
table->first_free = index; \
|
|
table->entries_used--; \
|
|
} \
|
|
\
|
|
int alloc_##ENTRY##_entry(ENTRY##Table *table) { \
|
|
table->entries_used++; \
|
|
if (table->first_free != HEAPENTRY_INVALID) { \
|
|
int oldff = table->first_free; \
|
|
table->first_free = table->table[oldff].next_free; \
|
|
\
|
|
table->table[oldff].next_free = oldff; \
|
|
return oldff; \
|
|
} else { \
|
|
if (table->max_entry == table->entries_nr) { \
|
|
table->entries_nr += INCREMENT; \
|
|
\
|
|
table->table = (ENTRY##Entry *)sci_realloc(table->table,\
|
|
sizeof(ENTRY##Entry) * table->entries_nr);\
|
|
memset(&table->table[table->entries_nr-INCREMENT], 0, INCREMENT * sizeof(ENTRY##Entry));\
|
|
} \
|
|
table->table[table->max_entry].next_free = table->max_entry; /* Tag as 'valid' */\
|
|
return table->max_entry++; \
|
|
} \
|
|
}
|
|
|
|
#define _HEAPENTRY_IGNORE_ME(x)
|
|
#define DEFINE_HEAPENTRY(e, i, p) DEFINE_HEAPENTRY_WITH_CLEANUP(e, i, p, _HEAPENTRY_IGNORE_ME)
|
|
|
|
} // End of namespace Sci
|
|
|
|
#endif // SCI_ENGINE_HEAPMGR_H
|