vala: manipulating (gstreamer) GLib.Value - gstreamer

I've written the small vala program below, and I don't know how
to manipulate the GLib.Value types, see the code below :
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-level.html
using Gst;
void application_message(Gst.Bus bus, Gst.Message msg) {
var s = msg.get_structure();
if(s == null)
return;
string msgtype = s.get_name();
if(msgtype != "level")
return;
GLib.Value rms = s.get_value("rms");
GLib.Value st = s.get_value("stream-time");
// according to the doc here : http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-level.html
// "rms" is apparently a "GValueArray of gdouble"
// and
// "st" is a GstClockTime, which is a "typedef guint64 GstClockTime"
// I want to create a string representation of the two, ex:
// 72374237490234, [0.234234,0,424234234,0.423423423,0.5345345, ...]
// and I'm clueless as to how to do the conversions or typecasts...
}
void main (string[] args) {
Gst.init (ref args);
try {
var pipeline = Gst.parse_launch(
"pulsesrc device=\"alsa_input.usb-046d_08c9_674634A4-02-U0x46d0x8c9.analog-mono\" ! " +
"level name=wavelevel interval=10000000 ! " +
"wavenc ! filesink location=audioz.wav"
);
var bus = pipeline.get_bus();
bus.add_signal_watch();
bus.message.connect(application_message);
// Set pipeline state to PLAYING
pipeline.set_state (State.PLAYING);
// Creating and starting a GLib main loop
new MainLoop ().run ();
}
catch(Error e) {
print("%s\n", e.message);
}
}
UPDATE :
THe doc for GLib.Value is here : http://www.valadoc.org/#!api=gobject-2.0/GLib.Value
calling strdup_contents() is somewhat satisfactory, but I'd like to manipulate the array in rms,
printl(rms.type().name()) tells me that it's a GstValueList,
so I'd thing that I should cast it to this :
http://www.valadoc.org/#!api=gstreamer-1.0/Gst.ValueList
but vala seems to know nothing of the type Gst.ValueList...

Vala makes working with GLib.Value very easy, it will implicitly convert between GLib.Value and the native types. Throwing GLib.StringBuilder into the mix to build your array, something like this (untested) should do the trick:
GLib.StringBuilder s = new GLib.StringBuilder ();
s.append (((uint64) st).to_string ());
s.append (",[");
{
bool first = true;
foreach ( unowned GLib.Value value in rms.values ) {
if (!first) {
s.append_c (',');
} else {
first = false;
}
s.append (((double) value).to_string ());
}
}
s.append_c (']');

Related

Bukkit Player check achievements

I don't know what I should put into player.getAdvancementProgress(Here).
if (player.getAdvancementProgress().isDone()) {
}
Maybe someone knows something?
You should use an Advancement object, specially the advancement that you are looking for informations.
You can get it with Bukkit.getAdvancement(NamespacedKey.fromString("advancement/name")) where advancement/name can be nether/all_potions for example. You can get all here (column: "Resource location). If you are getting it from command, I suggest you to add tab complete.
Example of TAB that show only not-done success :
#Override
public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] arg) {
List<String> list = new ArrayList<>();
if(!(sender instanceof Player))
return list;
Player p = (Player) sender;
String prefix = arg[arg.length - 1].toLowerCase(Locale.ROOT); // the begin of the searched advancement
Bukkit.advancementIterator().forEachRemaining((a) -> {
AdvancementProgress ap = p.getAdvancementProgress(a);
if((prefix.isEmpty() || a.getKey().getKey().toLowerCase().startsWith(prefix)) && !ap.isDone() && !a.getKey().getKey().startsWith("recipes"))
list.add(a.getKey().getKey());
});
return list;
}
Then, in the command you can do like that:
#Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arg) {
if(!(sender instanceof Player)) // not allowed for no-player
return false;
Player p = (Player) sender;
// firstly: try to get advancement
Advancement a = Bukkit.getAdvancement(NamespacedKey.fromString(arg[0]));
if(a == null)
a = Bukkit.getAdvancement(NamespacedKey.minecraft(arg[0]));
if(a == null) // can't find it
p.sendMessage(ChatColor.RED + "Failed to find success " + arg[0]);
else { // founded :
AdvancementProgress ap = p.getAdvancementProgress(a);
p.sendMessage(ChatColor.GREEN + "Achivement " + a.getKey().getKey() + " stay: " + ChatColor.YELLOW + String.join(", ", ap.getRemainingCriteria().stream().map(this::getCleaned).collect(Collectors.toList())));
}
return false;
}
private String getCleaned(String s) { // this method is only to make content easier to read
String[] args = s.split("/");
return args[args.length - 1].replace(".png", "").replace(".jpg", "").replace("minecraft:", "").replace("_", " ");
}
Else, if you want to get all advancements, you should use Bukkit.advancementIterator().

