cocos2d-x 10.1版本 http 链接

cocos2d-x 10.1版本 http 链接

这是根据 cocos2d-x-2.0 修改的。

 

 1 /********************************************************************
 2  *  Copyright(C) 2012 Ambition( All rights reserved. )
 3  *    Created:    2012/09/18   11:21
 4  *    File base:    HSBaseHttp.h
 5  *    Author:        Ambition
 6  *    
 7  *    Purpose:    
 8 *********************************************************************/
 9 #ifndef __HSBaseHttp_H__
10 #define __HSBaseHttp_H__
11 #pragma once
12 #include "cocos2d.h"
13 #include "curl.h"
14 #include <queue>
15 #include <pthread.h>
16 #include <semaphore.h>
17 #include <errno.h>
18 #include "HSHttpRequest.h"
19 #include "HSHttpResponse.h"
20 using namespace cocos2d;
21 
22 #if WIN32
23 #pragma comment(lib,"libcurl_imp.lib")
24 #pragma comment(lib,"pthreadVCE2.lib")
25 #endif
26 
27 
28 class HSBaseHttp : public SelectorProtocol,public CCObject
29 {
30 
31 public:
32     HSBaseHttp();
33     virtual ~HSBaseHttp();
34 
35 private:
36     int iTimeoutForConnect;        //链接超时时间
37     int iTimeoutForRead;        //读取超时时间
38 public:
39     //得到一个实例
40     static HSBaseHttp* GetInstance();
41     //销毁实例
42     static void DestroyInstance();
43     //发送请求
44     void Send(HSHttpRequest* request);
45     void SetTimeoutForConnect(int value);
46     
47     int GetTimeoutForConnect();
48  
49     void SetTimeoutForRead(int value);
50 
51     int GetTimeoutForRead();
52     
53 
54 
55 private:
56     //销毁回调
57     void DispatchResponseCallbacks(float delta);
58     //线程信号初始化
59     bool LazyInitThreadSemphore();
60 };
61 
62 
63 #endif // __HSBaseHttp_H__

 

  1 #include "HSBaseHttp.h"
  2 
  3 
  4 //static member
  5 static HSBaseHttp* s_pBaseHttp = NULL; // pointer to singleton
  6 
  7 //线程锁
  8 static pthread_t        s_networkThread;
  9 static pthread_mutex_t  s_requestQueueMutex;
 10 static pthread_mutex_t  s_responseQueueMutex;
 11 static sem_t *          s_pSem = NULL;
 12 static unsigned long    s_asyncRequestCount = 0;
 13 
 14 static bool need_quit = false;
 15 static CCArray* s_requestQueue = NULL;        //请求队列
 16 static CCArray* s_responseQueue = NULL;        //响应队列
 17 
 18 #if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
 19 #define CC_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE 1
 20 #else
 21 #define CC_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE 0
 22 #endif
 23 
 24 #if CC_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE
 25 #define CC_ASYNC_HTTPREQUEST_SEMAPHORE "ccHttpAsync"
 26 #else
 27 static sem_t s_sem;
 28 #endif
 29 
 30 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
 31 typedef int int32_t;
 32 #endif
 33 
 34 static char s_errorBuffer[CURL_ERROR_SIZE];
 35 
 36 typedef size_t (*write_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
 37 
 38 //
 39 // C 函数实现
 40 //
 41 
 42 size_t writeData(void *ptr, size_t size, size_t nmemb, void *stream)
 43 {
 44     std::vector<char> *recvBuffer = (std::vector<char>*)stream;
 45     size_t sizes = size * nmemb;
 46 
 47     recvBuffer->clear();
 48     recvBuffer->assign((char*)ptr, (char*)ptr + sizes);
 49     CCLog("...%s ...   ",(char*)ptr);
 50 
 51     return sizes;
 52 }
 53 
 54 bool ConfigureCURL(CURL *handle)
 55 {
 56     if (!handle) {
 57         return false;
 58     }
 59 
 60     int32_t code;
 61     code = curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, s_errorBuffer);
 62     if (code != CURLE_OK) {
 63         return false;
 64     }
 65     //设置超时时间 防止一直等待
 66     code = curl_easy_setopt(handle, CURLOPT_TIMEOUT, HSBaseHttp::GetInstance()->GetTimeoutForRead());
 67     if (code != CURLE_OK) {
 68         return false;
 69     }
 70     code = curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, HSBaseHttp::GetInstance()->GetTimeoutForConnect());
 71     if (code != CURLE_OK) {
 72         return false;
 73     }
 74 
 75     return true;
 76 }
 77 
 78 //Post 模式设置
 79 int ProcessPostTask(HSHttpRequest *request, write_callback callback, void *stream, int32_t *responseCode)
 80 {
 81     CURLcode code = CURL_LAST;
 82     CURL *curl = curl_easy_init();
 83 
 84     do {
 85         if (!ConfigureCURL(curl)) {
 86             break;
 87         }
 88 
 89         code = curl_easy_setopt(curl, CURLOPT_URL, request->GetUrl());
 90         if (code != CURLE_OK) {
 91             break;
 92         }
 93         code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
 94         if (code != CURLE_OK) {
 95             break;
 96         }
 97         code = curl_easy_setopt(curl, CURLOPT_WRITEDATA, stream);
 98         if (code != CURLE_OK) {
 99             break;
100         }
101         code = curl_easy_setopt(curl, CURLOPT_POST, 1);
102         if (code != CURLE_OK) {
103             break;
104         }
105         code = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request->GetRequestData());
106         if (code != CURLE_OK) {
107             break;
108         }
109         code = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, request->GetRequestDataSize());
110         if (code != CURLE_OK) {
111             break;
112         }
113         code = curl_easy_perform(curl);
114         if (code != CURLE_OK) {
115             break;
116         }
117 
118         code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, responseCode); 
119         if (code != CURLE_OK || *responseCode != 200) {
120             code = CURLE_HTTP_RETURNED_ERROR;
121         }
122     } while (0);
123     if (curl) {
124         curl_easy_cleanup(curl);
125     }
126 
127     return (code == CURLE_OK ? 0 : 1);    
128 }
129 
130 //Get模式设置
131 int ProcessGetTask(HSHttpRequest *request, write_callback callback, void *stream, int *responseCode)
132 {
133     CURLcode code = CURL_LAST;
134     CURL *curl = curl_easy_init();
135 
136     do {
137         if (!ConfigureCURL(curl)) 
138         {
139             break;
140         }
141 
142         code = curl_easy_setopt(curl, CURLOPT_URL, request->GetUrl());
143         if (code != CURLE_OK) 
144         {
145             break;
146         }
147 
148         code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
149         if (code != CURLE_OK) 
150         {
151             break;
152         }
153 
154         code = curl_easy_setopt(curl, CURLOPT_WRITEDATA, stream);
155         if (code != CURLE_OK) 
156         {
157             break;
158         }
159 
160         code = curl_easy_perform(curl);
161         if (code != CURLE_OK) 
162         {
163             break;
164         }
165 
166         code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, responseCode); 
167         if (code != CURLE_OK || *responseCode != 200) 
168         {
169             code = CURLE_HTTP_RETURNED_ERROR;
170         }
171     } while (0);
172 
173     if (curl) {
174         curl_easy_cleanup(curl);
175     }
176 
177     return (code == CURLE_OK ? 0 : 1);
178 }
179 
180 
181 static void* NetworkThread(void *data)
182 {    
183     HSHttpRequest *request = NULL;
184 
185     while (true) 
186     {
187         // Wait for http request tasks from main thread
188         int semWaitRet = sem_wait(s_pSem);
189         if (semWaitRet < 0) {
190             CCLog("HSBaseHttp: HttpRequest async thread semaphore error: %s\n", strerror(errno));
191             break;
192         }
193 
194         if (need_quit)
195         {
196             break;
197         }
198 
199         // step 1: send http request if the requestQueue isn't empty
200         request = NULL;
201 
202         pthread_mutex_lock(&s_requestQueueMutex); //Get request task from queue
203         if (0 != s_requestQueue->count())
204         {
205             request = dynamic_cast<HSHttpRequest*>(s_requestQueue->objectAtIndex(0));
206             s_requestQueue->removeObjectAtIndex(0);  
207             // request's refcount = 1 here
208         }
209         pthread_mutex_unlock(&s_requestQueueMutex);
210 
211         if (NULL == request)
212         {
213             continue;
214         }
215 
216         // step 2: libcurl sync access
217 
218         // Create a HttpResponse object, the default setting is http access failed
219         HSHttpResponse *response = new HSHttpResponse(request);
220 
221         // request's refcount = 2 here, it's retained by HttpRespose constructor
222         request->release();
223         // ok, refcount = 1 now, only HttpResponse hold it.
224 
225         int responseCode = -1;
226         int retValue = 0;
227 
228         // Process the request -> get response packet
229         switch (request->GetRequestType())
230         {
231         case HSHttpRequest::HTTP_MODE_GET: // HTTP GET
232             retValue = ProcessGetTask(request,     writeData,     response->GetResponseData(), &responseCode);
233             break;
234 
235         case HSHttpRequest::HTTP_MODE_POST: // HTTP POST
236             retValue = ProcessPostTask(request, writeData,     response->GetResponseData(), &responseCode);
237             break;
238 
239         default:
240             CCAssert(true, "CCHttpClient: unkown request type, only GET and POSt are supported");
241             break;
242         }
243 
244         // write data to HttpResponse
245         response->SetResponseCode(responseCode);
246 
247         if (retValue != 0) 
248         {
249             response->SetSucceed(false);
250             response->SetErrorBuffer(s_errorBuffer);
251         }
252         else
253         {
254             response->SetSucceed(true);
255         }
256 
257 
258         // add response packet into queue
259         pthread_mutex_lock(&s_responseQueueMutex);
260         s_responseQueue->addObject(response);
261         pthread_mutex_unlock(&s_responseQueueMutex);
262 
263         // resume dispatcher selector
264         CCScheduler::sharedScheduler()->resumeTarget(HSBaseHttp::GetInstance());
265     }
266 
267     // cleanup: if worker thread received quit signal, clean up un-completed request queue
268     pthread_mutex_lock(&s_requestQueueMutex);
269     s_requestQueue->removeAllObjects();
270     pthread_mutex_unlock(&s_requestQueueMutex);
271     s_asyncRequestCount -= s_requestQueue->count();
272 
273     if (s_pSem != NULL) {
274 #if CC_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE
275         sem_unlink(CC_ASYNC_HTTPREQUEST_SEMAPHORE);
276         sem_close(s_pSem);
277 #else
278         sem_destroy(s_pSem);
279 #endif
280 
281         s_pSem = NULL;
282 
283         pthread_mutex_destroy(&s_requestQueueMutex);
284         pthread_mutex_destroy(&s_responseQueueMutex);
285 
286         s_requestQueue->release();
287         s_responseQueue->release();
288     }
289 
290     pthread_exit(NULL);
291 
292     return 0;
293 }
294 
295 HSBaseHttp::HSBaseHttp()
296 {
297     this->iTimeoutForConnect = 30;
298     this->iTimeoutForRead = 60;
299     CCScheduler::sharedScheduler()->scheduleSelector(schedule_selector(HSBaseHttp::DispatchResponseCallbacks), this, 0, false);
300     CCScheduler::sharedScheduler()->pauseTarget(this);
301 }
302 
303 HSBaseHttp::~HSBaseHttp()
304 {
305     need_quit = true;
306 
307     if (s_pSem != NULL) 
308     {
309         sem_post(s_pSem);
310     }
311     CCScheduler::sharedScheduler()->unscheduleSelector(schedule_selector(HSBaseHttp::DispatchResponseCallbacks), this);
312 }
313 
314 HSBaseHttp* HSBaseHttp::GetInstance()
315 {
316     if (s_pBaseHttp == NULL)
317     {
318         s_pBaseHttp = new HSBaseHttp();
319     }
320 
321     return s_pBaseHttp;
322 }
323 
324 void HSBaseHttp::DestroyInstance()
325 {
326     CCScheduler::sharedScheduler()->unscheduleSelector(schedule_selector(HSBaseHttp::DispatchResponseCallbacks),HSBaseHttp::GetInstance());
327     CC_SAFE_RELEASE_NULL(s_pBaseHttp);
328 }
329 
330 void HSBaseHttp::DispatchResponseCallbacks(float delta)
331 {
332     HSHttpResponse* response = NULL;
333 
334     pthread_mutex_lock(&s_responseQueueMutex);
335     if (s_responseQueue->count())
336     {
337         response = dynamic_cast<HSHttpResponse*>(s_responseQueue->objectAtIndex(0));
338         s_responseQueue->removeObjectAtIndex(0);
339     }
340     pthread_mutex_unlock(&s_responseQueueMutex);
341 
342     if (response)
343     {
344         --s_asyncRequestCount;
345 
346         HSHttpRequest* request = response->GetHttpRequest();
347         SelectorProtocol* pTarget = request->GetTarget();
348         SEL_CallFuncND pSelector = request->GetSelector();
349 
350         if (pTarget && pSelector) 
351         {
352             (pTarget->*pSelector)((CCNode *)this, response);
353         }
354 
355         response->release();
356     }
357 
358     if (0 == s_asyncRequestCount) 
359     {
360         CCScheduler::sharedScheduler()->pauseTarget(this);
361     }
362 }
363 
364 bool HSBaseHttp::LazyInitThreadSemphore()
365 {
366     if(s_pSem != NULL)
367         return false;
368 
369 #if CC_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE
370     s_pSem = sem_open(CC_ASYNC_HTTPREQUEST_SEMAPHORE, O_CREAT, 0644, 0);
371     if (s_pSem == SEM_FAILED) {
372         CCLog("Open HttpRequest Semaphore failed");
373         s_pSem = NULL;
374         return false;
375     }
376 #else
377     int semRet = sem_init(&s_sem, 0, 0);
378     if (semRet < 0) {
379         CCLog("Init HttpRequest Semaphore failed");
380         return false;
381     }
382 
383     s_pSem = &s_sem;
384 #endif
385 
386     s_requestQueue = CCArray::array();
387     s_requestQueue->init();
388     s_requestQueue->retain();
389 
390     s_responseQueue = CCArray::array();    
391     s_responseQueue->init();
392     s_responseQueue->retain();
393 
394     pthread_mutex_init(&s_requestQueueMutex, NULL);
395     pthread_mutex_init(&s_responseQueueMutex, NULL);
396 
397     pthread_create(&s_networkThread, NULL, NetworkThread, NULL);
398     pthread_detach(s_networkThread);
399 
400     need_quit = false;
401 
402     return true;
403 
404 }
405 
406 void HSBaseHttp::Send(HSHttpRequest* request)
407 {
408     if (!LazyInitThreadSemphore() || !request) 
409     {
410         return;
411     }
412 
413     ++s_asyncRequestCount;
414 
415     request->retain();
416 
417     pthread_mutex_lock(&s_requestQueueMutex);
418     s_requestQueue->addObject(request);
419     pthread_mutex_unlock(&s_requestQueueMutex);
420 
421     // Notify thread start to work
422     sem_post(s_pSem);
423 }
424 
425 void HSBaseHttp::SetTimeoutForConnect( int value )
426 {
427     this->iTimeoutForConnect = value;
428 }
429 
430 int HSBaseHttp::GetTimeoutForConnect()
431 {
432     return this->iTimeoutForConnect;
433 }
434 
435 void HSBaseHttp::SetTimeoutForRead( int value )
436 {
437     this->iTimeoutForRead = value;
438 }
439 
440 int HSBaseHttp::GetTimeoutForRead()
441 {
442     return this->iTimeoutForRead;
443 }

 

 

 1 /********************************************************************
 2  *  Copyright(C) 2012 Ambition( All rights reserved. )
 3  *    Created:    2012/09/20   9:41
 4  *    File base:    HSHttpRequest.h
 5  *    Author:        Ambition
 6  *    
 7  *    Purpose:    请求消息发送和设置(不是发送的具体数据)
 8 *********************************************************************/
 9 #ifndef __HSHttpRequest_H__
