added an addon manager directly from our media server, not finalized
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8609 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,339 @@
|
|||||||
|
/*
|
||||||
|
** Copyright 2004, the OpenBeOS project. All rights reserved.
|
||||||
|
** Distributed under the terms of the OpenBeOS License.
|
||||||
|
**
|
||||||
|
** Authors: Marcus Overhagen, Axel Dörfler
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <Autolock.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include <image.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "AddOnManager.h"
|
||||||
|
|
||||||
|
// #pragma mark ImageLoader
|
||||||
|
|
||||||
|
/** The ImageLoader class is a convenience class to temporarily load
|
||||||
|
* an image file, and unload it on deconstruction automatically.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ImageLoader {
|
||||||
|
public:
|
||||||
|
ImageLoader(BPath &path)
|
||||||
|
{
|
||||||
|
fImage = load_add_on(path.Path());
|
||||||
|
}
|
||||||
|
|
||||||
|
~ImageLoader()
|
||||||
|
{
|
||||||
|
if (fImage >= B_OK)
|
||||||
|
unload_add_on(fImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t InitCheck() const { return fImage; }
|
||||||
|
image_id Image() const { return fImage; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
image_id fImage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
AddOnManager::AddOnManager()
|
||||||
|
:
|
||||||
|
fLock("add-on manager")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AddOnManager::~AddOnManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AddOnManager::LoadState()
|
||||||
|
{
|
||||||
|
RegisterAddOns();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AddOnManager::SaveState()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*status_t
|
||||||
|
AddOnManager::GetDecoderForFormat(xfer_entry_ref *_decoderRef,
|
||||||
|
const media_format &format)
|
||||||
|
{
|
||||||
|
if ((format.type == B_MEDIA_ENCODED_VIDEO
|
||||||
|
|| format.type == B_MEDIA_ENCODED_AUDIO
|
||||||
|
|| format.type == B_MEDIA_MULTISTREAM)
|
||||||
|
&& format.Encoding() == 0)
|
||||||
|
return B_MEDIA_BAD_FORMAT;
|
||||||
|
if (format.type == B_MEDIA_NO_TYPE
|
||||||
|
|| format.type == B_MEDIA_UNKNOWN_TYPE)
|
||||||
|
return B_MEDIA_BAD_FORMAT;
|
||||||
|
|
||||||
|
|
||||||
|
BAutolock locker(fLock);
|
||||||
|
|
||||||
|
printf("AddOnManager::GetDecoderForFormat: searching decoder for encoding %ld\n", format.Encoding());
|
||||||
|
|
||||||
|
decoder_info *info;
|
||||||
|
for (fDecoderList.Rewind(); fDecoderList.GetNext(&info);) {
|
||||||
|
media_format *decoderFormat;
|
||||||
|
for (info->formats.Rewind(); info->formats.GetNext(&decoderFormat);) {
|
||||||
|
// check if the decoder matches the supplied format
|
||||||
|
if (!decoderFormat->Matches(&format))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
printf("AddOnManager::GetDecoderForFormat: found decoder %s for encoding %ld\n",
|
||||||
|
info->ref.name, decoderFormat->Encoding());
|
||||||
|
|
||||||
|
*_decoderRef = info->ref;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AddOnManager::GetReaders(xfer_entry_ref *out_res, int32 *out_count, int32 max_count)
|
||||||
|
{
|
||||||
|
BAutolock locker(fLock);
|
||||||
|
|
||||||
|
*out_count = 0;
|
||||||
|
|
||||||
|
fReaderList.Rewind();
|
||||||
|
reader_info *info;
|
||||||
|
for (*out_count = 0; fReaderList.GetNext(&info) && *out_count <= max_count; *out_count += 1)
|
||||||
|
out_res[*out_count] = info->ref;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AddOnManager::RegisterAddOn(BEntry &entry)
|
||||||
|
{
|
||||||
|
BPath path(&entry);
|
||||||
|
|
||||||
|
entry_ref ref;
|
||||||
|
status_t status = entry.GetRef(&ref);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
printf("AddOnManager::RegisterAddOn(): trying to load \"%s\"\n", path.Path());
|
||||||
|
|
||||||
|
ImageLoader loader(path);
|
||||||
|
if ((status = loader.InitCheck()) < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
BEntry parent;
|
||||||
|
entry.GetParent(&parent);
|
||||||
|
BPath parentPath(&parent);
|
||||||
|
BString pathString = parentPath.Path();
|
||||||
|
|
||||||
|
if (pathString.FindFirst("input_server/devices")>0) {
|
||||||
|
BInputServerDevice *(*instantiate_func)();
|
||||||
|
|
||||||
|
if (get_image_symbol(loader.Image(), "instantiate_input_device",
|
||||||
|
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
|
||||||
|
printf("AddOnManager::RegisterAddOn(): can't find instantiate_input_device in \"%s\"\n",
|
||||||
|
path.Path());
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BInputServerDevice *isd = (*instantiate_func)();
|
||||||
|
if (isd == NULL) {
|
||||||
|
printf("AddOnManager::RegisterAddOn(): instantiate_input_device in \"%s\" returned NULL\n",
|
||||||
|
path.Path());
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterDevice(isd, ref);
|
||||||
|
|
||||||
|
} else if (pathString.FindFirst("input_server/filters")>0) {
|
||||||
|
BInputServerFilter *(*instantiate_func)();
|
||||||
|
|
||||||
|
if (get_image_symbol(loader.Image(), "instantiate_input_filter",
|
||||||
|
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
|
||||||
|
printf("AddOnManager::RegisterAddOn(): can't find instantiate_input_filter in \"%s\"\n",
|
||||||
|
path.Path());
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BInputServerFilter *isf = (*instantiate_func)();
|
||||||
|
if (isf == NULL) {
|
||||||
|
printf("AddOnManager::RegisterAddOn(): instantiate_input_filter in \"%s\" returned NULL\n",
|
||||||
|
path.Path());
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterFilter(isf, ref);
|
||||||
|
|
||||||
|
} else if (pathString.FindFirst("input_server/methods")>0) {
|
||||||
|
BInputServerMethod *(*instantiate_func)();
|
||||||
|
|
||||||
|
if (get_image_symbol(loader.Image(), "instantiate_input_method",
|
||||||
|
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
|
||||||
|
printf("AddOnManager::RegisterAddOn(): can't find instantiate_input_method in \"%s\"\n",
|
||||||
|
path.Path());
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BInputServerMethod *ism = (*instantiate_func)();
|
||||||
|
if (ism == NULL) {
|
||||||
|
printf("AddOnManager::RegisterAddOn(): instantiate_input_method in \"%s\" returned NULL\n",
|
||||||
|
path.Path());
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterMethod(ism, ref);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AddOnManager::RegisterAddOns()
|
||||||
|
{
|
||||||
|
class IAHandler : public AddOnMonitorHandler {
|
||||||
|
private:
|
||||||
|
AddOnManager * fManager;
|
||||||
|
public:
|
||||||
|
IAHandler(AddOnManager * manager) {
|
||||||
|
fManager = manager;
|
||||||
|
}
|
||||||
|
virtual void AddOnCreated(const add_on_entry_info * entry_info) {
|
||||||
|
}
|
||||||
|
virtual void AddOnEnabled(const add_on_entry_info * entry_info) {
|
||||||
|
entry_ref ref;
|
||||||
|
make_entry_ref(entry_info->dir_nref.device, entry_info->dir_nref.node,
|
||||||
|
entry_info->name, &ref);
|
||||||
|
BEntry entry(&ref, false);
|
||||||
|
fManager->RegisterAddOn(entry);
|
||||||
|
}
|
||||||
|
virtual void AddOnDisabled(const add_on_entry_info * entry_info) {
|
||||||
|
}
|
||||||
|
virtual void AddOnRemoved(const add_on_entry_info * entry_info) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const directory_which directories[] = {
|
||||||
|
B_USER_ADDONS_DIRECTORY,
|
||||||
|
B_COMMON_ADDONS_DIRECTORY,
|
||||||
|
B_BEOS_ADDONS_DIRECTORY,
|
||||||
|
};
|
||||||
|
const char subDirectories[][24] = {
|
||||||
|
// "input_server/devices",
|
||||||
|
"input_server/filters",
|
||||||
|
"input_server/methods",
|
||||||
|
};
|
||||||
|
fHandler = new IAHandler(this);
|
||||||
|
fAddOnMonitor = new AddOnMonitor(fHandler);
|
||||||
|
|
||||||
|
node_ref nref;
|
||||||
|
BDirectory directory;
|
||||||
|
BPath path;
|
||||||
|
for (uint i = 0 ; i < sizeof(directories) / sizeof(directory_which) ; i++)
|
||||||
|
for (uint j = 0 ; j < 2 ; j++) {
|
||||||
|
if ((find_directory(directories[i], &path) == B_OK)
|
||||||
|
&& (path.Append(subDirectories[j]) == B_OK)
|
||||||
|
&& (directory.SetTo(path.Path()) == B_OK)
|
||||||
|
&& (directory.GetNodeRef(&nref) == B_OK)) {
|
||||||
|
fHandler->AddDirectory(&nref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDo: this is for our own convenience only, and should be removed
|
||||||
|
// in the final release
|
||||||
|
//if ((directory.SetTo("/boot/home/develop/openbeos/current/distro/x86.R1/beos/system/add-ons/media/plugins") == B_OK)
|
||||||
|
// && (directory.GetNodeRef(&nref) == B_OK)) {
|
||||||
|
// fHandler->AddDirectory(&nref);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AddOnManager::RegisterDevice(BInputServerDevice *isd, const entry_ref &ref)
|
||||||
|
{
|
||||||
|
BAutolock locker(fLock);
|
||||||
|
|
||||||
|
device_info *pinfo;
|
||||||
|
for (fDeviceList.Rewind(); fDeviceList.GetNext(&pinfo);) {
|
||||||
|
if (!strcmp(pinfo->ref.name, ref.name)) {
|
||||||
|
// we already know this device
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINT(("AddOnManager::RegisterDevice, name %s\n", ref.name));
|
||||||
|
|
||||||
|
device_info info;
|
||||||
|
info.ref = ref;
|
||||||
|
|
||||||
|
fDeviceList.Insert(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AddOnManager::RegisterFilter(BInputServerFilter *filter, const entry_ref &ref)
|
||||||
|
{
|
||||||
|
BAutolock locker(fLock);
|
||||||
|
|
||||||
|
filter_info *pinfo;
|
||||||
|
for (fFilterList.Rewind(); fFilterList.GetNext(&pinfo);) {
|
||||||
|
if (!strcmp(pinfo->ref.name, ref.name)) {
|
||||||
|
// we already know this ref
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINT(("%s, name %s\n", __PRETTY_FUNCTION__, ref.name));
|
||||||
|
|
||||||
|
filter_info info;
|
||||||
|
info.ref = ref;
|
||||||
|
|
||||||
|
fFilterList.Insert(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AddOnManager::RegisterMethod(BInputServerMethod *method, const entry_ref &ref)
|
||||||
|
{
|
||||||
|
BAutolock locker(fLock);
|
||||||
|
|
||||||
|
method_info *pinfo;
|
||||||
|
for (fMethodList.Rewind(); fMethodList.GetNext(&pinfo);) {
|
||||||
|
if (!strcmp(pinfo->ref.name, ref.name)) {
|
||||||
|
// we already know this ref
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINT(("%s, name %s\n", __PRETTY_FUNCTION__, ref.name));
|
||||||
|
|
||||||
|
method_info info;
|
||||||
|
info.ref = ref;
|
||||||
|
|
||||||
|
fMethodList.Insert(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
** Copyright 2004, the OpenBeOS project. All rights reserved.
|
||||||
|
** Distributed under the terms of the OpenBeOS License.
|
||||||
|
**
|
||||||
|
** Author : Jérôme Duval
|
||||||
|
** Original authors: Marcus Overhagen, Axel Dörfler
|
||||||
|
*/
|
||||||
|
#ifndef _ADD_ON_MANAGER_H
|
||||||
|
#define _ADD_ON_MANAGER_H
|
||||||
|
|
||||||
|
// Manager for input_server add-ons (devices, filters, methods)
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <InputServerDevice.h>
|
||||||
|
#include <InputServerFilter.h>
|
||||||
|
#include <InputServerMethod.h>
|
||||||
|
#include "AddOnMonitor.h"
|
||||||
|
#include "AddOnMonitorHandler.h"
|
||||||
|
#include "TList.h"
|
||||||
|
|
||||||
|
class AddOnManager {
|
||||||
|
public:
|
||||||
|
AddOnManager();
|
||||||
|
~AddOnManager();
|
||||||
|
|
||||||
|
void LoadState();
|
||||||
|
void SaveState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t RegisterAddOn(BEntry &entry);
|
||||||
|
void RegisterAddOns();
|
||||||
|
|
||||||
|
void RegisterDevice(BInputServerDevice *isd, const entry_ref &ref);
|
||||||
|
void RegisterFilter(BInputServerFilter *isf, const entry_ref &ref);
|
||||||
|
void RegisterMethod(BInputServerMethod *ism, const entry_ref &ref);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct device_info {
|
||||||
|
entry_ref ref;
|
||||||
|
};
|
||||||
|
struct filter_info {
|
||||||
|
entry_ref ref;
|
||||||
|
};
|
||||||
|
struct method_info {
|
||||||
|
entry_ref ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
BLocker fLock;
|
||||||
|
List<device_info> fDeviceList;
|
||||||
|
List<filter_info> fFilterList;
|
||||||
|
List<method_info> fMethodList;
|
||||||
|
|
||||||
|
AddOnMonitorHandler *fHandler;
|
||||||
|
AddOnMonitor *fAddOnMonitor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _ADD_ON_MANAGER_H
|
||||||
@@ -33,14 +33,13 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <InputServer.h>
|
|
||||||
#include <Path.h>
|
|
||||||
#include <Directory.h>
|
|
||||||
#include <FindDirectory.h>
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <Locker.h>
|
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Path.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
#if DEBUG>=1
|
#if DEBUG>=1
|
||||||
@@ -51,10 +50,10 @@
|
|||||||
#define CALLED() ((void)0)
|
#define CALLED() ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "InputServer.h"
|
||||||
#include "InputServerDeviceListEntry.h"
|
#include "InputServerDeviceListEntry.h"
|
||||||
#include "InputServerFilterListEntry.h"
|
#include "InputServerFilterListEntry.h"
|
||||||
#include "InputServerMethodListEntry.h"
|
#include "InputServerMethodListEntry.h"
|
||||||
#include <Message.h>
|
|
||||||
#include "InputServerTypes.h"
|
#include "InputServerTypes.h"
|
||||||
|
|
||||||
// include app_server headers for communication
|
// include app_server headers for communication
|
||||||
@@ -109,9 +108,12 @@ InputServer::InputServer(void) : BApplication("application/x-vnd.OBOS-input_serv
|
|||||||
|
|
||||||
InitTestDevice();
|
InitTestDevice();
|
||||||
|
|
||||||
|
fAddOnManager = new AddOnManager();
|
||||||
|
fAddOnManager->LoadState();
|
||||||
|
|
||||||
// InitDevices();
|
// InitDevices();
|
||||||
InitFilters();
|
// InitFilters();
|
||||||
InitMethods();
|
// InitMethods();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -121,6 +123,8 @@ InputServer::InputServer(void) : BApplication("application/x-vnd.OBOS-input_serv
|
|||||||
InputServer::~InputServer(void)
|
InputServer::~InputServer(void)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
fAddOnManager->SaveState();
|
||||||
|
delete fAddOnManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include "InputServerDevice.h"
|
#include "InputServerDevice.h"
|
||||||
#include "InputServerFilter.h"
|
#include "InputServerFilter.h"
|
||||||
#include "InputServerMethod.h"
|
#include "InputServerMethod.h"
|
||||||
|
#include "AddOnManager.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -177,6 +178,7 @@ private:
|
|||||||
// added this to communicate via portlink
|
// added this to communicate via portlink
|
||||||
|
|
||||||
BPortLink *serverlink;
|
BPortLink *serverlink;
|
||||||
|
AddOnManager *fAddOnManager;
|
||||||
|
|
||||||
//fMouseState;
|
//fMouseState;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ Server input_server :
|
|||||||
InputServerFilter.cpp
|
InputServerFilter.cpp
|
||||||
InputServerMethod.cpp
|
InputServerMethod.cpp
|
||||||
|
|
||||||
|
AddOnManager.cpp
|
||||||
|
|
||||||
# storage
|
# storage
|
||||||
AddOnMonitor.cpp
|
AddOnMonitor.cpp
|
||||||
AddOnMonitorHandler.cpp
|
AddOnMonitorHandler.cpp
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
#ifndef _MEDIA_T_LIST_H
|
||||||
|
#define _MEDIA_T_LIST_H
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
|
||||||
|
template<class value> class List
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
List()
|
||||||
|
: item_max(INIT_COUNT),
|
||||||
|
item_count(0),
|
||||||
|
item_iter(-1),
|
||||||
|
items((value **)malloc(sizeof(value *) * INIT_COUNT))
|
||||||
|
{
|
||||||
|
ASSERT(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
~List()
|
||||||
|
{
|
||||||
|
MakeEmpty();
|
||||||
|
free(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
List(const List<value> &other)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<value> &operator=(const List<value> &other)
|
||||||
|
{
|
||||||
|
MakeEmpty();
|
||||||
|
free(items);
|
||||||
|
item_max = other.item_max;
|
||||||
|
item_count = other.item_count;
|
||||||
|
items = (value **)malloc(sizeof(value *) * item_max);
|
||||||
|
ASSERT(items);
|
||||||
|
for (int i = 0; i < item_count; i++) {
|
||||||
|
items[i] = new value;
|
||||||
|
*items[i] = *other.items[i];
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Insert(const value &v)
|
||||||
|
{
|
||||||
|
if (item_count == item_max) {
|
||||||
|
item_max *= 2;
|
||||||
|
items = (value **)realloc(items, sizeof(value *) * item_max);
|
||||||
|
ASSERT(items);
|
||||||
|
}
|
||||||
|
items[item_count] = new value;
|
||||||
|
*items[item_count] = v;
|
||||||
|
item_count++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Get(int32 index, value **v)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= item_count)
|
||||||
|
return false;
|
||||||
|
*v = items[index];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Remove(int32 index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= item_count)
|
||||||
|
return false;
|
||||||
|
delete items[index];
|
||||||
|
item_count--;
|
||||||
|
items[index] = items[item_count];
|
||||||
|
if (index == item_iter)
|
||||||
|
item_iter--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Find(const value &v)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < item_count; i++)
|
||||||
|
if (*items[i] == v)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CountItems()
|
||||||
|
{
|
||||||
|
return item_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEmpty()
|
||||||
|
{
|
||||||
|
return item_count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeEmpty()
|
||||||
|
{
|
||||||
|
if (items != 0) {
|
||||||
|
for (int i = 0; i < item_count; i++) {
|
||||||
|
delete items[i];
|
||||||
|
}
|
||||||
|
item_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rewind()
|
||||||
|
{
|
||||||
|
item_iter = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetNext(value **v)
|
||||||
|
{
|
||||||
|
item_iter++;
|
||||||
|
return Get(item_iter, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RemoveCurrent()
|
||||||
|
{
|
||||||
|
return Remove(item_iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum { INIT_COUNT=32 };
|
||||||
|
int item_max;
|
||||||
|
int item_count;
|
||||||
|
int item_iter;
|
||||||
|
value **items;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _MEDIA_T_LIST_H
|
||||||
Reference in New Issue
Block a user