scummvm/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp
2021-03-06 20:07:09 -08:00

163 lines
5 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.
*
*/
//=============================================================================
//
// C-Script run-time interpreter (c) 2001 Chris Jones
//
// You must DISABLE OPTIMIZATIONS AND REGISTER VARIABLES in your compiler
// when compiling this, or strange results can happen.
//
// There is a problem with importing functions on 16-bit compilers: the
// script system assumes that all parameters are passed as 4 bytes, which
// ints are not on 16-bit systems. Be sure to define all parameters as longs,
// or join the 21st century and switch to DJGPP or Visual C++.
//
//=============================================================================
//#define DEBUG_MANAGED_OBJECTS
#include "ags/engine/ac/dynobj/cc_dynamicobject.h"
#include "ags/engine/ac/dynobj/managedobjectpool.h"
#include "ags/shared/debugging/out.h"
#include "ags/shared/script/cc_error.h"
#include "ags/shared/script/script_common.h"
#include "ags/shared/util/stream.h"
#include "ags/globals.h"
namespace AGS3 {
using namespace AGS::Shared;
ICCStringClass *stringClassImpl = nullptr;
// set the class that will be used for dynamic strings
void ccSetStringClassImpl(ICCStringClass *theClass) {
stringClassImpl = theClass;
}
// register a memory handle for the object and allow script
// pointers to point to it
int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *callback, bool plugin_object) {
int32_t handl = _GP(pool).AddObject((const char *)object, callback, plugin_object);
ManagedObjectLog("Register managed object type '%s' handle=%d addr=%08X",
((callback == NULL) ? "(unknown)" : callback->GetType()), handl, object);
return handl;
}
// register a de-serialized object
int32_t ccRegisterUnserializedObject(int index, const void *object, ICCDynamicObject *callback, bool plugin_object) {
return _GP(pool).AddUnserializedObject((const char *)object, callback, plugin_object, index);
}
// unregister a particular object
int ccUnRegisterManagedObject(const void *object) {
return _GP(pool).RemoveObject((const char *)object);
}
// remove all registered objects
void ccUnregisterAllObjects() {
_GP(pool).reset();
}
// serialize all objects to disk
void ccSerializeAllObjects(Stream *out) {
_GP(pool).WriteToDisk(out);
}
// un-serialise all objects (will remove all currently registered ones)
int ccUnserializeAllObjects(Stream *in, ICCObjectReader *callback) {
return _GP(pool).ReadFromDisk(in, callback);
}
// dispose the object if RefCount==0
void ccAttemptDisposeObject(int32_t handle) {
_GP(pool).CheckDispose(handle);
}
// translate between object handles and memory addresses
int32_t ccGetObjectHandleFromAddress(const char *address) {
// set to null
if (address == nullptr)
return 0;
int32_t handl = _GP(pool).AddressToHandle(address);
ManagedObjectLog("Line %d WritePtr: %08X to %d", _G(currentline), address, handl);
if (handl == 0) {
cc_error("Pointer cast failure: the object being pointed to is not in the managed object pool");
return -1;
}
return handl;
}
const char *ccGetObjectAddressFromHandle(int32_t handle) {
if (handle == 0) {
return nullptr;
}
const char *addr = _GP(pool).HandleToAddress(handle);
ManagedObjectLog("Line %d ReadPtr: %d to %08X", _G(currentline), handle, addr);
if (addr == nullptr) {
cc_error("Error retrieving pointer: invalid handle %d", handle);
return nullptr;
}
return addr;
}
ScriptValueType ccGetObjectAddressAndManagerFromHandle(int32_t handle, void *&object, ICCDynamicObject *&manager) {
if (handle == 0) {
object = nullptr;
manager = nullptr;
return kScValUndefined;
}
ScriptValueType obj_type = _GP(pool).HandleToAddressAndManager(handle, object, manager);
if (obj_type == kScValUndefined) {
cc_error("Error retrieving pointer: invalid handle %d", handle);
}
return obj_type;
}
int ccAddObjectReference(int32_t handle) {
if (handle == 0)
return 0;
return _GP(pool).AddRef(handle);
}
int ccReleaseObjectReference(int32_t handle) {
if (handle == 0)
return 0;
if (_GP(pool).HandleToAddress(handle) == nullptr) {
cc_error("Error releasing pointer: invalid handle %d", handle);
return -1;
}
return _GP(pool).SubRef(handle);
}
} // namespace AGS3