Files
fs2open.github.com/code/object/deadobjectdock.cpp
asarium 39ab45dc7c Add macro for marking unreachable code
This can be used for mark parts of the code which should be unreachable
in normal execution. In debug mode, if such a statement is reached an
Error dialog is shown which aborts the execution. In release mode the
macro is replaced with a compiler specific expression that lets the
compiler know that this part is unreachable which allows it to optimize
the code better.
2018-06-09 17:38:17 +02:00

204 lines
4.2 KiB
C++

/*
* Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project.
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
#include "object/deadobjectdock.h"
#include "object/object.h"
// management prototypes
void dead_dock_add_instance(object *objp, int dockpoint, object *other_objp);
void dead_dock_remove_instance(object *objp, object *other_objp);
dock_instance *dead_dock_find_instance(object *objp, object *other_objp);
dock_instance *dead_dock_find_instance(object *objp, int dockpoint);
object *dock_get_first_dead_docked_object(object *objp)
{
Assert(objp != NULL);
// are we docked?
if (!object_is_dead_docked(objp))
return NULL;
return objp->dead_dock_list->docked_objp;
}
int dock_find_dead_dockpoint_used_by_object(object *objp, object *other_objp)
{
Assert(objp != NULL);
Assert(other_objp != NULL);
dock_instance *result = dead_dock_find_instance(objp, other_objp);
if (result == NULL)
return -1;
else
return result->dockpoint_used;
}
// dock management functions -------------------------------------------------------------------------------------
void dock_dead_dock_objects(object *objp1, int dockpoint1, object *objp2, int dockpoint2)
{
Assert(objp1 != NULL);
Assert(objp2 != NULL);
#ifndef NDEBUG
if ((dead_dock_find_instance(objp1, objp2) != NULL) || (dead_dock_find_instance(objp2, objp1) != NULL))
{
Error(LOCATION, "Trying to dock an object that's already docked!\n");
}
if ((dead_dock_find_instance(objp1, dockpoint1) != NULL) || (dead_dock_find_instance(objp2, dockpoint2) != NULL))
{
Error(LOCATION, "Trying to dock to a dockpoint that's in use!\n");
}
#endif
// put objects on each others' dock lists
dead_dock_add_instance(objp1, dockpoint1, objp2);
dead_dock_add_instance(objp2, dockpoint2, objp1);
}
void dock_dead_undock_objects(object *objp1, object *objp2)
{
Assert(objp1 != NULL);
Assert(objp2 != NULL);
// remove objects from each others' dock lists
dead_dock_remove_instance(objp1, objp2);
dead_dock_remove_instance(objp2, objp1);
}
void dock_dead_undock_all(object *objp)
{
Assert(objp != NULL);
while (object_is_dead_docked(objp))
{
object* dockee = dock_get_first_dead_docked_object(objp);
dock_dead_undock_objects(objp, dockee);
}
}
void dead_dock_add_instance(object *objp, int dockpoint, object *other_objp)
{
dock_instance *item;
// create item
item = (dock_instance *) vm_malloc(sizeof(dock_instance));
item->dockpoint_used = dockpoint;
item->docked_objp = other_objp;
// prepend item to existing list
item->next = objp->dead_dock_list;
objp->dead_dock_list = item;
}
void dead_dock_remove_instance(object *objp, object *other_objp)
{
int found = 0;
dock_instance *prev_ptr, *ptr;
prev_ptr = NULL;
ptr = objp->dead_dock_list;
// iterate until item found
while (ptr != NULL)
{
// if found, exit loop
if (ptr->docked_objp == other_objp)
{
found = 1;
break;
}
// iterate
prev_ptr = ptr;
ptr = ptr->next;
}
// delete if found
if (found)
{
// special case... found at beginning of list
if (prev_ptr == NULL)
{
objp->dead_dock_list = ptr->next;
}
// normal case
else
{
prev_ptr->next = ptr->next;
}
// delete it
vm_free(ptr);
}
else
{
// Trigger assertion. We can recover from this, thankfully
UNREACHABLE("Tried to undock an object that isn't dead docked!\n");
}
}
// just free the list without worrying about undocking anything
void dock_free_dead_dock_list(object *objp)
{
Assert(objp != NULL);
while (objp->dead_dock_list != NULL)
{
dock_instance *ptr = objp->dead_dock_list;
objp->dead_dock_list = ptr->next;
vm_free(ptr);
}
}
dock_instance *dead_dock_find_instance(object *objp, object *other_objp)
{
dock_instance *ptr = objp->dead_dock_list;
// iterate until item found
while (ptr != NULL)
{
// if found, return it
if (ptr->docked_objp == other_objp)
return ptr;
// iterate
ptr = ptr->next;
}
// not found
return NULL;
}
dock_instance *dead_dock_find_instance(object *objp, int dockpoint)
{
dock_instance *ptr = objp->dead_dock_list;
// iterate until item found
while (ptr != NULL)
{
// if found, return it
if (ptr->dockpoint_used == dockpoint)
return ptr;
// iterate
ptr = ptr->next;
}
// not found
return NULL;
}