Selaa lähdekoodia

Merge pull request #1280 from AtomicGameEngine/JME-ATOMIC-UPDATES

Updates
JoshEngebretson 9 vuotta sitten
vanhempi
sitoutus
bccaaaf8a1

+ 0 - 23
Resources/EditorData/AtomicEditor/editor/ui/activation.tb.txt

@@ -1,23 +0,0 @@
-TBLayout: axis: y, distribution: gravity
-	TBLayout: distribution: gravity
-		TBImageWidget: filename: "AtomicEditor/editor/images/atomic_logo.png"
-		TBTextField: text: "Product Key:"
-			font: size:18
-		TBLayout: gravity: left right, distribution-position: right bottom
-			TBEditField: id: license_key, autofocus: 1
-				placeholder ATOMIC-XXXX-XXXX-XXXX-XXXX
-				lp: width: 240
-	TBSeparator: gravity: left right, skin: AESeparator
-	TBLayout: position: top, spacing: 28
-		TBButton: text: Activate, id: activate
-			lp: min-width: 128, min-height: 64
-		TBLayout: axis: y
-			TBButton: text: "Get Free Key", id: get_key, skin: TBButton.greentext
-				lp: min-width: 128, min-height: 64
-			TBTextField: text: "(will open browser window)", skin: DarkGrayText
-	TBSeparator: gravity: left right, skin: AESeparator
-	TBButton: text: Quit, id: quit
-	TBSeparator: gravity: left right, skin: AESeparator
-	TBTextField: text: "Please contact [email protected] with any product key issues"		
-		
-

+ 16 - 8
Script/AtomicEditor/ui/modal/About.ts

@@ -89,17 +89,27 @@ class About extends ModalWindow {
         var buildDate = Atomic.AtomicBuildInfo.getBuildDate();
         var buildTime = Atomic.AtomicBuildInfo.getBuildTime();
         var buildSHA = Atomic.AtomicBuildInfo.getGitSHA();
+        var buildVendor = Atomic.AtomicBuildInfo.getBuildVendor();
 
-        var buildString = `<color #FFFFFF>'${buildName}' - ${buildDate} ${buildTime}\nGit: ${buildSHA} </color>`;
+        var buildString = `<color #FFFFFF>'${buildName}' - ${buildDate} ${buildTime}\nGit: ${buildSHA}\nVendor: <color #76D6FF>${buildVendor}</color></color>`;
 
         text += "<widget TBImageWidget: filename: 'AtomicEditor/editor/images/atomic_logo.png'>\n\n";
         text += "(c) 2014-2016 THUNDERBEAST GAMES LLC\n\n";
 
         text += "<color #76D6FF>Build Information:</color>\n";
 
-        text += "<color #D4FB79>" + buildString + "</color>\n\n";
+        text += buildString + "\n\n";
 
-        text += "<color #D4FB79>Installed platforms and modules:</color>\n\n";
+        let contributors = ["JoshEngebretson", "shaddockh", "rsredsq", "JimMarlowe", "mattbenic",
+        "Type1J", "weinandvv", "JohnnyWahib", "raheelx", "CTrauma", "eugenegous", "christoffersch", "GarethNN",
+        "LaraEngebretson", "bitonator", "rokups", "honigbeutler123", "benwolf", "jonaspm",
+        "keithjohnston", "darrylryan", "Alan-FGR", "marynate", "Sleaker", "Tarik-B", "flyover", "buresu"];
+
+        contributors.sort();
+
+        text += `<color #76D6FF>Atomic Contributors:</color>\n<color #88FF88>${contributors.join(", ")}</color>\n\n`;
+
+        text += "<color #76D6FF>Installed platforms and modules:</color>\n\n";
 
         var licenseSystem = ToolCore.licenseSystem;
 
@@ -128,12 +138,10 @@ class About extends ModalWindow {
         if (!licenseSystem.licenseIOS || !licenseSystem.licenseAndroid || !licenseSystem.licenseModule3D) {
           text += "<color #76D6FF>Available platforms and modules:</color>\n\n";
           text += availableText + "\n\n\n";
-      }
-
+        }
 
-        text += "<color #76D6FF>Special Thanks:</color>\n\n";
-        text += "    The Urho3D Project - http://urho3d.github.io\n\n";
-        text += "    Sami Vaarala - http://www.duktape.org";
+        text += "<color #76D6FF>Special Thanks:</color>\n";
+        text += "The Urho3D Project (http://urho3d.github.io), Sami Vaarala (http://www.duktape.org)\n";
 
         return text;
 

+ 13 - 0
Source/Atomic/BuildInfo/AtomicBuildInfo.cpp

@@ -53,4 +53,17 @@ bool AtomicBuildInfo::GetDistBuild()
 #endif
 }
 
