Skip to content

Commit

Permalink
ADDED beginnings of interaction with scenery objects
Browse files Browse the repository at this point in the history
  • Loading branch information
ksterker committed Jul 18, 2010
1 parent d63a22c commit 7521e0d
Show file tree
Hide file tree
Showing 11 changed files with 450 additions and 68 deletions.
35 changes: 34 additions & 1 deletion src/python/python.cc
Expand Up @@ -102,13 +102,46 @@ namespace python
return ret;
}

// pad tuple
PyObject *pad_tuple (PyObject *tuple, const u_int16 & len)
{
// make sure the given arguments are a tuple
if (tuple && !PyTuple_Check (tuple))
{
fprintf (stderr, "*** error: python::pad_tuple: argument must be a tuple!\n");
return NULL;
}

// calculate size of argument tuple required
u_int16 size = tuple ? PyTuple_GET_SIZE (tuple) + len : len;

// prepare callback arguments
PyObject *new_tuple = PyTuple_New (size);

// pad with none object
for (u_int16 i = 0; i < len; i++)
{
PyTuple_SET_ITEM (new_tuple, i, Py_None);
}

// copy remaining objects, if any
for (u_int16 i = len; i < size; i++)
{
PyObject *o = PyTuple_GET_ITEM (tuple, i - len);
Py_INCREF (o);
PyTuple_SET_ITEM (new_tuple, i, o);
}

return new_tuple;
}

