Files @ r24860:fb2788d47d86
Branch filter:

Location: cpp/openttd-patchpack/source/src/3rdparty/squirrel/squirrel/squtils.h

Michael Lutz
Codechange: [OSX] Only keep a total dirty rect for drawing.

When drawing an 8bpp screen buffer, palette resolving was done for each
dirty rectangle. In areas with high activity, this would mean a pixel might
have been resolved multiple times. Also, if too many individual updates
were queued, the whole screen would be refreshed, even if unnecessary.

All other drivers only keep one overall dirty rect, so do it here as well.
/*	see copyright notice in squirrel.h */
#ifndef _SQUTILS_H_
#define _SQUTILS_H_

void *sq_vm_malloc(SQUnsignedInteger size);
void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
void sq_vm_free(void *p,SQUnsignedInteger size);

#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
#define SQ_MALLOC(__size) sq_vm_malloc((__size));
#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size));
#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size));

//sqvector mini vector class, supports objects by value
template<typename T> class sqvector
{
public:
	sqvector()
	{
		_vals = NULL;
		_size = 0;
		_allocated = 0;
	}
	sqvector(const sqvector<T>& v)
	{
		copy(v);
	}
	void copy(const sqvector<T>& v)
	{
		resize(v._size);
		for(SQUnsignedInteger i = 0; i < v._size; i++) {
			new ((void *)&_vals[i]) T(v._vals[i]);
		}
		_size = v._size;
	}
	~sqvector()
	{
		if(_allocated) {
		        /* Break freeing loops, if this vector (indirectly) links to itself. */
		        size_t allocated_size = _allocated * sizeof(T);
		        _allocated = 0;

			for(size_t i = 0; i < _size; i++)
				_vals[i].~T();
			SQ_FREE(_vals, allocated_size);
		}
	}
	void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
	void resize(SQUnsignedInteger newsize, const T& fill = T())
	{
		if(newsize > _allocated)
			_realloc(newsize);
		if(newsize > _size) {
			while(_size < newsize) {
				new ((void *)&_vals[_size]) T(fill);
				_size++;
			}
		}
		else{
			for(SQUnsignedInteger i = newsize; i < _size; i++) {
				_vals[i].~T();
			}
			_size = (size_t)newsize;
		}
	}
	void shrinktofit() { if(_size > 4) { _realloc(_size); } }
	T& top() const { return _vals[_size - 1]; }
	inline SQUnsignedInteger size() const { return _size; }
	bool empty() const { return (_size <= 0); }
	inline T &push_back(const T& val = T())
	{
		if(_allocated <= _size)
			_realloc(_size * 2);
		return *(new ((void *)&_vals[_size++]) T(val));
	}
	inline void pop_back()
	{
		_size--; _vals[_size].~T();
	}
	void insert(SQUnsignedInteger idx, const T& val)
	{
		resize(_size + 1);
		for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
			_vals[i] = _vals[i - 1];
		}
    	_vals[idx] = val;
	}
	void remove(SQUnsignedInteger idx)
	{
		_vals[idx].~T();
		if(idx < (_size - 1)) {
			memmove(static_cast<void *>(&_vals[idx]), &_vals[idx+1], sizeof(T) * (_size - (size_t)idx - 1));
		}
		_size--;
	}
	SQUnsignedInteger capacity() { return _allocated; }
	inline T &back() const { return _vals[_size - 1]; }
	inline T& operator[](SQUnsignedInteger pos) const{ assert(pos < _allocated); return _vals[pos]; }
	T* _vals;
private:
	void _realloc(SQUnsignedInteger newsize)
	{
		newsize = (newsize > 0)?newsize:4;
		_vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
		_allocated = (size_t)newsize;
	}
	size_t _size;
	size_t _allocated;
};

#endif //_SQUTILS_H_