⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e32module.cpp

📁 python s60 1.4.5版本的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    CActiveScheduler::Add(this);
  }
  
  void DoYield() {
    iStatus = KRequestPending;
    SetActive();
    //iStatus = KErrNone; // Doing this will panic the 3.0 emulator with E32USER-CBase 46 "Stray signal".
    TRequestStatus* pstatus = &iStatus;
    RThread().RequestComplete(pstatus, 0);
#ifdef HAVE_ACTIVESCHEDULERWAIT   
    iWait.Start();
#else
    CActiveScheduler::Start();
#endif
  }

 private:
  void DoCancel() {;}
  void RunL() {
#ifdef HAVE_ACTIVESCHEDULERWAIT
    iWait.AsyncStop();
#else
    CActiveScheduler::Stop();
#endif
  }

#ifdef HAVE_ACTIVESCHEDULERWAIT
  CActiveSchedulerWait iWait;
#endif
};

extern "C" PyObject *
e32_ao_yield(PyObject* /*self*/)
{
  CE32AoYield* y = new CE32AoYield();
  if (!y)
    return PyErr_NoMemory();
  
  Py_BEGIN_ALLOW_THREADS
  y->DoYield();
  delete y;
  Py_END_ALLOW_THREADS

  Py_INCREF(Py_None);
  return Py_None;
}

/*
 *
 * Implementation of e32.ao_sleep
 *
 */

class CE32AoSleep : public CActive
{
 public:
  CE32AoSleep(PyObject* aCb=0):CActive(EPriorityStandard) {
    iCb = aCb;
    Py_XINCREF(iCb);
  }
  ~CE32AoSleep() {
    Cancel();
    iTimer.Close();
    Py_XDECREF(iCb);
  }
  TInt Construct() {
    TInt error = iTimer.CreateLocal();
    if (error == KErrNone)
      CActiveScheduler::Add(this);
    return error;
  }
  void DoSleep(TReal aDelay /*time in seconds*/) {
    iTimeMultiplier = (TInt)(aDelay / MAX_TIME);  
    TReal timeLeft = aDelay - (MAX_TIME * iTimeMultiplier);  
    StartTimer(timeLeft);
    if (!iCb){
      Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT   
      iWait.Start();
#else
      CActiveScheduler::Start();
#endif
      Py_END_ALLOW_THREADS 
    }
  }

 private:
  void DoCancel() {
    iTimer.Cancel();
  }
  void RunL() {
    if (iTimeMultiplier>0) {
      StartTimer(MAX_TIME);
      iTimeMultiplier--;
    }
    else if (!iCb) {
#ifdef HAVE_ACTIVESCHEDULERWAIT
      iWait.AsyncStop();
#else
      CActiveScheduler::Stop();
#endif
      delete this;
    }
    else {
      PyEval_RestoreThread(PYTHON_TLS->thread_state);
      PyObject* tmp_r = NULL;
      tmp_r = PyEval_CallObject(iCb, NULL);
      Py_XDECREF(tmp_r);
      if (PyErr_Occurred())
	      PyErr_Print();
      PyEval_SaveThread();
      delete this;
    }
  }
  void StartTimer(TReal aDelay) {
    TTimeIntervalMicroSeconds32 delay;
#ifndef EKA2 
    delay = TTimeIntervalMicroSeconds32(TInt64(aDelay*1000*1000).GetTInt());
#else
    delay = TTimeIntervalMicroSeconds32(TInt64(aDelay*1000*1000));
#endif  
    iTimer.After(iStatus, delay);
    SetActive();
  }   
  RTimer iTimer;
  TInt iTimeMultiplier;
#ifdef HAVE_ACTIVESCHEDULERWAIT
  CActiveSchedulerWait iWait;
#endif
  PyObject* iCb;
};