10 #define __HSHttpRequest_H__
11 #pragma once
12 #include "cocos2d.h"
13 using namespace cocos2d;
14 
15 class HSHttpRequest : public CCObject
16 {
17 public:
18     HSHttpRequest(void);
19     ~HSHttpRequest(void);
20 
21 public:
22     typedef enum
23     {
24         HTTP_MODE_GET,
25         HTTP_MODE_POST,
26         HTTP_MODE_UNKOWN,
27     }HttpRequestType;
28 
29 protected:
30     SelectorProtocol*    pTarget;
31     SEL_CallFuncND        pSelector;        //回调选择器
32     HttpRequestType        requestType;    //请求类型
33     string                strUrl;
34     vector<char>        vRequestData;
35     string              tag;
36     void*               pUserData;        //用语在请求前添加的标志 例(Ambition:xxxxxx)
37 
38 public:
39     SelectorProtocol* GetTarget();
40     SEL_CallFuncND GetSelector();
41     void SetRequestType(HttpRequestType type);
42     HttpRequestType GetRequestType();
43 
44     void SetUrl(const char* url);
45     const char* GetUrl();
46 
47     void SetRequestData(const char* buffer, unsigned int len);
48     char* GetRequestData();
49 
50     int GetRequestDataSize();
51 
52     void SetResponseCallback(SelectorProtocol* pTarget, cocos2d::SEL_CallFuncND pSelector);  
53 
54     void SetTag(const char* tag);
55     const char* GetTag();
56 
57     void SetUserData(void* pUserData);
58     void* GetUserData();
59 };
60 
61 
62 #endif // __HSHttpRequest_H__

 

 

 1 #include "HSHttpRequest.h"
 2 
 3 HSHttpRequest::HSHttpRequest(void)
 4 {
 5     this->requestType = HTTP_MODE_UNKOWN;
 6     this->vRequestData.clear();
 7     this->tag.clear();
 8     this->pTarget = NULL;
 9     this->pSelector = NULL;
10     this->pUserData = NULL;
11 }
12 
13 HSHttpRequest::~HSHttpRequest(void)
14 {
15 }
16 
17 SelectorProtocol* HSHttpRequest::GetTarget()
18 {
19     return this->pTarget;
20 }
21 
22 cocos2d::SEL_CallFuncND HSHttpRequest::GetSelector()
23 {
24     return pSelector;
25 }
26 
27 HSHttpRequest::HttpRequestType HSHttpRequest::GetRequestType()
28 {
29     return this->requestType;
30 }
31 
32 void HSHttpRequest::SetUrl( const char* url )
33 {
34     strUrl = url;
35 }
36 
37 const char* HSHttpRequest::GetUrl()
38 {
39     return strUrl.c_str();
40 }
41 
42 void HSHttpRequest::SetRequestData( const char* buffer, unsigned int len )
43 {
44     vRequestData.assign(buffer, buffer + len);
45 }
46 
47 char* HSHttpRequest::GetRequestData()
48 {
49     return &(vRequestData.front());
50 }
51 
52 int HSHttpRequest::GetRequestDataSize()
53 {
54     return vRequestData.size();
55 }
56 
57 void HSHttpRequest::SetRequestType( HttpRequestType type )
58 {
59     requestType = type;
60 }
61 
62 void HSHttpRequest::SetResponseCallback( SelectorProtocol* pTarget, cocos2d::SEL_CallFuncND pSelector )
63 {
64     this->pTarget = pTarget;
65     this->pSelector = pSelector;
66 
67     if (this->pTarget)
68     {
69         //this->pTarget->retain();
70         //如果有问题以后修改
71     }
72 }
73 
74 void HSHttpRequest::SetTag( const char* tag )
75 {
76     this->tag = tag;
77 }
78 
79 const char* HSHttpRequest::GetTag()
80 {
81     return this->tag.c_str();
82 }
83 
84 void HSHttpRequest::SetUserData( void* pUserData )
85 {
86     this->pUserData = pUserData;
87 }
88 
89 void* HSHttpRequest::GetUserData()
90 {
91     return this->pUserData;
92 }

 

 1 /********************************************************************
 2  *  Copyright(C) 2012 Ambition( All rights reserved. )
 3  *    Created:    2012/09/20   9:42
 4  *    File base:    HSHttpResponse.h
 5  *    Author:        Ambition
 6  *    
 7  *    Purpose:    响应包含返回的具体数据,但是没有解析
 8 *********************************************************************/
 9 #ifndef __HSHttpResponse_H__
10 #define __HSHttpResponse_H__
11 #pragma once
12 #include "HSHttpRequest.h"
13 
14 
15 class HSHttpResponse : public CCObject
16 {
17 public:
18     HSHttpResponse(HSHttpRequest* request);
19     virtual ~HSHttpResponse(void);
20 
21 protected:
22     HSHttpRequest*    pHttpRequest;    //对应的请求指针
23     bool            isSucceed;        //是否成功
24     vector<char>    vResponseData;    
25     int                iResponseCode;    //响应代码
26     string            strErrorBuffer;    //错误信息缓存
27 
28 public:
29     HSHttpRequest* GetHttpRequest();
30 
31     void SetResponseData(std::vector<char>* data);
32     vector<char>* GetResponseData();
33 
34     void SetResponseCode(int value);
35     int GetResponseCode();
36 
37     void SetSucceed(bool value);
38     bool GetSucceed();
39 
40     void SetErrorBuffer(const char* value);
41     const char* GetErrorBuffer();
42 
43 };
44 
45 #endif // __HSHttpResponse_H__

 

 1 #include "HSHttpResponse.h"
 2 
 3 HSHttpResponse::HSHttpResponse(HSHttpRequest* request)
 4 {
 5     this->pHttpRequest = request;
 6     if (this->pHttpRequest)
 7     {
 8         this->pHttpRequest->retain();
 9     }
10     this->isSucceed = false;
11     this->vResponseData.clear();
12     this->strErrorBuffer.clear();
13 }
14 
15 HSHttpResponse::~HSHttpResponse(void)
16 {
17     if (this->pHttpRequest)
18     {
19         this->pHttpRequest->release();
20     }
21 }
22 
23 HSHttpRequest* HSHttpResponse::GetHttpRequest()
24 {
25     return this->pHttpRequest;
26 }
27 
28 void HSHttpResponse::SetResponseData( std::vector<char>* data )
29 {
30     vResponseData = *data;
31 }
32 
33 vector<char>* HSHttpResponse::GetResponseData()
34 {
35     return &vResponseData;
36 }
37 
38 void HSHttpResponse::SetResponseCode( int value )
39 {
40     iResponseCode = value;
41 }
42 
43 int HSHttpResponse::GetResponseCode()
44 {
45     return this->iResponseCode;
46 }
47 
48 void HSHttpResponse::SetSucceed( bool value )
49 {
50     isSucceed = value;
51 }
52 
53 bool HSHttpResponse::GetSucceed()
54 {
55     return this->isSucceed;
56 }
57 
58 void HSHttpResponse::SetErrorBuffer( const char* value )
59 {
60     strErrorBuffer.clear();
61     strErrorBuffer.assign(value);
62 }
63 
64 const char* HSHttpResponse::GetErrorBuffer()
65 {
66     return strErrorBuffer.c_str();
67 }

 