Unreal engine c++ write delegate OnScreenshotCaptured

I am new to C++. I've wrote code in C# and PHP.Since I am using Unreal engine I am trying to learn C++. For my project I need to make a screenshot in-game and show it immediately so I want to get it as a texture.
I made a blueprint node which calls this function i've made:
void UMyBlueprintFunctionLibrary::TakeScreenshot()
{
FScreenshotRequest::RequestScreenshot(true);
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Tried to take screenshot");
}
When I hover my mouse above RequestScreenshot I see the following pop-up:
"Screenshot can be read from memory by subscribing to the viewsport OnScreenshopCaptured delegate"
So that is what I try to do but I have no idea how I looked up this:
https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/Engine/UGameViewportClient/OnScreenshotCaptured/
Can someone tell me how to implement this and how you see/know how to implement it?
I have an alternative, no delegate, but FRenderTarget::ReadPixel() to some buffer you allocated, by implementing your own UGameViewportClient (inherit it), and overriding Draw() function.
I'll show the essential codes, but not complete.
void UMyGameViewportClient::Draw(FViewport* Viewport, FCanvas* SceneCanvas)
{
Super::Draw(Viewport, SceneCanvas);
if (any_condition_you_need) {
CaptureFrame();
}
}
void UMyGameViewportClient::CaptureFrame()
{
if (!Viewport) {
return;
}
if (ViewportSize.X == 0 || ViewportSize.Y == 0) {
return;
}
ColorBuffer.Empty(); // Declare this in header as TArray<FColor>
if (!Viewport->ReadPixels(ColorBuffer, FReadSurfaceDataFlags(),
FIntRect(0, 0, ViewportSize.X, ViewportSize.Y)))
{
return;
}
SaveThumbnailImage();
}
void UMyGameViewportClient::SaveThumbnailImage()
{
IImageWrapperModule& wrappermodule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
auto wrapper_ptr = wrappermodule.CreateImageWrapper(EImageFormat::PNG);
for (int i = 0; i < ColorBuffer.Num(); i++)
{
auto ptr = &ColorBuffer[i];
auto r = ptr->R;
auto b = ptr->B;
ptr->R = b;
ptr->B = r;
ptr->A = 255;
} // not necessary, if you like bgra, just change the following function argument to ERGBFormat::BGRA
wrapper_ptr->SetRaw(&ColorBuffer[0], ColorBuffer.Num() * 4,
ViewportSize.X, ViewportSize.Y, ERGBFormat::RGBA, 8);
FFileHelper::SaveArrayToFile(wrapper_ptr->GetCompressed(), *ThumbnailFile);
}

std::map pass by reference Pointer to Object

