summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2013-03-16 17:45:18 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2013-03-16 17:45:18 (GMT)
commitf05044ab68e51ce9c374f6af09284051efcda449 (patch)
tree6ae35ed5f6f3395593fc0d2c90780d8162f302e7 /src
parentd383d6d7e5e1d3ca0856c02ebbcea5e9b8b2ff4e (diff)
downloadpowder-f05044ab68e51ce9c374f6af09284051efcda449.zip
powder-f05044ab68e51ce9c374f6af09284051efcda449.tar.gz
APIRequest, Aync methods for client, Profile edit/viewer (WIP)
Diffstat (limited to 'src')
-rw-r--r--src/client/Client.cpp55
-rw-r--r--src/client/Client.h5
-rw-r--r--src/client/UserInfo.h22
-rw-r--r--src/client/requestbroker/APIRequest.cpp77
-rw-r--r--src/client/requestbroker/APIRequest.h15
-rw-r--r--src/client/requestbroker/APIResultParser.h16
-rw-r--r--src/client/requestbroker/RequestBroker.cpp12
-rw-r--r--src/client/requestbroker/RequestBroker.h4
-rw-r--r--src/game/GameController.cpp12
-rw-r--r--src/options/OptionsController.cpp5
-rw-r--r--src/options/OptionsController.h1
-rw-r--r--src/options/OptionsModel.cpp11
-rw-r--r--src/options/OptionsModel.h2
-rw-r--r--src/options/OptionsView.cpp18
-rw-r--r--src/options/OptionsView.h1
-rw-r--r--src/preview/PreviewView.cpp2
-rw-r--r--src/profile/ProfileActivity.cpp68
-rw-r--r--src/profile/ProfileActivity.h17
18 files changed, 320 insertions, 23 deletions
diff --git a/src/client/Client.cpp b/src/client/Client.cpp
index a43c45b..dcd4903 100644
--- a/src/client/Client.cpp
+++ b/src/client/Client.cpp
@@ -39,10 +39,13 @@
#include "client/SaveInfo.h"
#include "client/SaveFile.h"
#include "client/GameSave.h"
+#include "client/UserInfo.h"
#include "search/Thumbnail.h"
#include "preview/Comment.h"
#include "ClientListener.h"
#include "requestbroker/RequestBroker.h"
+#include "requestbroker/APIRequest.h"
+#include "requestbroker/APIResultParser.h"
#include "cajun/reader.h"
#include "cajun/writer.h"
@@ -1178,26 +1181,42 @@ std::vector<unsigned char> Client::GetSaveData(int saveID, int saveDate)
return saveData;
}
-VideoBuffer * Client::GetAvatar(std::string username)
+RequestBroker::Request * Client::GetUserInfoAsync(std::string username)
{
- lastError = "";
- int dataStatus;
- int dataLength = 0;
- unsigned char * data;
- std::stringstream urlStream;
- urlStream << "http://" << STATICSERVER << "/avatars/" << username << ".pti";
-
- data = (unsigned char *)http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
- if(data && dataStatus == 200)
+ class UserInfoParser: public APIResultParser
{
- std::vector<char> responseData(data, data+dataLength);
- return format::PTIToVideoBuffer(responseData);
- }
- else if(data)
- {
- free(data);
- }
- return NULL;
+ virtual void * ProcessResponse(unsigned char * data, int dataLength)
+ {
+ try
+ {
+ std::istringstream dataStream((char*)data);
+ json::Object objDocument;
+ json::Reader::Read(objDocument, dataStream);
+ json::Object tempUser = objDocument["User"];
+
+ json::Number userIDTemp = tempUser["ID"];
+ json::String usernameTemp = tempUser["Username"];
+ json::String bioTemp = tempUser["Biography"];
+ //json::Number ageTemp = tempUser["Age"];
+
+ return new UserInfo(
+ userIDTemp.Value(),
+ 0,//ageTemp.Value(),
+ usernameTemp.Value(),
+ bioTemp.Value());
+ }
+ catch (json::Exception &e)
+ {
+ return 0;
+ }
+ }
+ virtual void Cleanup(void * objectPtr)
+ {
+ delete (UserInfo*)objectPtr;
+ }
+ virtual ~UserInfoParser() { }
+ };
+ return new APIRequest("http://" SERVER "/User.json?Name=" + username, new UserInfoParser());
}
LoginStatus Client::Login(std::string username, std::string password, User & user)
diff --git a/src/client/Client.h b/src/client/Client.h
index c824d28..f00083d 100644
--- a/src/client/Client.h
+++ b/src/client/Client.h
@@ -12,6 +12,8 @@
#include "cajun/elements.h"
+#include "requestbroker/RequestBroker.h"
+
class Thumbnail;
class SaveInfo;
class SaveFile;
@@ -126,7 +128,8 @@ public:
RequestStatus AddComment(int saveID, std::string comment);
- VideoBuffer * GetAvatar(std::string username);
+ //Retrieves a "UserInfo" object
+ RequestBroker::Request * GetUserInfoAsync(std::string username);
unsigned char * GetSaveData(int saveID, int saveDate, int & dataLength);
std::vector<unsigned char> GetSaveData(int saveID, int saveDate);
diff --git a/src/client/UserInfo.h b/src/client/UserInfo.h
new file mode 100644
index 0000000..edd6659
--- /dev/null
+++ b/src/client/UserInfo.h
@@ -0,0 +1,22 @@
+#ifndef USERINFO_H_
+#define USERINFO_H_
+
+#include <string>
+
+class UserInfo
+{
+public:
+ int ID;
+ int Age;
+ std::string Username;
+ std::string Biography;
+ UserInfo(int id, int age, std::string username, std::string biography):
+ ID(id),
+ Age(age),
+ Username(username),
+ Biography(biography)
+ { }
+};
+
+
+#endif /* USER_H_ */
diff --git a/src/client/requestbroker/APIRequest.cpp b/src/client/requestbroker/APIRequest.cpp
new file mode 100644
index 0000000..71d683f
--- /dev/null
+++ b/src/client/requestbroker/APIRequest.cpp
@@ -0,0 +1,77 @@
+#include <iostream>
+#include <typeinfo>
+#include <cstdlib>
+#include "APIRequest.h"
+#include "client/HTTP.h"
+#include "APIResultParser.h"
+
+APIRequest::APIRequest(std::string url, APIResultParser * parser, ListenerHandle listener):
+ RequestBroker::Request(API, listener)
+{
+ HTTPContext = NULL;
+ Parser = parser;
+ URL = url;
+}
+
+RequestBroker::ProcessResponse APIRequest::Process(RequestBroker & rb)
+{
+ if(HTTPContext)
+ {
+ if(http_async_req_status(HTTPContext))
+ {
+ char * data;
+ int status, data_size;
+ data = http_async_req_stop(HTTPContext, &status, &data_size);
+
+ if (status == 200 && data)
+ {
+ void * resultObject = Parser->ProcessResponse((unsigned char *)data, data_size);
+ free(data);
+
+ if(resultObject)
+ {
+ this->ResultObject = resultObject;
+ rb.requestComplete(this);
+ return RequestBroker::Finished;
+ }
+ else
+ {
+ std::cout << typeid(*this).name() << " Request for " << URL << " could not be parsed" << status << std::endl;
+ return RequestBroker::Failed;
+ }
+ }
+ else
+ {
+//#ifdef DEBUG
+ std::cout << typeid(*this).name() << " Request for " << URL << " failed with status " << status << std::endl;
+//#endif
+ if(data)
+ free(data);
+
+ return RequestBroker::Failed;
+ }
+ }
+ }
+ else
+ {
+ std::cout << typeid(*this).name() << " New Request for " << URL << std::endl;
+ HTTPContext = http_async_req_start(NULL, (char *)URL.c_str(), NULL, 0, 0);
+ //RequestTime = time(NULL);
+ }
+ return RequestBroker::OK;
+}
+
+APIRequest::~APIRequest()
+{
+ delete Parser;
+}
+
+void APIRequest::Cleanup()
+{
+ Request::Cleanup();
+ if(ResultObject)
+ {
+ Parser->Cleanup(ResultObject);
+ ResultObject = NULL;
+ }
+} \ No newline at end of file
diff --git a/src/client/requestbroker/APIRequest.h b/src/client/requestbroker/APIRequest.h
new file mode 100644
index 0000000..2d41eb6
--- /dev/null
+++ b/src/client/requestbroker/APIRequest.h
@@ -0,0 +1,15 @@
+#include "RequestBroker.h"
+
+class APIResultParser;
+class APIRequest: public RequestBroker::Request
+{
+public:
+ APIResultParser * Parser;
+ std::string URL;
+ void * HTTPContext;
+ APIRequest(std::string url, APIResultParser * parser, ListenerHandle listener = ListenerHandle(0, 0));
+ virtual RequestBroker::ProcessResponse Process(RequestBroker & rb);
+ virtual ~APIRequest();
+ virtual void Cleanup();
+};
+
diff --git a/src/client/requestbroker/APIResultParser.h b/src/client/requestbroker/APIResultParser.h
new file mode 100644
index 0000000..40c7512
--- /dev/null
+++ b/src/client/requestbroker/APIResultParser.h
@@ -0,0 +1,16 @@
+#ifndef APIRESULTPARSER_H
+#define APIRESULTPARSER_H
+
+class APIResultParser
+{
+public:
+ //Process the raw API response into a result object to be returned to the requester
+ virtual void * ProcessResponse(unsigned char * data, int dataLength) { return 0; }
+
+ //A method to clean up the result of ProcessResponse in the event of a callback failure in APIRequest/RequestBroker
+ virtual void Cleanup(void * objectPtr) { }
+
+ virtual ~APIResultParser() { }
+};
+
+#endif \ No newline at end of file
diff --git a/src/client/requestbroker/RequestBroker.cpp b/src/client/requestbroker/RequestBroker.cpp
index 68427dc..cfa1294 100644
--- a/src/client/requestbroker/RequestBroker.cpp
+++ b/src/client/requestbroker/RequestBroker.cpp
@@ -114,6 +114,18 @@ void RequestBroker::RetrieveAvatar(std::string username, int width, int height,
RetrieveImage(urlStream.str(), width, height, tListener);
}
+void RequestBroker::Start(Request * request, RequestListener * tListener)
+{
+ ListenerHandle handle = AttachRequestListener(tListener);
+
+ request->Listener = handle;
+ pthread_mutex_lock(&requestQueueMutex);
+ requestQueue.push_back(request);
+ pthread_mutex_unlock(&requestQueueMutex);
+
+ assureRunning();
+}
+
void RequestBroker::RetrieveImage(std::string imageUrl, int width, int height, RequestListener * tListener)
{
ListenerHandle handle = AttachRequestListener(tListener);
diff --git a/src/client/requestbroker/RequestBroker.h b/src/client/requestbroker/RequestBroker.h
index 003ac37..4c31e89 100644
--- a/src/client/requestbroker/RequestBroker.h
+++ b/src/client/requestbroker/RequestBroker.h
@@ -16,6 +16,7 @@ typedef std::pair<int, RequestListener*> ListenerHandle;
class RequestBroker: public Singleton<RequestBroker>
{
friend class ImageRequest;
+ friend class APIRequest;
friend class ThumbRenderRequest;
public:
class Request;
@@ -55,6 +56,7 @@ public:
void RetrieveThumbnail(int saveID, int saveDate, int width, int height, RequestListener * tListener);
void RetrieveThumbnail(int saveID, int width, int height, RequestListener * tListener);
void RetrieveAvatar(std::string username, int width, int height, RequestListener * tListener);
+ void Start(Request * request, RequestListener * tLIstener);
bool CheckRequestListener(ListenerHandle handle);
ListenerHandle AttachRequestListener(RequestListener * tListener);
@@ -63,7 +65,7 @@ public:
class Request
{
public:
- enum RequestType { ThumbnailRender, Image };
+ enum RequestType { ThumbnailRender, Image, API };
RequestType Type;
void * ResultObject;
ListenerHandle Listener;
diff --git a/src/game/GameController.cpp b/src/game/GameController.cpp
index 017aa58..1493b39 100644
--- a/src/game/GameController.cpp
+++ b/src/game/GameController.cpp
@@ -17,6 +17,7 @@
#include "GameModelException.h"
#include "simulation/Air.h"
#include "elementsearch/ElementSearchActivity.h"
+#include "profile/ProfileActivity.h"
#include "colourpicker/ColourPickerActivity.h"
#include "update/UpdateActivity.h"
#include "Notification.h"
@@ -1067,8 +1068,15 @@ void GameController::OpenLocalBrowse()
void GameController::OpenLogin()
{
- loginWindow = new LoginController();
- ui::Engine::Ref().ShowWindow(loginWindow->GetView());
+ if(Client::Ref().GetAuthUser().ID)
+ {
+ new ProfileActivity(Client::Ref().GetAuthUser().Username);
+ }
+ else
+ {
+ loginWindow = new LoginController();
+ ui::Engine::Ref().ShowWindow(loginWindow->GetView());
+ }
}
void GameController::OpenElementSearch()
diff --git a/src/options/OptionsController.cpp b/src/options/OptionsController.cpp
index b789c1f..17c42f4 100644
--- a/src/options/OptionsController.cpp
+++ b/src/options/OptionsController.cpp
@@ -54,6 +54,11 @@ void OptionsController::SetFullscreen(bool fullscreen)
model->SetFullscreen(fullscreen);
}
+void OptionsController::SetShowAvatars(bool showAvatars)
+{
+ model->SetShowAvatars(showAvatars);
+}
+
void OptionsController::SetScale(bool scale)
{
if(scale)
diff --git a/src/options/OptionsController.h b/src/options/OptionsController.h
index f76459c..481f9d2 100644
--- a/src/options/OptionsController.h
+++ b/src/options/OptionsController.h
@@ -27,6 +27,7 @@ public:
void SetFullscreen(bool fullscreen);
void SetScale(bool scale);
void SetFastQuit(bool fastquit);
+ void SetShowAvatars(bool showAvatars);
void Exit();
OptionsView * GetView();
virtual ~OptionsController();
diff --git a/src/options/OptionsModel.cpp b/src/options/OptionsModel.cpp
index fbfe2a0..8ca2a30 100644
--- a/src/options/OptionsModel.cpp
+++ b/src/options/OptionsModel.cpp
@@ -124,6 +124,17 @@ void OptionsModel::SetFastQuit(bool fastquit)
notifySettingsChanged();
}
+bool OptionsModel::GetShowAvatars()
+{
+ return Client::Ref().GetPrefBool("ShowAvatars", true);
+}
+
+void OptionsModel::SetShowAvatars(bool state)
+{
+ Client::Ref().SetPref("ShowAvatars", state);
+ notifySettingsChanged();
+}
+
void OptionsModel::notifySettingsChanged()
{
for(int i = 0; i < observers.size(); i++)
diff --git a/src/options/OptionsModel.h b/src/options/OptionsModel.h
index b0867c1..1fdf372 100644
--- a/src/options/OptionsModel.h
+++ b/src/options/OptionsModel.h
@@ -23,6 +23,8 @@ public:
void SetNewtonianGravity(bool state);
bool GetWaterEqualisation();
void SetWaterEqualisation(bool state);
+ bool GetShowAvatars();
+ void SetShowAvatars(bool state);
int GetAirMode();
void SetAirMode(int airMode);
int GetEdgeMode();
diff --git a/src/options/OptionsView.cpp b/src/options/OptionsView.cpp
index 5bbd608..70aeba5 100644
--- a/src/options/OptionsView.cpp
+++ b/src/options/OptionsView.cpp
@@ -5,7 +5,7 @@
#include "interface/DropDown.h"
OptionsView::OptionsView():
- ui::Window(ui::Point(-1, -1), ui::Point(300, 290)){
+ ui::Window(ui::Point(-1, -1), ui::Point(300, 310)){
ui::Label * tempLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 14), "Simulation Options");
tempLabel->SetTextColour(style::Colour::InformationTitle);
@@ -176,6 +176,21 @@ OptionsView::OptionsView():
AddComponent(tempLabel);
AddComponent(fastquit);
+ class ShowAvatarsAction: public ui::CheckboxAction
+ {
+ OptionsView * v;
+ public:
+ ShowAvatarsAction(OptionsView * v_){ v = v_; }
+ virtual void ActionCallback(ui::Checkbox * sender){ v->c->SetShowAvatars(sender->GetChecked()); }
+ };
+
+ showAvatars = new ui::Checkbox(ui::Point(8, 270), ui::Point(Size.X-6, 16), "Show Avatars", "");
+ showAvatars->SetActionCallback(new ShowAvatarsAction(this));
+ tempLabel = new ui::Label(ui::Point(showAvatars->Position.X+Graphics::textwidth(showAvatars->GetText().c_str())+20, showAvatars->Position.Y), ui::Point(Size.X-28, 16), "\bg- Disable if you have a slow connection");
+ tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
+ AddComponent(tempLabel);
+ AddComponent(showAvatars);
+
class CloseAction: public ui::ButtonAction
{
public:
@@ -206,6 +221,7 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
scale->SetChecked(sender->GetScale());
fullscreen->SetChecked(sender->GetFullscreen());
fastquit->SetChecked(sender->GetFastQuit());
+ showAvatars->SetChecked(sender->GetShowAvatars());
}
void OptionsView::AttachController(OptionsController * c_)
diff --git a/src/options/OptionsView.h b/src/options/OptionsView.h
index 8d41ba5..4ee254f 100644
--- a/src/options/OptionsView.h
+++ b/src/options/OptionsView.h
@@ -21,6 +21,7 @@ class OptionsView: public ui::Window {
ui::Checkbox * scale;
ui::Checkbox * fullscreen;
ui::Checkbox * fastquit;
+ ui::Checkbox * showAvatars;
public:
OptionsView();
void NotifySettingsChanged(OptionsModel * sender);
diff --git a/src/preview/PreviewView.cpp b/src/preview/PreviewView.cpp
index d9319f8..e04295a 100644
--- a/src/preview/PreviewView.cpp
+++ b/src/preview/PreviewView.cpp
@@ -67,6 +67,8 @@ PreviewView::PreviewView():
}
};
+ showAvatars = Client::Ref().GetPrefBool("ShowAvatars", true);
+
favButton = new ui::Button(ui::Point(50, Size.Y-19), ui::Point(51, 19), "Fav");
favButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; favButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
favButton->SetIcon(IconFavourite);
diff --git a/src/profile/ProfileActivity.cpp b/src/profile/ProfileActivity.cpp
new file mode 100644
index 0000000..1b3a1f8
--- /dev/null
+++ b/src/profile/ProfileActivity.cpp
@@ -0,0 +1,68 @@
+#include <algorithm>
+#include "ProfileActivity.h"
+#include "interface/Button.h"
+#include "interface/Textbox.h"
+#include "interface/Label.h"
+#include "interface/Keys.h"
+#include "Style.h"
+#include "client/Client.h"
+#include "client/requestbroker/RequestListener.h"
+
+ProfileActivity::ProfileActivity(std::string username) :
+ WindowActivity(ui::Point(-1, -1), ui::Point(236, 302))
+{
+ bool editable = Client::Ref().GetAuthUser().ID && Client::Ref().GetAuthUser().Username == username;
+
+
+ class CloseAction: public ui::ButtonAction
+ {
+ ProfileActivity * a;
+ public:
+ CloseAction(ProfileActivity * a) : a(a) { }
+ void ActionCallback(ui::Button * sender_)
+ {
+ a->Exit();
+ }
+ };
+
+ class SaveAction: public ui::ButtonAction
+ {
+ ProfileActivity * a;
+ public:
+ SaveAction(ProfileActivity * a) : a(a) { }
+ void ActionCallback(ui::Button * sender_)
+ {
+ }
+ };
+
+ ui::Button * closeButton = new ui::Button(ui::Point(0, Size.Y-15), ui::Point((Size.X/2)+1, 15), "Close");
+ closeButton->SetActionCallback(new CloseAction(this));
+
+ if(editable)
+ {
+ ui::Button * saveButton = new ui::Button(ui::Point(Size.X/2, Size.Y-15), ui::Point(Size.X/2, 15), "Save");
+ saveButton->SetActionCallback(new SaveAction(this));
+ AddComponent(saveButton);
+ }
+
+ AddComponent(closeButton);
+
+ RequestBroker::Ref().Start(Client::Ref().GetUserInfoAsync(username), this);
+}
+
+void ProfileActivity::OnResponseReady(void * userDataPtr)
+{
+ exit(0);
+}
+
+void ProfileActivity::OnDraw()
+{
+ Graphics * g = ui::Engine::Ref().g;
+ g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3);
+ g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255);
+}
+
+ProfileActivity::~ProfileActivity() {
+ RequestBroker::Ref().DetachRequestListener(this);
+}
+
diff --git a/src/profile/ProfileActivity.h b/src/profile/ProfileActivity.h
new file mode 100644
index 0000000..a4648e9
--- /dev/null
+++ b/src/profile/ProfileActivity.h
@@ -0,0 +1,17 @@
+#ifndef PROFILEACTIVITY_H_
+#define PROFILEACTIVITY_H_
+
+#include <string>
+#include "Activity.h"
+#include "client/requestbroker/RequestListener.h"
+#include "interface/Window.h"
+
+class ProfileActivity: public WindowActivity, public RequestListener {
+public:
+ ProfileActivity(std::string username);
+ virtual ~ProfileActivity();
+ virtual void OnResponseReady(void * userDataPtr);
+ virtual void OnDraw();
+};
+
+#endif /* PROFILEACTIVITY_H_ */