+#ifndef ATOMIC_BUILD_VENDOR
+static String buildVendor("Unknown Vendor");
+#else
+static String buildVendor(ATOMIC_BUILD_VENDOR);
+#endif
+
+const String& AtomicBuildInfo::GetBuildVendor()
+{
+    return buildVendor;
+}
+
+
+
 }

+ 3 - 0
Source/Atomic/BuildInfo/AtomicBuildInfo.h

@@ -58,6 +58,9 @@ class AtomicBuildInfo : public RefCounted
     /// Get whether this is a distibution/installer binary build
     static bool GetDistBuild();
 
+    /// Get vendor string
+    static const String& GetBuildVendor();
+
 };
 
 

+ 63 - 0
Source/Atomic/Web/WebEvents.h

@@ -0,0 +1,63 @@
+//
+// Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "../Core/Object.h"
+
+namespace Atomic
+{
+
+/// WebRequest has completed
+ATOMIC_EVENT(E_WEBREQUESTCOMPLETE, WebRequestComplete)
+{
+    ATOMIC_PARAM(P_REQUEST, Request);    // WebRequest
+    ATOMIC_PARAM(P_ERROR, Error);        // String
+    ATOMIC_PARAM(P_DOWNLOAD, Download);  // Deserializer (BufferQueue)
+    ATOMIC_PARAM(P_UPLOAD, Upload);      // Serializer (BufferQueue)
+}
+
+/// WebRequest progress event
+ATOMIC_EVENT(E_WEBREQUESTPROGRESS, WebRequestProgress)
+{
+    ATOMIC_PARAM(P_REQUEST, Request);              // WebRequest
+    ATOMIC_PARAM(P_DOWNLOADTOTAL, DownloadTotal);  // int
+    ATOMIC_PARAM(P_DOWNLOADED, Downloaded);        // int
+    ATOMIC_PARAM(P_UPLOADTOTAL, UploadTotal);      // int
+    ATOMIC_PARAM(P_UPLOADED, Uploaded);            // int
+}
+
+ATOMIC_EVENT(E_WEBREQUESTDOWNLOADCHUNK, WebRequestDownloadChunk)
+{
+    ATOMIC_PARAM(P_REQUEST, Request);     // WebRequest
+    ATOMIC_PARAM(P_DOWNLOAD, Download);   // Deserializer (BufferQueue)
+    ATOMIC_PARAM(P_CHUNKSIZE, ChunkSize);  // unsigned
+}
+
+ATOMIC_EVENT(E_WEBREQUESTUPLOADCHUNK, WebRequestUploadChunk)
+{
+    ATOMIC_PARAM(P_REQUEST, Request);       // WebRequest
+    ATOMIC_PARAM(P_UPLOAD, Upload);         // Serializer (BufferQueue)
+    ATOMIC_PARAM(P_BYTESREMAINING, BytesRemaining);   // unsigned
+}
+
+}

+ 85 - 41
Source/Atomic/Web/WebRequest.cpp