I'm coding a plugin for XPLANE10 which gets a MSG from ROS.
My IDE is QTcreator 4.1.0 based QT 5.7.0 for Ubuntu 64 Bit. I would like to use C++11 Standards
My code explained
The main initializes ROS and creates a map -> container.
ROS spins in a loop till my GUI sends a MSG where my AirPlane should fly.
The MSG contains 3 floats(phi, theta, psi) where "phi" is the AirPlane ID, theta contains the ID for my ETA(Estimated Time of Arrival)
and psi contains the ID for my pose All of the IDs are saved in the ParameterServer(lookuptable).
So at the beginning i look up the activeAirplanes which returns a vector . I would like to store them in a map where the key is the AirCraft ID and the second param is an instance of the Object.
So i have initialized the for example(looked in container while debugging):
[0] first = 1 // Airplane ID1
[0] second = new CObject(freq)
[1] first = 2 // Airplane ID2
[1] second = new CObject(freq)
If i get a MSG from GUI
phi = 1
theta=2
psi=3
,
ROS will callback
MSG(....std::map<i32, CObject> &container)
// if phi is 1 so use the mapkey 1 and trigger the method do_stuff from CObject
do_stuff(phi, theta, psi,freq)
I would like to call the in a function from main
int getPlanes(std::map<i32,CObject>& container)
{
...
getActiveAirplanesFromServer(activePlanes);
}
First Question:
How do i pass the container to my callback?
Second Question:
How do i parallelize do_stuff() so my callback will return to main and i'm able to command more aircrafts while the others are calculated?
Third Question:
How would be the correct syntax for getPlanes to pass the container by reference so getPlanes() can edit it?
Fourth Question:
Is there a difference between
std::map<i32,CObject*> map
std::map<i32,CObject>* map
and
std::map<i32,CObject*>::iterator it=container->begin();
std::map<i32,CObject*>::iterator* it=container->begin();
If yes, what do i want ? #4Solved
// I have to edit stuff 'cause of some restrictions in my company.
#include "Header.h"
int main()
{
f64 freq = 10;
std::map<i32, CObject>* container;
std::map<i32,CObject>::iterator* it=container->begin();
// ROS
if(!ros::isInitialized())
{
int rosargc = 0;
char** rosargv = NULL;
ros::init(rosargc, rosargv, "MainNode");//), ros::init_options::AnonymousName);
}
else
{
printf("Ros has already been initialized.....\n");
}
ros::NodeHandle* mainNodeHandle=new ros::NodeHandle;
ros::AsyncSpinner spinner(2);
ParameterServer * ptrParam= new ParameterServer(mainNodeHandle);
ros::Subscriber airSub=mainNodeHandle->subscribe<own_msgs::ownStruct>("/MSG",
1000,
boost::bind(MSG,
_1,
freq,
container));
std::vector<i32> activePlanes;
i32 retVal=0;
retVal += ptrParam-> ParameterServer::getActiveAirplanesFromServer(activePlanes);
if (retVal == 0 && activePlanes.size()>0)
{
for (u32 j =0; j <activePlanes.size(); j++)
{
container->insert (std::pair<i32,CObject> (activePlanes[j] , new CObject(freq)));
}
}
while (ros::ok())
{
spinner.start(); //spinnt sehr viel :-)
ros::waitForShutdown ();
}
std::cout<<"ENDE"<<std::endl;
int retval = 1;
return retval;
}
void MSG(const own_msgs::ownStruct<std::allocator<void> >::ConstPtr &guiMSG,
f64 freq,
std::map<i32, CObject> &container)
{
if ((guiMSG->phi != 0) && (guiMSG->theta != 0) && (guiMSG->psi != 0))
{
std::string alpha = std::to_string(guiMSG->phi)+std::to_string(guiMSG->theta)+to_string(guiMSG->psi);
container.at(guiMSG->phi) -> do_stuff(guiMSG->phi,guiMSG->theta,guiMSG->psi, freq);
}
else
{
std::cout<<" Did not receive anything\n"<<endl;
}
}
void do_stuff(...)
{
//copy the IDs to private Member of this single Object
//setROS() for this single Object
//callback the current AC pose via ID from XPLANE
//callback the wished AC pose via ID from ParamServer
// do some calculations for optimum flight path
// publish the Route to XPlane
}
EDIT::
Problem is i get it to compile now and if debug it and set a breakpoint at :
void MSG(const own_msgs::ownStruct<std::allocator<void> >::ConstPtr &guiMSG,f64 freq,std::map<i32, CObject*> &container)
{
..
/*->*/ container.at(guiMSG->)...
}
The Container remains empty.
So i read some stuff about pointers and i saw my errors..
I confused * and &
if i want to pass the adress of a variable i have to write like
int main()
{
int a = 0;
AddTwo(&a)
cout<<a<<endl; // Output: 2
}
void AddTwo(int* a)
{
a+=2;
}

