Blender V2.61 - r43446

SCA_RandomSensor.cpp

Go to the documentation of this file.
00001 /*
00002  * Generate random pulses
00003  *
00004  *
00005  * ***** BEGIN GPL LICENSE BLOCK *****
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software Foundation,
00019  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00022  * All rights reserved.
00023  *
00024  * The Original Code is: all of this file.
00025  *
00026  * Contributor(s): none yet.
00027  *
00028  * ***** END GPL LICENSE BLOCK *****
00029  */
00030 
00036 #include <stddef.h>
00037 
00038 #include "SCA_RandomSensor.h"
00039 #include "SCA_EventManager.h"
00040 #include "SCA_RandomEventManager.h"
00041 #include "SCA_LogicManager.h"
00042 #include "ConstExpr.h"
00043 #include <iostream>
00044 
00045 /* ------------------------------------------------------------------------- */
00046 /* Native functions                                                          */
00047 /* ------------------------------------------------------------------------- */
00048 
00049 SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, 
00050                                    SCA_IObject* gameobj,
00051                                    int startseed)
00052     : SCA_ISensor(gameobj,eventmgr)
00053 {
00054     m_basegenerator = new SCA_RandomNumberGenerator(startseed);
00055     Init();
00056 }
00057 
00058 
00059 
00060 SCA_RandomSensor::~SCA_RandomSensor() 
00061 {
00062     m_basegenerator->Release();
00063 }
00064 
00065 void SCA_RandomSensor::Init()
00066 {
00067     m_iteration  = 0;
00068     m_interval = 0;
00069     m_lastdraw   = false;
00070     m_currentDraw = m_basegenerator->Draw();
00071 }
00072 
00073 
00074 CValue* SCA_RandomSensor::GetReplica()
00075 {
00076     CValue* replica = new SCA_RandomSensor(*this);
00077     // this will copy properties and so on...
00078     replica->ProcessReplica();
00079 
00080     return replica;
00081 }
00082 
00083 void SCA_RandomSensor::ProcessReplica()
00084 {
00085     SCA_ISensor::ProcessReplica();
00086     // increment reference count so that we can release the generator at this end
00087     m_basegenerator->AddRef();
00088 }
00089 
00090 
00091 bool SCA_RandomSensor::IsPositiveTrigger()
00092 { 
00093     return (m_invert !=m_lastdraw);
00094 }
00095 
00096 
00097 bool SCA_RandomSensor::Evaluate()
00098 {
00099     /* Random generator is the generator from Line 25 of Table 1 in          */
00100     /* [KNUTH 1981, The Art of Computer Programming Vol. 2                   */
00101     /* (2nd Ed.), pp102]                                                     */
00102     /* It's a very simple max. length sequence generator. We can             */
00103     /* draw 32 bool values before having to generate the next                */
00104     /* sequence value. There are some theorems that will tell you            */
00105     /* this is a reasonable way of generating bools. Check Knuth.            */
00106     /* Furthermore, we only draw each <delay>-eth frame.                     */
00107 
00108     bool evaluateResult = false;
00109 
00110     if (++m_interval > m_pulse_frequency) {
00111         bool drawResult = false;
00112         m_interval = 0;
00113         if (m_iteration > 31) {
00114             m_currentDraw = m_basegenerator->Draw();
00115             drawResult = (m_currentDraw & 0x1) == 0;
00116             m_iteration = 1;
00117         } else {
00118             drawResult = ((m_currentDraw >> m_iteration) & 0x1) == 0;
00119             m_iteration++;
00120         }
00121         evaluateResult = drawResult != m_lastdraw;
00122         m_lastdraw = drawResult;
00123     }
00124 
00125     /* now pass this result to some controller */
00126     return evaluateResult;
00127 }
00128 
00129 #ifdef WITH_PYTHON
00130 
00131 /* ------------------------------------------------------------------------- */
00132 /* Python functions                                                          */
00133 /* ------------------------------------------------------------------------- */
00134 
00135 /* Integration hooks ------------------------------------------------------- */
00136 PyTypeObject SCA_RandomSensor::Type = {
00137     PyVarObject_HEAD_INIT(NULL, 0)
00138     "SCA_RandomSensor",
00139     sizeof(PyObjectPlus_Proxy),
00140     0,
00141     py_base_dealloc,
00142     0,
00143     0,
00144     0,
00145     0,
00146     py_base_repr,
00147     0,0,0,0,0,0,0,0,0,
00148     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00149     0,0,0,0,0,0,0,
00150     Methods,
00151     0,
00152     0,
00153     &SCA_ISensor::Type,
00154     0,0,0,0,0,0,
00155     py_base_new
00156 };
00157 
00158 PyMethodDef SCA_RandomSensor::Methods[] = {
00159     {NULL,NULL} //Sentinel
00160 };
00161 
00162 PyAttributeDef SCA_RandomSensor::Attributes[] = {
00163     KX_PYATTRIBUTE_BOOL_RO("lastDraw",SCA_RandomSensor,m_lastdraw),
00164     KX_PYATTRIBUTE_RW_FUNCTION("seed", SCA_RandomSensor, pyattr_get_seed, pyattr_set_seed),
00165     {NULL} //Sentinel
00166 };
00167 
00168 PyObject* SCA_RandomSensor::pyattr_get_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00169 {
00170     SCA_RandomSensor* self= static_cast<SCA_RandomSensor*>(self_v);
00171     return PyLong_FromSsize_t(self->m_basegenerator->GetSeed());
00172 }
00173 
00174 int SCA_RandomSensor::pyattr_set_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
00175 {
00176     SCA_RandomSensor* self= static_cast<SCA_RandomSensor*>(self_v);
00177     if (!PyLong_Check(value)) {
00178         PyErr_SetString(PyExc_TypeError, "sensor.seed = int: Random Sensor, expected an integer");
00179         return PY_SET_ATTR_FAIL;
00180     }
00181     self->m_basegenerator->SetSeed(PyLong_AsSsize_t(value));
00182     return PY_SET_ATTR_SUCCESS;
00183 }
00184 
00185 #endif // WITH_PYTHON
00186 
00187 /* eof */