extern "C" PyObject *
e32_ao_sleep(PyObject* /*self*/, PyObject* args)
{
  TReal d;
  PyObject* c=NULL;

  if (!PyArg_ParseTuple(args, "d|O", &d, &c))
    return NULL;

  if (c && !PyCallable_Check(c)) {
    PyErr_SetString(PyExc_TypeError, "callable expected for 2nd argument");
    return NULL;
  }

  if (d < 0) {
    PyErr_SetString(PyExc_RuntimeError, "negative number not allowed");
    return NULL;
  }

  CE32AoSleep* s = new CE32AoSleep(c);
  if (!s)
    return PyErr_NoMemory();

  TInt error = s->Construct();
  if (error != KErrNone) {
    delete s;
    return SPyErr_SetFromSymbianOSErr(error);
  }

  s->DoSleep(d);
  Py_INCREF(Py_None);
  return Py_None;
}


/*
 *
 * Implementation of e32.Ao_timer
 *
 */

#define Ao_timer_type (PYTHON_GLOBALS->t_Ao_timer)

#ifndef EKA2
class Ao_timer : public CActive {
#else
NONSHARABLE_CLASS(Ao_timer) : public CActive {
#endif
public:
  Ao_timer();
  void After(TTimeIntervalMicroSeconds32 aSleep, PyObject* aCb);
  TInt Construct();
  ~Ao_timer();
private:
  void RunL();
  void DoCancel();
  RTimer iTimer;
  PyObject* iCb;
#ifdef HAVE_ACTIVESCHEDULERWAIT
  CActiveSchedulerWait iWait;
#endif
};

Ao_timer::Ao_timer():CActive(EPriorityStandard) {;}

void Ao_timer::After(TTimeIntervalMicroSeconds32 aDelay, PyObject* aCb=0)
{
  iCb = aCb;
  Py_XINCREF(iCb);
  iTimer.After(iStatus, aDelay);
  SetActive();
  if (!iCb) {
    Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT   
    iWait.Start();
#else
    CActiveScheduler::Start();
#endif
    Py_END_ALLOW_THREADS
  }
}

TInt Ao_timer::Construct() 
{
  TInt error = iTimer.CreateLocal();
  if (error == KErrNone)
    CActiveScheduler::Add(this);
  return error;
}

Ao_timer::~Ao_timer()
{
  Cancel();
  iTimer.Close();
  Py_XDECREF(iCb);  
}

void Ao_timer::RunL()
{
    if (!iCb) {
#ifdef HAVE_ACTIVESCHEDULERWAIT
      iWait.AsyncStop();
#else
      CActiveScheduler::Stop();
#endif
    }
    else {
    PyEval_RestoreThread(PYTHON_TLS->thread_state);
    PyObject* tmp_r = NULL;
    tmp_r = PyEval_CallObject(iCb, NULL);
    Py_XDECREF(tmp_r);
    if (PyErr_Occurred())
	    PyErr_Print();
    PyEval_SaveThread();
  }
}

void Ao_timer::DoCancel() 
{
  iTimer.Cancel();
}

struct Ao_timer_object {
  PyObject_VAR_HEAD
  Ao_timer* ob_data;
};

extern "C" PyObject *
new_e32_ao_timer_object(PyObject* /*self*/, PyObject /**args*/)
{
  if (!CActiveScheduler::Current()) {
    PyErr_SetString(PyExc_AssertionError, "no ao scheduler");
    return NULL;
  }

  Ao_timer_object *op = PyObject_New(Ao_timer_object, &Ao_timer_type);
  if (op == NULL)
    return PyErr_NoMemory();

  op->ob_data = new Ao_timer();
  if (op->ob_data == NULL) {
    PyObject_Del(op);
    return PyErr_NoMemory();
  }

  TInt error = op->ob_data->Construct();
  if (error != KErrNone) {
    PyObject_Del(op);
    return SPyErr_SetFromSymbianOSErr(error);
  }  
  
  return (PyObject *) op;
}

extern "C" PyObject *
ao_timer_after(Ao_timer_object *self, PyObject* args)
{
  TReal d;
  PyObject* c=NULL;

  if (!PyArg_ParseTuple(args, "d|O", &d, &c))
    return NULL;

  if (c && !PyCallable_Check(c)) {
    PyErr_SetString(PyExc_TypeError, "callable expected for 2nd argument");
    return NULL;
  }
  
  if(self->ob_data->IsActive()) {
    PyErr_SetString(PyExc_RuntimeError, "Timer pending - cancel first");
    return NULL;  
  }
  
  if (d < 0) {
    PyErr_SetString(PyExc_RuntimeError, "negative number not allowed");
    return NULL;
  }
  #ifndef EKA2 
  self->ob_data->After(TTimeIntervalMicroSeconds32(TInt64(d*1000*1000).GetTInt()), c);
  #else
  self->ob_data->After(TTimeIntervalMicroSeconds32(TInt64(d*1000*1000)), c);
  #endif /*EKA2*/ 
  Py_INCREF(Py_None);
  return Py_None;
}

extern "C" PyObject *
ao_timer_cancel(Ao_timer_object *self, PyObject* /*args*/)
{
  self->ob_data->Cancel();
  
  Py_INCREF(Py_None);
  return Py_None;
}

extern "C" {

  static void
  ao_timer_dealloc(Ao_timer_object *op)
  {
    delete op->ob_data;
    op->ob_data = NULL;

    PyObject_Del(op);
  }
  
  static const PyMethodDef ao_timer_methods[] = {
    {"after", (PyCFunction)ao_timer_after, METH_VARARGS},
    {"cancel", (PyCFunction)ao_timer_cancel, METH_NOARGS},
    {NULL,              NULL}           /* sentinel */
  };

  static PyObject *
  ao_timer_getattr(Ao_timer_object *p, char *name)
  {
    return Py_FindMethod((PyMethodDef*)ao_timer_methods,
                         (PyObject *)p, name);
  }

  static const PyTypeObject c_Ao_timer_type = {
    PyObject_HEAD_INIT(NULL)
    0,
    "e32.Ao_timer",
    sizeof(Ao_timer_object),
    0,
    /* methods */
    (destructor)ao_timer_dealloc,       /* tp_dealloc */
    0,                                  /* tp_print */
    (getattrfunc)ao_timer_getattr,      /* tp_getattr */
    0,                                  /* tp_setattr */
    0,                                  /* tp_compare */
    0,                                  /* tp_repr */
    0,                                  /* tp_as _number*/
    0,                                  /* tp_as _sequence*/
    0,                                  /* tp_as _mapping*/
    0,                                  /* tp_hash */
  };
} /* extern "C" */


/*
 *
 * Implementation of e32.ao_callgate
 *
 */

#define Ao_callgate_type ((PYTHON_GLOBALS->tobj).t_Ao_callgate)


struct Ao_callgate_call_item {
  PyObject* args;
  PyObject* kwargs;
  Ao_callgate_call_item* next;
};

class Ao_callgate;

struct Ao_callgate_object {
  PyObject_VAR_HEAD
  Ao_callgate* ob_data;
  unsigned int ob_tid;
  Ao_callgate_call_item ob_args;
};

#ifndef EKA2
class Ao_callgate : public CActive {
#else
NONSHARABLE_CLASS(Ao_callgate) : public CActive {
#endif
public:
  Ao_callgate(Ao_callgate_object* aOb, PyObject* aCb, TInt aTid);
  ~Ao_callgate() {
    Cancel();
    Py_DECREF(iCb);
  }
  TInt Signal(TInt aStatus=KErrNone);
private:
  void RunL();
  void DoCancel() {
    Signal(KErrCancel);
  }
  TRequestStatus* iPst;
  PyObject* iCb;
  Ao_callgate_object* iOb;
  TInt iTid;
};

Ao_callgate::Ao_callgate(Ao_callgate_object* aOb, PyObject* aCb, TInt aTid):
  CActive(0),iOb(aOb),iTid(aTid)
{
  iCb = aCb;
  Py_INCREF(iCb);
  CActiveScheduler::Add(this);
  iStatus = KRequestPending;
  iPst = &iStatus;
  SetActive();
}

TInt Ao_callgate::Signal(TInt aReason)
{
  RThread t;
  TInt error = t.Open(iTid);
  if (error == KErrNone) {
    /* Check for this here, since this check crashes if the thread where the callgate was has finished already. */
    if (iStatus != KRequestPending)
        return KErrNone;
    t.RequestComplete(iPst, aReason);
    t.Close();
  }
  return error;
}

void Ao_callgate::RunL()
{
  PyEval_RestoreThread(PYTHON_TLS->thread_state);
  Ao_callgate_call_item* p = iOb->ob_args.next;
  iOb->ob_args.next = NULL;
  int lastReferenceGone = 0;
  while (p) {
    PyObject* tmp_r = NULL;
    tmp_r = PyEval_CallObjectWithKeywords(iCb, p->args, p->kwargs);
    Py_XDECREF(tmp_r);
    if (PyErr_Occurred())
      PyErr_Print();
    Ao_callgate_call_item* tmp = p->next;
    Py_XDECREF(p->args);
    Py_XDECREF(p->kwargs);
    PyMem_Free(p);
    p = tmp;
    lastReferenceGone=(iOb->ob_refcnt == 1);  
    /* Note: If refcount is 1, this object is destroyed right now! 
     * There shouldn't be any calls in the queue after this. */
    Py_DECREF(iOb); 
  }
  PyEval_SaveThread();
  if (lastReferenceGone) {
      /* If the last reference was lost above, then the object has been freed already, and we
       * must not go poking around in the deallocated memory anymore. */ 
      return;
  }
  iStatus = KRequestPending;
  iPst = &iStatus;
  SetActive();
}

extern "C" PyObject *
e32_ao_callgate(PyObject* /*self*/, PyObject* args)
{
  if (!CActiveScheduler::Current()) {
    PyErr_SetString(PyExc_AssertionError, "no ao scheduler");
    return NULL;
  }

  PyObject* c;
  if (!PyArg_ParseTuple(args, "O", &c))
    return NULL;
    
  if (!PyCallable_Check(c)) {
    PyErr_SetString(PyExc_TypeError, "callable expected");
    return NULL;
  }

  Ao_callgate_object *op = PyObject_New(Ao_callgate_object,
                                        &Ao_callgate_type);
  if (op == NULL)
    return PyErr_NoMemory();

  op->ob_args.args = NULL;
  op->ob_args.kwargs = NULL;
  op->ob_args.next = NULL;
  op->ob_tid = RThread().Id();
  if (!(op->ob_data = new Ao_callgate(op, c, op->ob_tid))) {
    PyObject_Del(op);
    return PyErr_NoMemory();
  }
  return (PyObject *) op;
}

extern "C" PyObject *
ao_cg_call(PyObject* self, PyObject* args, PyObject* kwargs)
{
  Ao_callgate_object *op = (Ao_callgate_object*)self;
  Ao_callgate_call_item* n =
    (Ao_callgate_call_item*)PyMem_Malloc(sizeof(Ao_callgate_call_item));
  if (!n)
    return PyErr_NoMemory();
  n->args = args;
  Py_XINCREF(args);
  n->kwargs = kwargs;
  Py_XINCREF(kwargs);
  n->next = NULL;

  Ao_callgate_call_item* p = &(op->ob_args);
  while (p->next) p = p->next;
  p->next = n;
  
  Py_INCREF(op);
  TInt error = op->ob_data->Signal();
  if (error != KErrNone) {
    p->next = NULL;
    Py_DECREF(op);
    Py_XDECREF(n->args);
    Py_XDECREF(n->kwargs);
    PyMem_Free(n);
  }
  RETURN_ERROR_OR_PYNONE(error);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -