PathFinding.xs
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:5k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #include <stdlib.h>
  2. #include "EXTERN.h"
  3. #include "perl.h"
  4. #include "XSUB.h"
  5. #include "algorithm.h"
  6. typedef CalcPath_session * PathFinding;
  7. /* Convenience function for checking whether pv is a reference, and dereference it if necessary */
  8. static inline SV *
  9. derefPV (SV *pv)
  10. {
  11. if (SvTYPE (pv) == SVt_RV) {
  12. return SvRV (pv);
  13. } else
  14. return pv;
  15. }
  16. MODULE = PathFinding PACKAGE = PathFinding PREFIX = PathFinding_
  17. PROTOTYPES: ENABLE
  18. PathFinding
  19. PathFinding_create()
  20. CODE:
  21. RETVAL = CalcPath_new ();
  22. OUTPUT:
  23. RETVAL
  24. void
  25. PathFinding__reset(session, map, weights, width, height, startx, starty, destx, desty, time_max)
  26. PathFinding session
  27. SV *map
  28. SV *weights
  29. unsigned long width
  30. unsigned long height
  31. unsigned short startx
  32. unsigned short starty
  33. unsigned short destx
  34. unsigned short desty
  35. unsigned int time_max
  36. PREINIT:
  37. unsigned char *real_weights = NULL;
  38. char *real_map = NULL;
  39. pos *start, *dest;
  40. session = (PathFinding) 0; /* shut up compiler warning */
  41. CODE:
  42. if (session->map_sv)
  43. SvREFCNT_dec (session->map_sv);
  44. if (session->weight_sv) {
  45. SvREFCNT_dec (session->weight_sv);
  46. session->weight_sv = NULL;
  47. }
  48. /* Sanity check the map parameter and get the map data */
  49. if (map && SvOK (map))
  50. real_map = (char *) SvPV_nolen (derefPV (map));
  51. if (!real_map)
  52. croak("The 'map' parameter must be a valid scalar.n");
  53. if (weights && SvOK (weights)) {
  54. /* Don't use default weights if weights are explictly given */
  55. STRLEN len;
  56. real_weights = (unsigned char *) SvPV (derefPV (weights), len);
  57. if (real_weights && len < 256)
  58. croak("The 'weight' parameter must be a scalar of 256 bytes, or undef.n");
  59. }
  60. start = (pos *) malloc (sizeof (pos));
  61. dest = (pos *) malloc (sizeof (pos));
  62. start->x = startx;
  63. start->y = starty;
  64. dest->x = destx;
  65. dest->y = desty;
  66. CalcPath_init (session, real_map, real_weights, width, height, start, dest, time_max);
  67. /* Increase SV reference counts so the data
  68.    won't be destroyed while we're calculating. */
  69. session->map_sv = derefPV (map);
  70. SvREFCNT_inc (session->map_sv);
  71. if (real_weights != NULL) {
  72. session->weight_sv = weights;
  73. SvREFCNT_inc (weights);
  74. }
  75. int
  76. PathFinding_run(session, r_array)
  77. PathFinding session
  78. SV *r_array
  79. PREINIT:
  80. int status;
  81. CODE:
  82. if (!r_array || !SvOK (r_array) || SvTYPE (r_array) != SVt_RV || SvTYPE (SvRV (r_array)) != SVt_PVAV) {
  83. croak ("PathFinding::run(session, r_array): r_array must be a reference to an arrayn");
  84. XSRETURN_IV (-1);
  85. }
  86. status = CalcPath_pathStep (session);
  87. if (status < 0) {
  88. RETVAL = -1;
  89. } else if (status > 0) {
  90. AV *array;
  91. int i, size;
  92. size = session->solution.size;
  93. array = (AV *) SvRV (r_array);
  94. if (av_len (array) > size)
  95. av_clear (array);
  96. av_extend (array, session->solution.size);
  97. for (i = 0; i < size; i++) {
  98. HV *pos = (HV *) sv_2mortal ((SV *) newHV ());
  99. hv_store (pos, "x", 1, newSViv (session->solution.array[i].x), 0);
  100. hv_store (pos, "y", 1, newSViv (session->solution.array[i].y), 0);
  101. av_store (array, size - i, newRV ((SV *) pos));
  102. }
  103. RETVAL = size;
  104. } else {
  105. RETVAL = 0;
  106. }
  107. OUTPUT:
  108. RETVAL
  109. SV *
  110. PathFinding_runref(session)
  111. PathFinding session
  112. PREINIT:
  113. int status;
  114. CODE:
  115. status = CalcPath_pathStep (session);
  116. if (status < 0) {
  117. XSRETURN_UNDEF;
  118. } else if (status > 0) {
  119. AV * results;
  120. int i;
  121. results = (AV *)sv_2mortal((SV *)newAV());
  122. av_extend(results, session->solution.size);
  123. for (i = session->solution.size - 1; i >= 0; i--) {
  124. HV * rh = (HV *)sv_2mortal((SV *)newHV());
  125. hv_store(rh, "x", 1, newSViv(session->solution.array[i].x), 0);
  126. hv_store(rh, "y", 1, newSViv(session->solution.array[i].y), 0);
  127. av_push(results, newRV((SV *)rh));
  128. }
  129. RETVAL = newRV((SV *)results);
  130. } else {
  131. XSRETURN_NO;
  132. }
  133. OUTPUT:
  134. RETVAL
  135. SV *
  136. PathFinding_runstr(session)
  137. PathFinding session
  138. PREINIT:
  139. int status;
  140. CODE:
  141. status = CalcPath_pathStep (session);
  142. if (status < 0) {
  143. XSRETURN_UNDEF;
  144. } else if (status > 0) {
  145. RETVAL = newSVpvn((char *)&session->solution.array, session->solution.size * sizeof(pos));
  146. } else {
  147. XSRETURN_IV (0);
  148. }
  149. OUTPUT:
  150. RETVAL
  151. int
  152. PathFinding_runcount(session)
  153. PathFinding session
  154. PREINIT:
  155. int status;
  156. CODE:
  157. status = CalcPath_pathStep (session);
  158. if (status < 0)
  159. RETVAL = -1;
  160. else if (status > 0)
  161. RETVAL = (int) session->solution.size;
  162. else
  163. RETVAL = 0;
  164. OUTPUT:
  165. RETVAL
  166. void
  167. PathFinding_DESTROY(session)
  168. PathFinding session
  169. PREINIT:
  170. session = (PathFinding) 0; /* shut up compiler warning */
  171. CODE:
  172. if (session->map_sv)
  173. SvREFCNT_dec (session->map_sv);
  174. if (session->weight_sv)
  175. SvREFCNT_dec (session->weight_sv);
  176. CalcPath_destroy (session);