@@ -27,6 +27,7 @@
 #include "../IO/BufferQueue.h"
 #include "../IO/Log.h"
 #include "../Web/Web.h"
+#include "../Web/WebEvents.h"
 #include "../Web/WebRequest.h"
 
 #ifdef EMSCRIPTEN
@@ -48,10 +49,8 @@ namespace Atomic
 
 struct WebRequestInternalState
 {
-    /// The WebRequest external state.
+    /// The WebRequest external state
     WebRequest& es;
-    /// The WebRequest external state to force it to stay around.
-    SharedPtr<WebRequest> es_hold;
     /// The work queue.
     asio::io_service* service;
     /// URL.
@@ -61,9 +60,9 @@ struct WebRequestInternalState
     /// Response headers.
     HashMap<StringHash, Pair<String, String>> responseHeaders;
     /// Upload stream.
-    SharedPtr<Object> upload;
+    SharedPtr<BufferQueue> upload;
     /// Download stream.
-    SharedPtr<Object> download;
+    SharedPtr<BufferQueue> download;
     /// Request Headers.
     curl_slist* headers = NULL;
     /// Connection state.
@@ -80,16 +79,16 @@ struct WebRequestInternalState
     bool isAddedToMulti;
     /// Error string. Empty if no error.
     char error[CURL_ERROR_SIZE];
+    /// String cache of response
+    String response;
 
     WebRequestInternalState(WebRequest &es_) :
         es(es_)
     {
-        ATOMIC_LOGDEBUG("Create WebRequestInternalState");
     }
 
     ~WebRequestInternalState()
     {
-        ATOMIC_LOGDEBUG("Destroy WebRequestInternalState");
     }
 
     static int onProgress(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
@@ -103,12 +102,16 @@ struct WebRequestInternalState
             return CURL_READFUNC_ABORT;
         }
 
+        using namespace WebRequestProgress;
+
         VariantMap eventData;
-        eventData.Insert(MakePair(StringHash("down_total"), Variant((double)dltotal)));
-        eventData.Insert(MakePair(StringHash("down_loaded"), Variant((double)dlnow)));
-        eventData.Insert(MakePair(StringHash("up_total"), Variant((double)ultotal)));
-        eventData.Insert(MakePair(StringHash("up_loaded"), Variant((double)ulnow)));
-        is_->es.SendEvent("progress", eventData);
+        eventData[P_REQUEST] = &is_->es;
+        eventData[P_DOWNLOADTOTAL] = (int) dltotal;
+        eventData[P_DOWNLOADED] = (int) dlnow;
+        eventData[P_UPLOADTOTAL] = (int) ultotal;
+        eventData[P_UPLOADED] = (int) ulnow;
+        is_->es.SendEvent(E_WEBREQUESTPROGRESS, eventData);
+
         return 0;
     }
 
@@ -182,14 +185,16 @@ struct WebRequestInternalState
         size_t real_size(size * nmemb);
 
         // Write the date into the download buffer queue.
-        Serializer* download(dynamic_cast<Serializer*>(is_->download.Get()));
-        download->Write(ptr, (unsigned int)real_size);
+        is_->download->Write(ptr, (unsigned int)real_size);
 
-        // Emit a "download_chunk" event.
+        using namespace WebRequestDownloadChunk;
         VariantMap eventData;
-        eventData.Insert(MakePair(StringHash("download"), Variant(is_->download)));
-        eventData.Insert(MakePair(StringHash("size"), Variant((unsigned int)real_size)));
-        is_->es.SendEvent("download_chunk", eventData);
+
+        eventData[P_REQUEST] = &is_->es;
+        eventData[P_DOWNLOAD] = is_->download;
+        eventData[P_CHUNKSIZE] = (unsigned) real_size;
+
+        is_->es.SendEvent(E_WEBREQUESTDOWNLOADCHUNK, eventData);
 
         return real_size;
     }