// unflatten the contents of a tuple
PyObject *get_tuple (base::flat & in, const u_int16 & start)
{
u_int16 len = in.get_uint16 ("pln") + start;
PyObject *tuple = PyTuple_New (len);
void *value;

for (u_int16 i = start; i < len; i++)
{
switch (int type = in.next (&value))
Expand Down
12 changes: 11 additions & 1 deletion src/python/python.h
Expand Up @@ -316,9 +316,19 @@ namespace python
//@}

/**
* @name Loading / Saving
* @name Convenience functions.
*/
//@{
/**
* Pads the front of the given tuple, moving the existing
* entries to the end of the tuple. If the given tuple is
* NULL, returns a new tuple of size len. Reference count
* of the contents of the given tuple is increased by one.
*
* @return a new tuple or NULL on error.
*/
PyObject *pad_tuple (PyObject *tuple, const u_int16 & len);

/**
* Read the contents of a tuple from given stream.
* @param in flattener to read the tuple from.
Expand Down
2 changes: 2 additions & 0 deletions src/world/CMakeLists.txt
@@ -1,5 +1,6 @@
# Define the adonthell_world_SRCS variable containing all required files.
set(adonthell_world_SRCS
action.cc
area.cc
area_manager.cc
character.cc
Expand All @@ -24,6 +25,7 @@ set(adonthell_world_SRCS
)

set(adonthell_world_HEADERS
action.h
area.h
area_manager.h
character.h
Expand Down
2 changes: 2 additions & 0 deletions src/world/Makefile.am
Expand Up @@ -4,6 +4,7 @@ EXTRA_DIST = CMakeLists.txt
## Our header files
pkgincludeworlddir = $(pkgincludedir)/world
pkgincludeworld_HEADERS = \
action.h \
area.h \
area_manager.h \
character.h \
Expand Down Expand Up @@ -43,6 +44,7 @@ lib_LTLIBRARIES = libadonthell_world.la

## Rules to build libworld
libadonthell_world_la_SOURCES = \
action.cc \
area.cc \
area_manager.cc \
character.cc \
Expand Down
125 changes: 125 additions & 0 deletions src/world/action.cc
@@ -0,0 +1,125 @@
/*
Copyright (C) 2010 Kai Sterker <kaisterker@linuxgames.com>
Part of the Adonthell Project http://adonthell.linuxgames.com
Adonthell 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.
Adonthell 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 Adonthell; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

/**
* @file world/action.cc
*
* @author Kai Sterker
* @brief Implements the object interaction class.
*/


#include "world/action.h"
#include "python/pool.h"
#include "world/character.h"
#include "world/object.h"


using world::action;

// ctor
action::action ()
{
Action = NULL;
Args = NULL;
}

// dtor
action::~action()
{
clear ();
}

// reset
void action::clear ()
{
delete Action;
Py_XDECREF(Args);

Action = NULL;
Args = NULL;
}

// init
bool action::init (const std::string & script, const std::string & method, PyObject *args)
{
clear ();

Action = python::pool::connect (ACTION_DIR + script, script, method);
if (Action == NULL) return false;

Args = python::pad_tuple (args, 2);
if (Args == NULL)
{
delete Action;
Action = NULL;

return false;
}

return true;
}

// execute action
void action::execute (world::character *actor, world::object *target)
{
execute (python::pass_instance (actor), python::pass_instance (target));
}

// execute action
void action::execute (PyObject *actor, PyObject *target)
{
if (Action != NULL)
{
// prepare arguments
PyTuple_SET_ITEM (Args, 0, actor);
PyTuple_SET_ITEM (Args, 1, target);

Action->execute (Args);

// reset
PyTuple_SET_ITEM (Args, 0, Py_None);
PyTuple_SET_ITEM (Args, 1, Py_None);
}
}

// save
void action::put_state (base::flat& file) const
{
if (Action != NULL)
{
base::flat record;
Action->put_state (record);
python::put_tuple (Args, record, 2);
file.put_flat ("action", record);
}
}

// load
bool action::get_state (base::flat& file)
{
Action = new python::method();
if (Action->get_state (file))
{
Args = python::get_tuple (file, 2);
return true;
}

return false;
}
129 changes: 129 additions & 0 deletions src/world/action.h
@@ -0,0 +1,129 @@
/*
Copyright (C) 2010 Kai Sterker <kaisterker@linuxgames.com>
Part of the Adonthell Project http://adonthell.linuxgames.com
Adonthell 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.
Adonthell 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 Adonthell; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

/**
* @file world/action.h
*
* @author Kai Sterker
* @brief Declares the object interaction class.
*/

#ifndef WORLD_ACTION_H
#define WORLD_ACTION_H

#include "python/method.h"

/**
* Path to the object interaction scripts.
*/
#define ACTION_DIR "schedules.obj."

namespace world
{
class character;
class object;

/**
* This class is used to associate an action with a scenery
* object. The action itself is implemented as the method of
* a python script. Since the method is loaded from the python::pool,
* it should be stateless as it is probably shared by more than
* one object.
*/
class action
{
public:
/**
* Create a new, empty action.
*/
action ();

/**
* Destructor.
*/
~action ();

/**
* Initialize the action.
* @param script name of file inside the action directory.
* @param method name of the method implementing the action.
* @param args optional arguments when calling the method.
* @return true on success, false otherwise.
*/
bool init (const std::string & script, const std::string & method, PyObject *args = NULL);

#ifndef SWIG
/**
* Execute the action with the given character and object.
* @param actor the character triggering the action.
* @param target the object acted on.
*/
void execute (world::character *actor, world::object *target);
#endif

/**
* Execute the action with the given character and object.
*
* This method is optimized for being called from a Python
* script, as it avoids boxing and unboxing of its arguments.
*
* @param actor the character triggering the action.
* @param target the object acted on.
*/
void execute (PyObject *actor, PyObject *target);

/**
* @name Loading / Saving
*/
//@{
/**
* Save the %action to a stream.
* @param file stream where to save the %action.
*/
void put_state (base::flat& file) const;

/**
* Loads the %action from a stream.
* @param file stream to load the %action from.
* @return \e true if the %schedule was loaded successfully, \e false otherwise.
*/
bool get_state (base::flat& file);
//@}

#ifndef SWIG
/// allow %action to be passed through SWIG
GET_TYPE_NAME(world::action);
#endif // SWIG

private:
/**
* Reset the action.
*/
void clear ();

/// Forbid copy constructor
action (const action & a);
/// the action implementation
python::method *Action;
/// additional arguments for the action
PyObject *Args;
};
}

#endif

0 comments on commit 7521e0d

Please sign in to comment.