#include "mysignal.h"
#include "pthread.h"
#include "stdlib.h"
#include "lambda.h"
#include "sys/time.h"
#include "errno.h"
#include "stdio.h"
#include "string.h"
#include "exception.h"
#include "debug.h"

#include "signal_test.h"






// 以下是自动生成的代码示例

// // 把槽函数的参数封装为结构体
// typedef struct {
//   slot_list_with_pars slot_;
//   void* self;
//   int a;
//   int b;
// }test_signal_args;

// typedef struct {
//   slot_list_with_pars slot_;
//   void* self;
//   int a;
//   int b;
// }test_slot_args;


// // 封装函数用来调用实际的槽函数
// static void test_slot_caller(void* args) {
//   test_slot_args* a = args;
//   DBG_LOG("test_slot_caller: %d %d\n", a->a, a->b);
//   DBG_LOG("args_p=%p\n", a);
//   test_slot(a->self, a->a, a->b);
// }

// // 信号函数的实现
// signal test_signal(test_sig_obj* self, int a, int b) {
//   test_signal_args* pars = NULL;
//   slot_list* slot_p = self->__sig_obj.slot_head;
//   while (slot_p) {
//     pars = calloc(1, sizeof(test_signal_args));
//     pars->slot_.func = slot_p->func;
//     // 这里self要换成槽的self
//     pars->self = slot_p->slot_obj;
//     pars->a = a;
//     pars->b = b;
//     if (slot_p->thread) {
//       // 异步调用
//       send_slot_fun(slot_p->thread, (slot_list_with_pars*)pars);
//     } else {
//       // 同步调用
//       slot_p->func(pars);
//       free(pars);
//     }
//     slot_p = slot_p->next;
//   }
// }

// // 定义一个数据结构来保存槽封装函数与槽函数的关系
// typedef struct {
//   void (*func)(void*);
//   char *name;
// } func_name;

// static const func_name g_func_table[] = {
//   {
//     .func = test_slot_caller,
//     .name = "test_slot"
//   }
// };


// void* signal_find_slot_func(const char* name) {
//   for (int i = 0; i < sizeof(g_func_table) / sizeof(func_name); i++) {
//     if (strcmp(name, g_func_table[i].name) == 0) {
//       return g_func_table[i].func;
//     }
//   }
//   return 0;
// }


// 自动生成代码示例结束

static void mdelay(unsigned long mSec){
  struct timeval tv;
  tv.tv_sec=mSec/1000;
  tv.tv_usec=(mSec%1000)*1000;
  int err;
  do{
    err=select(0,NULL,NULL,NULL,&tv);
  }while(err<0 && errno==EINTR);
}


// 定义槽函数
slot test_slot(test_sig_obj2* obj, int a, int b) {
  DBG_LOG("test_slot var=%d\n", obj->test_var);
  obj->test_var = a + b;
  DBG_LOG("test_slot var=%d\n", obj->test_var);
}

slot test_slot3(test_sig_obj3* obj, int a, int b) {
  DBG_LOG("test_slot3 a=%d, b=%d\n", a, b);
  DBG_LOG("obj->v1=%d, obj->v2=%d\n", obj->test_var, obj->test_var2);
}

slot test_slot3_2(test_sig_obj3* obj, int a, int b, const char* c) {
  DBG_LOG("test_slot3_2 a=%d, b=%d, c=%s\n", a, b, c);
  throw_("test_slot3_2 err");
}

static test_sig_obj g_sig_obj = { .test_var = 1, };
static test_sig_obj2 g_sig_obj2 = { .test_var = 2, };
static test_sig_obj3 g_sig_obj3;



void try_catch_test() {
  try_ {
    DBG_LOG("进入第一个try");
    DBG_LOG("抛出异常");
    throw_("第一个try抛出的异常");
  }catch_ {
    DBG_LOG("进入第一个catch");
    try_ {
      DBG_LOG("进入第二个try");
      throw_("第二个try抛出的异常");
    }catch_ {
      DBG_LOG("进入第二个catch");
      throw_("第二个catch抛出的异常");
    }
  }
}





int thread_fun(void* t) {
  mythread_t* th = sigthread_init("signal_thread");
  DBG_LOG("thread_fun start\n");
  connect(&g_sig_obj, test_signal, th, &g_sig_obj2, test_slot);
  connect(&g_sig_obj, test_signal, th, &g_sig_obj3, test_slot3);
  connect(&g_sig_obj, test_signal2, th, &g_sig_obj3, test_slot3_2);
  mdelay(1000);
  emit test_signal(&g_sig_obj, 2, 3);
  mdelay(1000);
  emit test_signal2(&g_sig_obj, 5, 6,"hello world");
  mdelay(1000);
  DBG_LOG("test end\n");
  try_catch_test();

  return 0;
}


