Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/GameLogic/SCA_ISensor.cpp')
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp176
1 files changed, 142 insertions, 34 deletions
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 68f5653d53a..2783bf14600 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -45,26 +45,28 @@ void SCA_ISensor::ReParent(SCA_IObject* parent)
SCA_ILogicBrick::ReParent(parent);
// will be done when the sensor is activated
//m_eventmgr->RegisterSensor(this);
- this->SetActive(false);
+ //this->SetActive(false);
}
SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
class SCA_EventManager* eventmgr,
PyTypeObject* T ) :
- SCA_ILogicBrick(gameobj,T),
- m_triggered(false)
+ SCA_ILogicBrick(gameobj,T)
{
m_links = 0;
m_suspended = false;
m_invert = false;
m_level = false;
+ m_tap = false;
m_reset = false;
m_pos_ticks = 0;
m_neg_ticks = 0;
m_pos_pulsemode = false;
m_neg_pulsemode = false;
m_pulse_frequency = 0;
+ m_state = false;
+ m_prev_state = false;
m_eventmgr = eventmgr;
}
@@ -75,6 +77,12 @@ SCA_ISensor::~SCA_ISensor()
// intentionally empty
}
+void SCA_ISensor::ProcessReplica()
+{
+ SCA_ILogicBrick::ProcessReplica();
+ m_linkedcontrollers.clear();
+}
+
bool SCA_ISensor::IsPositiveTrigger() {
bool result = false;
@@ -104,9 +112,13 @@ void SCA_ISensor::SetLevel(bool lvl) {
m_level = lvl;
}
+void SCA_ISensor::SetTap(bool tap) {
+ m_tap = tap;
+}
+
double SCA_ISensor::GetNumber() {
- return IsPositiveTrigger();
+ return GetState();
}
void SCA_ISensor::Suspend() {
@@ -143,27 +155,80 @@ void SCA_ISensor::RegisterToManager()
{
// sensor is just activated, initialize it
Init();
- m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
+ m_state = false;
m_eventmgr->RegisterSensor(this);
}
+void SCA_ISensor::LinkToController(SCA_IController* controller)
+{
+ m_linkedcontrollers.push_back(controller);
+}
+
+void SCA_ISensor::UnlinkController(SCA_IController* controller)
+{
+ std::vector<class SCA_IController*>::iterator contit;
+ for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+ {
+ if ((*contit) == controller)
+ {
+ *contit = m_linkedcontrollers.back();
+ m_linkedcontrollers.pop_back();
+ return;
+ }
+ }
+ printf("Missing link from sensor %s:%s to controller %s:%s\n",
+ m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(),
+ controller->GetParent()->GetName().ReadPtr(), controller->GetName().ReadPtr());
+}
+
+void SCA_ISensor::UnlinkAllControllers()
+{
+ std::vector<class SCA_IController*>::iterator contit;
+ for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+ {
+ (*contit)->UnlinkSensor(this);
+ }
+ m_linkedcontrollers.clear();
+}
+
void SCA_ISensor::UnregisterToManager()
{
m_eventmgr->RemoveSensor(this);
+ m_links = 0;
+}
+
+void SCA_ISensor::ActivateControllers(class SCA_LogicManager* logicmgr)
+{
+ for(vector<SCA_IController*>::const_iterator c= m_linkedcontrollers.begin();
+ c!=m_linkedcontrollers.end();++c)
+ {
+ SCA_IController* contr = *c;
+ if (contr->IsActive())
+ logicmgr->AddTriggeredController(contr, this);
+ }
}
-void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
+void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr)
{
// calculate if a __triggering__ is wanted
// don't evaluate a sensor that is not connected to any controller
if (m_links && !m_suspended) {
- bool result = this->Evaluate(event);
+ bool result = this->Evaluate();
+ // store the state for the rest of the logic system
+ m_prev_state = m_state;
+ m_state = this->IsPositiveTrigger();
if (result) {
- logicmgr->AddActivatedSensor(this);
- // reset these counters so that pulse are synchronized with transition
- m_pos_ticks = 0;
- m_neg_ticks = 0;
+ // the sensor triggered this frame
+ if (m_state || !m_tap) {
+ ActivateControllers(logicmgr);
+ // reset these counters so that pulse are synchronized with transition
+ m_pos_ticks = 0;
+ m_neg_ticks = 0;
+ } else
+ {
+ result = false;
+ }
} else
{
/* First, the pulsing behaviour, if pulse mode is
@@ -172,41 +237,55 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
if (m_pos_pulsemode) {
m_pos_ticks++;
if (m_pos_ticks > m_pulse_frequency) {
- if ( this->IsPositiveTrigger() )
+ if ( m_state )
{
- logicmgr->AddActivatedSensor(this);
+ ActivateControllers(logicmgr);
+ result = true;
}
m_pos_ticks = 0;
}
}
-
- if (m_neg_pulsemode)
+ // negative pulse doesn't make sense in tap mode, skip
+ if (m_neg_pulsemode && !m_tap)
{
m_neg_ticks++;
if (m_neg_ticks > m_pulse_frequency) {
- if (!this->IsPositiveTrigger() )
+ if (!m_state )
{
- logicmgr->AddActivatedSensor(this);
+ ActivateControllers(logicmgr);
+ result = true;
}
m_neg_ticks = 0;
}
}
}
- if (!m_newControllers.empty())
+ if (m_tap)
{
- if (!IsActive() && m_level)
+ // in tap mode: we send always a negative pulse immediately after a positive pulse
+ if (!result)
{
- // This level sensor is connected to at least one controller that was just made
- // active but it did not generate an event yet, do it now to those controllers only
- for (std::vector<SCA_IController*>::iterator ci=m_newControllers.begin();
- ci != m_newControllers.end(); ci++)
+ // the sensor did not trigger on this frame
+ if (m_prev_state)
{
- logicmgr->AddTriggeredController(*ci, this);
+ // but it triggered on previous frame => send a negative pulse
+ ActivateControllers(logicmgr);
+ result = true;
}
+ // in any case, absence of trigger means sensor off
+ m_state = false;
+ }
+ }
+ if (!result && m_level)
+ {
+ // This level sensor is connected to at least one controller that was just made
+ // active but it did not generate an event yet, do it now to those controllers only
+ for(vector<SCA_IController*>::const_iterator c= m_linkedcontrollers.begin();
+ c!=m_linkedcontrollers.end();++c)
+ {
+ SCA_IController* contr = *c;
+ if (contr->IsJustActivated())
+ logicmgr->AddTriggeredController(contr, this);
}
- // clear the list. Instead of using clear, which also release the memory,
- // use erase, which keeps the memory available for next time.
- m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
}
}
}
@@ -221,7 +300,7 @@ const char SCA_ISensor::IsPositive_doc[] =
PyObject* SCA_ISensor::PyIsPositive()
{
ShowDeprecationWarning("isPositive()", "the read-only positive property");
- int retval = IsPositiveTrigger();
+ int retval = GetState();
return PyInt_FromLong(retval);
}
@@ -385,6 +464,7 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_ISensor, reset,
"\tThe sensor is put in its initial state as if it was just activated.\n")
{
Init();
+ m_prev_state = false;
Py_RETURN_NONE;
}
@@ -393,8 +473,13 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_ISensor, reset,
/* ----------------------------------------------- */
PyTypeObject SCA_ISensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_ISensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -453,18 +538,25 @@ PyAttributeDef SCA_ISensor::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RW("useNegPulseMode",SCA_ISensor,m_neg_pulsemode),
KX_PYATTRIBUTE_INT_RW("frequency",0,100000,true,SCA_ISensor,m_pulse_frequency),
KX_PYATTRIBUTE_BOOL_RW("invert",SCA_ISensor,m_invert),
- KX_PYATTRIBUTE_BOOL_RW("level",SCA_ISensor,m_level),
+ KX_PYATTRIBUTE_BOOL_RW_CHECK("level",SCA_ISensor,m_level,pyattr_check_level),
+ KX_PYATTRIBUTE_BOOL_RW_CHECK("tap",SCA_ISensor,m_tap,pyattr_check_tap),
KX_PYATTRIBUTE_RO_FUNCTION("triggered", SCA_ISensor, pyattr_get_triggered),
KX_PYATTRIBUTE_RO_FUNCTION("positive", SCA_ISensor, pyattr_get_positive),
+ //KX_PYATTRIBUTE_TODO("links"),
+ //KX_PYATTRIBUTE_TODO("posTicks"),
+ //KX_PYATTRIBUTE_TODO("negTicks"),
{ NULL } //Sentinel
};
-PyObject*
-SCA_ISensor::py_getattro(PyObject *attr)
+PyObject* SCA_ISensor::py_getattro(PyObject *attr)
{
py_getattro_up(SCA_ILogicBrick);
}
+PyObject* SCA_ISensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ILogicBrick);
+}
+
int SCA_ISensor::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_ILogicBrick);
@@ -482,7 +574,23 @@ PyObject* SCA_ISensor::pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_D
PyObject* SCA_ISensor::pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
SCA_ISensor* self= static_cast<SCA_ISensor*>(self_v);
- return PyInt_FromLong(self->IsPositiveTrigger());
+ return PyInt_FromLong(self->GetState());
+}
+
+int SCA_ISensor::pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_ISensor* self= static_cast<SCA_ISensor*>(self_v);
+ if (self->m_level)
+ self->m_tap = false;
+ return 0;
+}
+
+int SCA_ISensor::pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_ISensor* self= static_cast<SCA_ISensor*>(self_v);
+ if (self->m_tap)
+ self->m_level = false;
+ return 0;
}
/* eof */