测试代码:

 

 

 1     HSHttpRequest* request = new HSHttpRequest();
 2     request->SetUrl("http://220.194.62.22/wapgame/a.jsp");
 3     request->SetRequestType(HSHttpRequest::HTTP_MODE_POST);
 4     request->SetResponseCallback(this, callfuncND_selector(HelloWorld::onHttpRequestCompleted));
 5 
 6     // write the post data
 7     const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetowrkTest";
 8     request->SetRequestData(postData, strlen(postData)); 
 9     request->SetTag("POST test");
10     HSBaseHttp::GetInstance()->Send(request);
11     request->release();

 

转载于:https://www.cnblogs.com/GameDeveloper/articles/2706562.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110313.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • JDK1.8下载安装(Windows版)

    JDK1.8下载安装(Windows版)官网下载JDK在oracle上的下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html,根据自己的需要,我这儿选择的是“JavaSE8u201/JavaSE8u202”,点击【JDK-DOWNLOAD】,打开第二张截图,如图选择接受,然后下载“JavaSEDevelopmentKit…

  • 北京移动全网优惠_随着竞争的加剧

    北京移动全网优惠_随着竞争的加剧 【eNet硅谷动力消息】被叫全免计划终于推出了,这个计划可以说是大家翘首以盼,许多人大大节省了话费,对很多人来说是一个大大的福音,但也因此造成了中国通讯资费的改革提速,从而加剧了行业之间的竞争。  中移动北京公司市场部负责人介绍,5月23日公司正式推出了全球通标准资费“被叫全免计划”。自即日开始,北京地区的全球通客户切实实现被叫免费,接听时间没有限制,进一步呼应了社会的期盼。按照本次…

  • 快速排序基本思路(通俗易懂+例子)「建议收藏」

    快速排序基本思路(通俗易懂+例子)「建议收藏」快速排序今天看到大神写的一篇快速排序的博客,肃然起敬,觉得原来快速排序这么简单下面进行简单的试试快速排序的基本思想是1、先从数列中取出一个数作为基准数2、分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边3、再对左右区间重复第二步,直到各区间只有一个数概括来说为挖坑填数+分治法下面举例来进行说明,主要有三个参数,i为区间的开始地址,j为区间

  • python进阶(11)生成器[通俗易懂]

    python进阶(11)生成器[通俗易懂]生成器利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。

  • Lucene全文检索工具包学习笔记总结

    Lucene全文检索工具包学习笔记总结

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号