@@ -208,32 +213,35 @@ struct WebRequestInternalState
         size_t real_size(size * nitems);
 
         // Read as much as we can from the upload buffer queue.
-        Deserializer* upload(dynamic_cast<Deserializer*>(is_->upload.Get()));
-        size_t size_queued(upload->GetSize());
+        size_t size_queued(is_->upload->GetSize());
         size_t size_left(real_size);
         if ((size_left > 0) && (size_queued > 0))
         {
             size_t read_size(std::min(size_queued, size_left));
-            upload->Read(buffer, (unsigned int)read_size);
+            is_->upload->Read(buffer, (unsigned int)read_size);
             size_left -= read_size;
         }
 
-        // If we still have bytes to fill, then emit a "upload_chunk" event.
+        // If we still have bytes to fill, then emit a E_WEBREQUESTUPLOADCHUNK event.
         if (size_left > 0)
         {
+            using namespace WebRequestUploadChunk;
+
             VariantMap eventData;
-            eventData.Insert(MakePair(StringHash("upload"), Variant(is_->upload)));
-            eventData.Insert(MakePair(StringHash("size"), Variant((unsigned int)size_left)));
-            is_->es.SendEvent("upload_chunk", eventData);
+            eventData[P_REQUEST] = &is_->es;
+            eventData[P_UPLOAD] = is_->upload;
+            eventData[P_BYTESREMAINING] = (unsigned)size_left;
+
+            is_->es.SendEvent(E_WEBREQUESTUPLOADCHUNK, eventData);
         }
 
         // Read as much as we can from the upload buffer queue (again).
-        size_queued = upload->GetSize();
+        size_queued = is_->upload->GetSize();
         size_left = real_size;
         if ((size_left > 0) && (size_queued > 0))
         {
             size_t read_size(std::min(size_queued, size_left));
-            upload->Read(buffer, (unsigned int)read_size);
+            is_->upload->Read(buffer, (unsigned int)read_size);
             size_left -= read_size;
         }
 
@@ -248,20 +256,25 @@ struct WebRequestInternalState
     }
 
     void onEnd(int code)
-    {
+    {       
+        using namespace WebRequestComplete;
         VariantMap eventData;
+
+        eventData[P_REQUEST] = &es;
+
         if (code != CURLE_OK)
         {
             state = HTTP_ERROR;
-            eventData.Insert(MakePair(StringHash("error"), Variant(String(error, (unsigned int)strnlen(error, sizeof(error))))));
+            eventData[P_ERROR] = String(error, (unsigned int)strnlen(error, sizeof(error)));
         }
         else
         {
             state = HTTP_CLOSED;
-            eventData.Insert(MakePair(StringHash("download"), Variant(download)));
-            eventData.Insert(MakePair(StringHash("upload"), Variant(upload)));
+            eventData[P_DOWNLOAD] = download;
+            eventData[P_UPLOAD] = upload;
         }
-        es.SendEvent("complete", eventData);
+
+        es.SendEvent(E_WEBREQUESTCOMPLETE, eventData);
     }
 };
 
@@ -286,8 +299,6 @@ WebRequest::WebRequest(Context* context, const String& verb, const String& url,
 
 WebRequest::~WebRequest()
 {
-    ATOMIC_LOGDEBUG("Destroy WebRequest");
-
     curl_slist_free_all(is_->headers);
     if (is_->curlm == NULL)
     {
@@ -299,14 +310,10 @@ WebRequest::~WebRequest()
 
 void WebRequest::setup(asio::io_service *service, CURLM *curlm)
 {
-    ATOMIC_LOGDEBUG("Create WebRequest");
-
     is_->service = service;
     is_->curlm = curlm;
     is_->curl = curl_easy_init();
 
-    ATOMIC_LOGDEBUG("HTTP " + is_->verb + " request to URL " + is_->url);
-
     curl_easy_setopt(is_->curl, CURLOPT_ERRORBUFFER, is_->error);
     is_->error[0] = '\0';
 
@@ -346,11 +353,14 @@ void WebRequest::setup(asio::io_service *service, CURLM *curlm)
 void WebRequest::internalNotify(WebRequest *wr, int code)
 {
     wr->is_->onEnd(code);
+
     if (wr->is_->isAddedToMulti)
     {
         curl_multi_remove_handle(wr->is_->curlm, wr->is_->curl);
         wr->is_->isAddedToMulti = false;
-        wr->is_->es_hold.Reset();
+
+        // release the reference held from the Send method
+        wr->ReleaseRef();
     }
 }
 
@@ -401,11 +411,15 @@ void WebRequest::Send()
 {
     if (!is_->isAddedToMulti && !is_->isAborted)
     {
-        is_->es_hold = this;
+        // Add a reference to ourselves during the Send, this is released
+        // in notifyInternal,  if we're leaking WebRequests check that
+        // this is being called
+        AddRef();
+
         curl_easy_setopt(is_->curl, CURLOPT_HTTPHEADER, is_->headers);
         if (CURLM_OK != curl_multi_add_handle(is_->curlm, is_->curl))
         {
-            ATOMIC_LOGDEBUG("ERROR SENDING REQUEST!");
+            ATOMIC_LOGERROR("WebRequest::Send() - ERROR SENDING REQUEST!");
         }
         is_->isAddedToMulti = true;
     }
@@ -446,6 +460,36 @@ String WebRequest::GetAllResponseHeaders()
     return allHeaders;
 }
 
+void WebRequest::SetPostData(const String& postData)
+{
+    // use the copy post fields option so we don't need to hold onto the string buffer
+    curl_easy_setopt(is_->curl, CURLOPT_COPYPOSTFIELDS, postData.CString());
 }
 
+const String& WebRequest::GetResponse()
+{
+    // use cached response if we have one
+    if (is_->response.Length())
+        return is_->response;
+
+    unsigned size = is_->download->GetSize();
+
+    if (!size)
+        return String::EMPTY;
+
+    SharedArrayPtr<unsigned char> response(new unsigned char[size + 1]);
+
+    // ensure 0 terminated string
+    response[size] = 0;
+
+    is_->download->Read( (void *) &response[0], size);
+    is_->response = (const char*) &response[0];
+
+    return is_->response;
+
+}
+
+}
+
+
 #endif

+ 8 - 2
Source/Atomic/Web/WebRequest.h

@@ -53,7 +53,7 @@ enum WebRequestState
 
 struct WebRequestInternalState;
 
-/// An HTTP connection with response data stream.
+/// An HTTP(S) connection with response data stream that uses curl internally
 class WebRequest : public Object
 {
     friend class Web;
@@ -82,7 +82,7 @@ public:
     /// Return whether connection is in the open state.
     bool IsOpen() const { return GetState() == HTTP_OPEN; }
 
-    /// Return whether "download_chunk" event will be fired or if only "complete" will be.
+    /// Return whether E_WEBREQUESTDOWNLOADCHUNK event will be fired or if only E_WEBREQUESTCOMPLETE will be.
     bool HasDownloadChunkEvent();
 
     /// Set an HTTP request header (only works before Send has been called).
@@ -96,6 +96,12 @@ public:
     /// Get all HTTP response headers. Using GetResponseHeaderKeys() and GetResponseHeader() is more efficient than using this function.
     String GetAllResponseHeaders();
 
+    /// Set post data for request
+    void SetPostData(const String& postData);
+
+    /// Get the request response as a string
+    const String& GetResponse();
+
 private:
 #ifndef EMSCRIPTEN
     void setup(asio::io_service *service, CURLM* curlm);

+ 1 - 1
Submodules/AtomicExamples

@@ -1 +1 @@
-Subproject commit a1d68b7432419d0d6de3cd8184ee26bfbc4942ae
+Subproject commit cfa4c4e116d92cc9787048664134d30c0fa92154