Qt and GoogleMaps - duration type

I use this code to getData from javascript:
const QVariant myvar = this->page()->mainFrame()->
evaluateJavaScript("measureDistance("+QString::fromStdString(prev->marker_id)+","+QString::fromStdString(stop->marker_id+");"));
bool ok;
const int myint = myvar.toInt(&ok);
if (!ok)
qWarning() << "Error getting int from JS";
qDebug() << myint;
getMapTimeDistance(location, QString::fromStdString(prev->getName()), stop, 10);
And in javascript the last line is:
function measureDistance(m1, m2) {
var wp = new Array();
var lstart = new google.maps.LatLng(markers[m1].position);
var lend = new google.maps.LatLng(markers[m2].position);
var request = {
origin : lstart,
destination : lend,
waypoints : [],
optimizeWaypoints: true,
travelMode : google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status== google.maps.DirectionsStatus.OK) {
response.routes[0].legs[0].duration.text;
} else {
document.getElementById('locationD').value = "drawRouteBad";
}
});
}
Do you know why this code won't work for me? I've tried different combinations of types, but nothing helped. Probably I don't know what type is javasscripts value. Maybe I should pass it to the qt in different way?
response.routes[0].legs[0].duration.value; is coming from the Google Maps API v3 Directions Service (per your last question. That service is asynchronous, you can't return anything from the call to it, you have to use any data you need inside the callback function (when it has been returned from the server and is available).

How do I separate String and Integer variables in same one resources

I'm bit hardly to separate the variable String and Integer to passed in "if()" statement.
I have two variable "buffString" and "buffInteger", when i put the buffString in the "if()" statement, I wanna to take String "Data Stop" in the buffString variable, and then set to the RichEdit to showing "Data Stop", but the problem when the buffInteger filled same as buffString its error come in the process. and compilers say "Data Stop" is not valid Integer value
void __fastcall TfrmServer::ComPort1RxChar(TObject *Sender, int Count)
{
String buff;
ComPort1->ReadStr(buff,255);
BUF_RX->Data_suhu = buff; // source
int bufferInteger;
String bufferString;
try{
if(!buff.IsEmpty())
{
bufferInteger = StrToInt(BUF_RX->Data_suhu);
bufferString = BUF_RX->Data_suhu;
if(bufferString == "Data Stop")
{
ad_log_Serial("AT89S52 -> "+BUF_RX->Data_suhu,clRed);
}
else
{
ad_log_Serial("AT89S52 -> "+IntToStr(bufferInteger),clRed);
txtTemp->Text = IntToStr(bufferInteger).c_str();
}
LedRx->States->Items[0]->Value = true;
}
else
{
LedRx->States->Items[0]->Value = false;
}
}__finally
{
delete(BUF_RX);
}
}
what should i do this code?
Move your bufferInteger assignment to the else clause:
else
{
bufferInteger = StrToInt(BUF_RX->Data_suhu);
ad_log_Serial("AT89S52 -> "+IntToStr(bufferInteger),clRed);
txtTemp->Text = IntToStr(bufferInteger).c_str();
}
Since it's not being used outside it, there's no point in having it there. And assuming that any string that's not "Data Stop" is supposed to represent an integer, the code will not fail this way.