I am developing a mobile game using Cocos2D-x engine for android platform and i want to integrate GPGS on it.
I achieved to show leaderboards, but there is a little annoying problem. When leaderboard is visible, if i go background and then come back to app, the gamescene goes to black. I think opengl context being released and doesnt restore again. In my opinion running leaderboard on same activity causes this, the game engine cant understand whats happening there. Whatever, because of this I want to run leaderboard (and also all GPGS things) on a new activity using intent.
Google likes "Providing"
In the reference documents of Google Play Game Services C++ SDK, there is a few unclear/fuzzy explanation about using SetOptionalIntentHandlerForUI method.
"Provide a function that can start a provided UI intent at any point, using startActivityForResult."
What is the mean of "Providing"? What is a provided Intent? How will I use startActivityForResult method? Unfortunately, "using" and "providing methods" are not clear expressions for coding. There is no sample about
using this method in the documents of GPGS for C++. Eventually,
Google's document is so poor and
there is no useful information on the internet. If someone from Google helps me, I will be so happy.
As i understand, I wrote the code like this. But it gives error when starting.
AppActivity.java
public void runGPGSActivity(Intent i) {
startActivityForResult(i,100);
}
AndroidPlatformConfiguration.h (From C++ gpg lib)
typedef std::function<void(jobject)> IntentHandler;
AndroidPlatformConfiguration &SetOptionalIntentHandlerForUI(
IntentHandler intent_handler);
main.cpp (JNI binding, the working code, GPGS runs on same activity )
gpg::AndroidPlatformConfiguration platform_configuration;
platform_configuration.SetActivity(activity);
StateManager::InitServices( ...
main.cpp (JNI binding, GPGS must be run on new activity )
gpg::AndroidPlatformConfiguration platform_configuration;
jclass activityClass = env->FindClass("org/cocos2dx/cpp/AppActivity");
jmethodID jIntentHandlerMethodID = env->GetMethodID(activityClass,"runGPGSActivity","(Landorid/content/Intent;)V");
jobject jIntentHandler = env->NewObject(activityClass, jIntentHandlerMethodID);
gpg::AndroidPlatformConfiguration::IntentHandler mIntentHandler; /*= [](jobject mjIntentHandler){};*/
std::function<void(jobject)> intentHandler = std::bind(mIntentHandler,jIntentHandler);
platform_configuration.SetOptionalIntentHandlerForUI(intentHandler);
platform_configuration.SetActivity(activity);
StateManager::InitServices(
There is no build error, but the application crashes when launching.
03-24 14:12:24.301: A/libc(21352): Fatal signal 6 (SIGABRT) at
0x00005368 (code=-6), thread 21352 (main)
And some links about this issue:
IntentHandler reference
StartActivityForResult reference
/// Thank you in advance. ///
...Yeah I solved the problem, but didn't use IntentHandler method.
I was using this code in my app, to show weekly leaderboard data.
gameServices->Leaderboards().ShowUIBlocking(leaderboardId,gpg::LeaderboardTimeSpan::WEEKLY);
But return value is not void, it is UIStatus (whatever it is)
I've reverted back to this code, app is not going to black screen now. This method returns void, I think I have to catch some callbacks when using ShowUIBlocking method, with that UIStatus thing.
gameServices->Leaderboards().ShowUI(leaderboardId);
But now, I can't benefit from timespan feature of leaderboards.
I am going to research how it can be used. There is no problem for now. But, documentation of SetOptionalIntentHandlerForUI must be written more explicit, for programmers who want to use it.
Related
In windows runtime component project (BackgroundTask c++)
#include "pch.h"
#include "BackgroundTask.h"
using namespace Platform;
namespace SyncBackground {
void BackgroundTask::Run(IBackgroundTaskInstance^ taskInstance) {
_taskInstance = taskInstance;
taskInstance->Canceled += ref new BackgroundTaskCanceledEventHandler(this, &BackgroundTask::OnCanceled);
_deferral = taskInstance->GetDeferral();
OutputDebugString(L"Debug: CPP\r\n");
}
void BackgroundTask::OnCanceled(IBackgroundTaskInstance^ sender, BackgroundTaskCancellationReason reason) {
_deferral->Complete();
}
}
I try ApplicationTrigger from c# project, but OutputDebugString write only one times from first trigger. In the same BackgroundTask C#, Debug.WriteLine() write every trigger.
Then why in c++ do it only one times? And how make it work look like c# (i need send some data and command via trigger)
Thank
I need it still run background
If I understand correctly, you just want to run background tasks indefinitely. If so, even if you don't call TaskDeferral.Complete();, it won't still run background, after a period of time, it will still be terminated. In that case, you can refer to this document to configure. But it mentions if you use it, you can't put an app into the Microsoft Store. If not, please point me out.
I have the following XAML
<MediaPlayerElement x:Name="EmbeddedPlayer" AreTransportControlsEnabled="True" HorizontalAlignment="Stretch" IsDoubleTapEnabled="True" DoubleTapped="OnEmbeddedPlayerDoubleTapped"> </MediaPlayerElement>
According to this official documentation, I should be able to use the available Cast button to cast the video to my TV. The Movies & TV app can does that: When I clicked the cast button in that app, it lists the available targets. But when I do the same thing for my app, it asks me to make sure that the devices are discoverable and no progress ring indicating device searching/discovery was going on. (I am on a Lumia 635.) Once again, I feel the frustration of mismatching between documentation and reality!
Is there a complete working example for video/audio casting?
EDIT: I added the simplified code following the third method for device discovery given in the article:
using namespace Windows::Devices::Enumeration;
MainPage::MainPage()
{
// Other set up
DeviceWatcher ^deviceWatcher;
CastingConnection ^castingConnection;
//Create our watcher and have it find casting devices capable of video casting
deviceWatcher = DeviceInformation::CreateWatcher(CastingDevice::GetDeviceSelector(CastingPlaybackTypes::Video));
//Register for watcher events
deviceWatcher->Added += ref new TypedEventHandler<DeviceWatcher^, DeviceInformation^>(this, &MainPage::DeviceWatcher_Added);
deviceWatcher->Start();
}
void MainPage::DeviceWatcher_Added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ args)
{
Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new DispatchedHandler([args]()
{
//Add each discovered device to our listbox
create_task(CastingDevice::FromIdAsync(args->Id)).then([](CastingDevice^ addedDevice)
{
OutputDebugString(("Found cast device " + addedDevice->FriendlyName + "\n")->Data());
}, task_continuation_context::use_current());
//castingDevicesListBox.Items.Add(addedDevice);
}));
}
As I anticipated, there is no device discovered. There might probably be some extra steps to take care of permission (allow app to discover & cast to devices) etc. that are never specified in the documentation.
Contrary to the documentation, one MUST NOT use MediaPlayerElement but the deprecated MediaElement for casting on mobile. This hint is taken from https://social.msdn.microsoft.com/Forums/en-US/0c37a74f-1331-4fb8-bfdf-3df11d953098/uwp-mediaplayerelement-mediacasting-is-broken-?forum=wpdevelop
This also solves a problem I previously asked about showing video in fullscreen: Fullscreen works like a charm for MediaElement on mobile; but not the supposely upgraded MediaPlayerElement.
I should have realized this obvious fact given that Microsoft already abandoned Windows 10 Mobile.
I know this has already be asked before but unfortunately none of those answers could help me. I have an app that executes bunch of short background tasks in different threads. The code is mostly in C++ with ObjectiveC added to it when necessary (so the code is in .mm file). For execution of background tasks i have roughly following C++ class with constructor and descrtuctor:
class BTask {
UIBackgroundTaskIdentifier taskIden;
public:
BTask(ExpirationHandler *h) {
taskIden = [[[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^ {
h->callback();
[[UIApplication sharedApplication] endBackgroundTask:taskIden];
taskIden = UIBackgroundTaskInvalid;
}];
}
~BTask() {
if (taskIden != UIBackgroundTaskInvalid)
[[UIApplication sharedApplication] endBackgroundTask:taskIden];
}
};
Now, each of my tasks runs in its own thread and has the following structure:
void task(.....) {
BTask btask(...);
//.... do the work of the task
//.... destructor of BTask will call endBackgroundTask
}
So when running, occasionally i get this error when endBackgroundTask is called (as in the title of the question): Can't get background task: no background task exists with identifier 1. The error reproduces only occasionally (1 in 3-4 times) and in the beginning of the application run (so it looks like it is the first task that has the problem) and the problematic identifier somehow is always 1.
My app does not declare any background capabilities.
I m running on iPhone 6s plus simulator, but could also reproduce the problem on other simulator (iPhone 5s).
The code that implements BTask class and the tasks themselves is in static library that is linked to the application (not sure if this makes a difference).
Also note that in my test case, the app is always in the foreground.
Also, i checked that the expiration handler block is never called (which is understandable since the app does not even go into background mode).
From UIApplication reference, it seems that i m doing it correctly and it is allowed to call beginBackgroundTask... and endBackgroundTask concurrently from multiple threads to have many background tasks at any one time, as long as beginBackgroundTask... and endBackgroundTask are paired with the same identifier, which should be the case in my code.
So, so far i have no idea what the problem might be and even tend to think there may be a bug in UIKit.
Any ideas?
I'm trying to get my head around AOP and some Qt Code would really help.
From wikipedia here is some sample code (easy for a Qt/C++ programmer to read):
void transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger)
throws Exception {
logger.info("transferring money...");
if (! checkUserPermission(user)){
logger.info("User has no permission.");
throw new UnauthorizedUserException();
}
if (fromAcc.getBalance() < amount) {
logger.info("Insufficient Funds, sorry :( ");
throw new InsufficientFundsException();
}
fromAcc.withdraw(amount);
toAcc.deposit(amount);
//get database connection
//save transactions
logger.info("Successful transaction. :) ");
}
And then "aspectized":
void transfer(Account fromAcc, Account toAcc, int amount) throws Exception {
if (fromAcc.getBalance() < amount) {
throw new InsufficientFundsException();
}
fromAcc.withdraw(amount);
toAcc.deposit(amount);
}
aspect Logger
{
void Bank.transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger)
{
logger.info("transferring money...");
}
void Bank.getMoneyBack(User user, int transactionId, Logger logger)
{
logger.info("User requested money back");
}
// other crosscutting code...
}
Qt has signals and slots to decouple objects. But I still need to emit signals.
So: Can this be done with Qt or do I need some special framework/preprocessors as referenced in the wikipedia article?
I have a feeling that there must be some trick since Qt uses the Meta Object Compiler and some functionality might be "injected" with dynamic methods.... just spit-balling here ;)
Edit: To give a better context: I really like the dynamic aspects (power) of the Qt meta object with signals and slots and would like to keep a Qt feel to it. Thus, my idea is to make use of slots (or signals) as point cuts. For example:
If I define slot Bank::transfer(...) and then signal Bank::OnBeforeTranfer() and signal Bank::OnAfterTransfer(). If I then connect them to other aspects say Security::transfer() and Logger::transfer() (all QObjects) I can block calls (like fail OnBeforeTransfer).
But, if we then take it to the next evolution to get less and cleaner code I would like to get rid of the OnXXXX signals and connect the Bank::transfer slot to Security::transfer slot and Logger::transfer. Anything dynamic in Qt? : Like order of calling slots and and preventing next call in the "slot chain"?
This whole context can still be considered AOP right? I'm trying to stick to "method level point cuts" or am I totally beside the point here?
In what language are you planning to use Qt? I recently had to build a simple GUI in Qt around a python script and used the AOP python package Aspyct to do some quick before and after stuff. Qt is event-driven programming, I'd say get familiar with the Qt basics, many things are similar to AOP-style operations and then find some AOP libraries for the language you plan to use Qt in.
Another AOP framework you may consider using is AspectC++. I've played with it a bit and it seems to work quite well. They even have a whitepaper on the site that describes how AspectC++ can be used with Qt.
If you want to stay within the Qt framework, you could take a look at the State Machine Framework. (And get rid of the exceptions :)
Then you could just connect the Logger to state change events.
I have a Win32 C++ program that validates user input and updates the UI with status information and options. Currently it is written like this:
void ShowError() {
SetIcon(kError);
SetMessageString("There was an error");
HideButton(kButton1);
HideButton(kButton2);
ShowButton(kButton3);
}
void ShowSuccess() {
SetIcon(kError);
std::String statusText (GetStatusText());
SetMessageString(statusText);
HideButton(kButton1);
HideButton(kButton2);
ShowButton(kButton3);
}
// plus several more methods to update the UI using similar mechanisms
I do not likes this because it duplicates code and causes me to update several methods if something changes in the UI.
I am wondering if there is a design pattern or best practice to remove the duplication and make the functionality easier to understand and update.
I could consolidate the code inside a config function and pass in flags to enable/disable UI items, but I am not convinced this is the best approach.
Any suggestions and ideas?
I would recommend Observer Pattern and State Pattern, when an validation happens to be successful or unsuccessful, attached buttons can change their state according to information provided in "notify" method. Please refer to GoF's book for further details, or just google them. Hope it helps.