forgot commit
This commit is contained in:
parent
6f2aae0c37
commit
378beb4b63
|
|
@ -0,0 +1,149 @@
|
|||
// Filename: simpleAllocator.I
|
||||
// Created by: drose (12May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocator::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE SimpleAllocator::
|
||||
SimpleAllocator(size_t max_size) :
|
||||
LinkedListNode(true),
|
||||
_total_size(0),
|
||||
_max_size(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocator::get_total_size
|
||||
// Access: Published
|
||||
// Description: Returns the total size of allocated objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t SimpleAllocator::
|
||||
get_total_size() const {
|
||||
return _total_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocator::get_max_size
|
||||
// Access: Published
|
||||
// Description: Returns the available space for allocated objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t SimpleAllocator::
|
||||
get_max_size() const {
|
||||
return _max_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocator::set_max_size
|
||||
// Access: Published
|
||||
// Description: Changes the available space for allocated objects.
|
||||
// This will not affect any already-allocated objects,
|
||||
// but will have an effect on future calls to alloc().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleAllocator::
|
||||
set_max_size(size_t max_size) {
|
||||
_max_size = max_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocatorBlock::Constructor
|
||||
// Access: Private
|
||||
// Description: A SimpleAllocatorBlock must be constructed via the
|
||||
// SimpleAllocator::alloc() call.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE SimpleAllocatorBlock::
|
||||
SimpleAllocatorBlock(SimpleAllocator *alloc,
|
||||
size_t start, size_t size) :
|
||||
_allocator(alloc),
|
||||
_start(start),
|
||||
_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocatorBlock::Destructor
|
||||
// Access: Published
|
||||
// Description: The block automatically frees itself when it
|
||||
// destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE SimpleAllocatorBlock::
|
||||
~SimpleAllocatorBlock() {
|
||||
free();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocatorBlock::free
|
||||
// Access: Published
|
||||
// Description: Releases the allocated space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleAllocatorBlock::
|
||||
free() {
|
||||
if (_allocator != (SimpleAllocator *)NULL) {
|
||||
_allocator->_total_size -= _size;
|
||||
remove_from_list();
|
||||
_allocator = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocatorBlock::get_allocator
|
||||
// Access: Published
|
||||
// Description: Returns the SimpleAllocator object that owns this
|
||||
// block. Returns NULL if the block has been freed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE SimpleAllocator *SimpleAllocatorBlock::
|
||||
get_allocator() const {
|
||||
return _allocator;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocatorBlock::get_start
|
||||
// Access: Published
|
||||
// Description: Returns the starting point of this block. It is an
|
||||
// error to call this if the block has been freed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t SimpleAllocatorBlock::
|
||||
get_start() const {
|
||||
nassertr(_allocator != (SimpleAllocator *)NULL, 0);
|
||||
return _start;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocatorBlock::get_size
|
||||
// Access: Published
|
||||
// Description: Returns the size of this block. It is an
|
||||
// error to call this if the block has been freed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t SimpleAllocatorBlock::
|
||||
get_size() const {
|
||||
nassertr(_allocator != (SimpleAllocator *)NULL, 0);
|
||||
return _size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocatorBlock::is_free
|
||||
// Access: Published
|
||||
// Description: Returns true if the block has been freed, false if it
|
||||
// is still valid.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool SimpleAllocatorBlock::
|
||||
is_free() const {
|
||||
return (_allocator != (SimpleAllocator *)NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
// Filename: simpleAllocator.cxx
|
||||
// Created by: drose (12May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "simpleAllocator.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocator::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
SimpleAllocator::
|
||||
~SimpleAllocator() {
|
||||
// We're shutting down. Force-free everything remaining.
|
||||
while (_next != (LinkedListNode *)this) {
|
||||
nassertv(_next != (LinkedListNode *)NULL);
|
||||
((SimpleAllocatorBlock *)_next)->free();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocator::alloc
|
||||
// Access: Published
|
||||
// Description: Allocates a new block. Returns NULL if a block of the
|
||||
// requested size cannot be allocated.
|
||||
//
|
||||
// To free the allocated block, call block->free(), or
|
||||
// simply delete the block pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
SimpleAllocatorBlock *SimpleAllocator::
|
||||
alloc(size_t size) {
|
||||
// First fit algorithm: walk through all the empty blocks until we
|
||||
// find one that has enough room.
|
||||
|
||||
SimpleAllocatorBlock *block = NULL;
|
||||
size_t end = 0;
|
||||
|
||||
if (_next != this) {
|
||||
// We have at least one allocated block.
|
||||
block = (SimpleAllocatorBlock *)_next;
|
||||
end = block->_start + block->_size;
|
||||
|
||||
// Scan until we have reached the last allocated block.
|
||||
while (block->_next != this) {
|
||||
SimpleAllocatorBlock *next = (SimpleAllocatorBlock *)block->_next;
|
||||
size_t free_size = next->_start - end;
|
||||
if (size <= free_size) {
|
||||
SimpleAllocatorBlock *new_block = new SimpleAllocatorBlock(this, end, size);
|
||||
new_block->insert_before(next);
|
||||
_total_size += size;
|
||||
return new_block;
|
||||
}
|
||||
|
||||
block = next;
|
||||
end = block->_start + block->_size;
|
||||
}
|
||||
}
|
||||
|
||||
// No free blocks; check for room at the end.
|
||||
size_t free_size = _max_size - end;
|
||||
if (size <= free_size) {
|
||||
SimpleAllocatorBlock *new_block = new SimpleAllocatorBlock(this, end, size);
|
||||
new_block->insert_before(this);
|
||||
_total_size += size;
|
||||
return new_block;
|
||||
}
|
||||
|
||||
// No room for this block.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocator::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SimpleAllocator::
|
||||
output(ostream &out) const {
|
||||
out << "SimpleAllocator, " << _total_size << " of " << _max_size
|
||||
<< " allocated";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocator::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SimpleAllocator::
|
||||
write(ostream &out) const {
|
||||
out << *this << ":\n";
|
||||
|
||||
SimpleAllocatorBlock *block = (SimpleAllocatorBlock *)_next;
|
||||
while (block->_next != this) {
|
||||
SimpleAllocatorBlock *next = (SimpleAllocatorBlock *)block->_next;
|
||||
|
||||
out << " " << *block << "\n";
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleAllocatorBlock::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SimpleAllocatorBlock::
|
||||
output(ostream &out) const {
|
||||
if (_allocator == (SimpleAllocator *)NULL) {
|
||||
out << "free block\n";
|
||||
} else {
|
||||
out << "block of size " << _size << " at " << _start;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
// Filename: simpleAllocator.h
|
||||
// Created by: drose (12May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SIMPLEALLOCATOR_H
|
||||
#define SIMPLEALLOCATOR_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "linkedListNode.h"
|
||||
|
||||
class SimpleAllocatorBlock;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : SimpleAllocator
|
||||
// Description : An implementation of a very simple block allocator.
|
||||
// This class can allocate ranges of nonnegative
|
||||
// integers within a specified upper limit; it uses a
|
||||
// simple first-fit algorithm to find the next available
|
||||
// space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA SimpleAllocator : public LinkedListNode {
|
||||
PUBLISHED:
|
||||
INLINE SimpleAllocator(size_t max_size);
|
||||
~SimpleAllocator();
|
||||
|
||||
SimpleAllocatorBlock *alloc(size_t size);
|
||||
|
||||
INLINE size_t get_total_size() const;
|
||||
INLINE size_t get_max_size() const;
|
||||
INLINE void set_max_size(size_t max_size);
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out) const;
|
||||
|
||||
private:
|
||||
// This is implemented as a linked-list chain of allocated blocks.
|
||||
// Free blocks are implicit. Blocks are kept in sorted order from
|
||||
// beginning to end. Allocating a block means creating a new entry
|
||||
// in the chain wherever it may fit; freeing a block means simply
|
||||
// removing the allocated block from the chain. With this simple
|
||||
// approach, there is no need to merge adjacent free blocks to
|
||||
// straighten out fragmentation, since free blocks are not stored.
|
||||
// However, it does mean we have to walk through a list of adjacent
|
||||
// allocated blocks in order to find the free blocks.
|
||||
size_t _total_size;
|
||||
size_t _max_size;
|
||||
|
||||
friend class SimpleAllocatorBlock;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : SimpleAllocatorBlock
|
||||
// Description : A single block as returned from
|
||||
// SimpleAllocator::alloc().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA SimpleAllocatorBlock : public LinkedListNode {
|
||||
private:
|
||||
INLINE SimpleAllocatorBlock(SimpleAllocator *alloc,
|
||||
size_t start, size_t size);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE ~SimpleAllocatorBlock();
|
||||
INLINE void free();
|
||||
|
||||
INLINE SimpleAllocator *get_allocator() const;
|
||||
|
||||
INLINE size_t get_start() const;
|
||||
INLINE size_t get_size() const;
|
||||
INLINE bool is_free() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
SimpleAllocator *_allocator;
|
||||
size_t _start;
|
||||
size_t _size;
|
||||
|
||||
friend class SimpleAllocator;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const SimpleAllocator &obj) {
|
||||
obj.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const SimpleAllocatorBlock &obj) {
|
||||
obj.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "simpleAllocator.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// Filename: vertexDataSaveFile.I
|
||||
// Created by: drose (12May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
// Filename: vertexDataSaveFile.cxx
|
||||
// Created by: drose (12May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "vertexDataSaveFile.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexDataSaveFile::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
VertexDataSaveFile::
|
||||
VertexDataSaveFile(const Filename &directory, const string &prefix,
|
||||
size_t max_size) :
|
||||
_allocator(max_size)
|
||||
{
|
||||
// Try to open and lock a writable temporary filename.
|
||||
int index = 0;
|
||||
while (true) {
|
||||
++index;
|
||||
ostringstream strm;
|
||||
strm << prefix << "_" << index << ".dat";
|
||||
string basename = strm.str();
|
||||
_filename = Filename(directory, basename);
|
||||
string os_specific = _filename.to_os_specific();
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows case.
|
||||
_handle = CreateFile(os_specific.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL);
|
||||
if (_handle == INVALID_HANDLE_VALUE) {
|
||||
// Couldn't open the file. Either the directory was bad, or the
|
||||
// file was locked.
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_SHARING_VIOLATION) {
|
||||
// Try the next file.
|
||||
break;
|
||||
}
|
||||
|
||||
// File couldn't be opened; permission problem or bogus directory.
|
||||
// TODO: handle this
|
||||
}
|
||||
|
||||
#else
|
||||
// Posix case.
|
||||
_fd = open(os_specific.c_str(), O_RDWR | O_CREAT, 0666);
|
||||
nassertv(_fd != -1); // TODO: handle this.
|
||||
|
||||
// Now try to lock the file, so we can be sure that no other
|
||||
// process is simultaneously writing to the same save file.
|
||||
int result = lockf(_fd, F_TLOCK, 0);
|
||||
if (result == 0) {
|
||||
// We've got the file. Truncate it first, for good measure, in
|
||||
// case there's an old version of the file we picked up.
|
||||
ftruncate(_fd, 0);
|
||||
|
||||
// On Unix, it's safe to unlink (delete) the temporary file after
|
||||
// it's been opened. The file remains open, but disappears from
|
||||
// the directory. This ensures it won't accidentally get left
|
||||
// behind should this process crash without closing and deleting
|
||||
// the file cleanly.
|
||||
//unlink(os_specific.c_str());
|
||||
//_filename = Filename();
|
||||
break;
|
||||
}
|
||||
|
||||
// Try the next file.
|
||||
close(_fd);
|
||||
#endif // _WIN32
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexDataSaveFile::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
VertexDataSaveFile::
|
||||
~VertexDataSaveFile() {
|
||||
#ifdef _WIN32
|
||||
if (_handle != NULL) {
|
||||
CloseHandle(_handle);
|
||||
}
|
||||
#else
|
||||
if (_fd != -1) {
|
||||
close(_fd);
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
if (!_filename.empty()) {
|
||||
_filename.unlink();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexDataSaveFile::write_data
|
||||
// Access: Public
|
||||
// Description: Writes a block of data to the file, and returns a
|
||||
// handle to the block handle. Returns NULL if the data
|
||||
// cannot be written (e.g. no remaining space on the
|
||||
// file).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
SimpleAllocatorBlock *VertexDataSaveFile::
|
||||
write_data(const unsigned char *data, size_t size) {
|
||||
SimpleAllocatorBlock *block = _allocator.alloc(size);
|
||||
if (block != (SimpleAllocatorBlock *)NULL) {
|
||||
|
||||
#ifdef _WIN32
|
||||
if (SetFilePointer(_handle, block->get_start(), NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
|
||||
gobj_cat.error()
|
||||
<< "Error seeking to position " << block->get_start() << " in save file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD bytes_written;
|
||||
if (!WriteFile(_handle, data, size, &bytes_written, NULL) ||
|
||||
bytes_written != size) {
|
||||
gobj_cat.error()
|
||||
<< "Error writing " << size << " bytes to save file. Disk full?\n";
|
||||
delete block;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
// Posix case.
|
||||
if (lseek(_fd, block->get_start(), SEEK_SET) == -1) {
|
||||
gobj_cat.error()
|
||||
<< "Error seeking to position " << block->get_start() << " in save file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t result = write(_fd, data, size);
|
||||
if (result != (ssize_t)size) {
|
||||
gobj_cat.error()
|
||||
<< "Error writing " << size << " bytes to save file. Disk full?\n";
|
||||
delete block;
|
||||
return NULL;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexDataSaveFile::read_data
|
||||
// Access: Public
|
||||
// Description: Reads a block of data from the file, and returns true
|
||||
// on success, false on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool VertexDataSaveFile::
|
||||
read_data(unsigned char *data, size_t size, SimpleAllocatorBlock *block) {
|
||||
nassertr(size == block->get_size(), false);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (SetFilePointer(_handle, block->get_start(), NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
|
||||
gobj_cat.error()
|
||||
<< "Error seeking to position " << block->get_start() << " in save file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD bytes_read;
|
||||
if (!ReadFile(_handle, data, size, &bytes_read, NULL) ||
|
||||
bytes_read != size) {
|
||||
gobj_cat.error()
|
||||
<< "Error writing " << size << " bytes to save file. Disk full?\n";
|
||||
delete block;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
// Posix case.
|
||||
if (lseek(_fd, block->get_start(), SEEK_SET) == -1) {
|
||||
gobj_cat.error()
|
||||
<< "Error seeking to position " << block->get_start() << " in save file.\n";
|
||||
return false;
|
||||
}
|
||||
ssize_t result = read(_fd, data, size);
|
||||
if (result != (ssize_t)size) {
|
||||
gobj_cat.error()
|
||||
<< "Error reading " << size << " bytes from save file.\n";
|
||||
return false;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// Filename: vertexDataSaveFile.h
|
||||
// Created by: drose (12May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef VERTEXDATASAVEFILE_H
|
||||
#define VERTEXDATASAVEFILE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "simpleAllocator.h"
|
||||
#include "filename.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : VertexDataSaveFile
|
||||
// Description : A temporary file to hold the vertex data that has
|
||||
// been evicted from memory and written to disk. All
|
||||
// vertex data arrays are written into one large flat
|
||||
// file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA VertexDataSaveFile {
|
||||
public:
|
||||
VertexDataSaveFile(const Filename &directory, const string &prefix,
|
||||
size_t max_size);
|
||||
~VertexDataSaveFile();
|
||||
|
||||
SimpleAllocatorBlock *write_data(const unsigned char *data, size_t size);
|
||||
bool read_data(unsigned char *data, size_t size,
|
||||
SimpleAllocatorBlock *block);
|
||||
|
||||
private:
|
||||
SimpleAllocator _allocator;
|
||||
Filename _filename;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE _handle;
|
||||
#else
|
||||
int _fd; // Posix file descriptor
|
||||
#endif // _WIN32
|
||||
};
|
||||
|
||||
#include "vertexDataSaveFile.I"
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue