I'm very new to unity. I'm trying to play in unity the example room scene from livekit https://github.com/livekit/client-sdk-unity-web (Livekit enables webRTC for unity WebGL project) but I can not because I receive an EntryPointNotFoundException whenever there is a DLLImport Internal in the code.
Here is an example of the error I get :
Here is an extract code from JSRef where line 92 is:
[Preserve]
internal JSRef(JSHandle handle)
{
NativeHandle = handle;
// We add the instantiated object into the cache se we can retrieve it later if not garbage collected.
// Note that if JSRef has been garbage collected, it doesn't mean that the key doesn't exists on this map ( Finalizer is unpredictable )
Cache[handle.DangerousGetHandle()] = new WeakReference<JSRef>(this);
}
internal JSRef() : this(JSNative.NewRef()) //this is line 92
{
}
And the code where newRef is in the file JSNative:
[DllImport("__Internal")]
internal static extern JSHandle NewRef();
and this is the code for JSHandle :
public class JSHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private JSHandle() : base(true)
{
}
internal JSHandle(IntPtr ptr, bool ownsHandle) : base(ownsHandle)
{
SetHandle(ptr);
}
protected override bool ReleaseHandle()
{
return JSNative.RemRef(handle);
}
}
Please help me, I've looked on Google and other posts on StackOverflow but I don't know what to do....
Related
I've written myself a helper class to handle the loading and unloading of addressables, but I can't determine if it is working correctly as I don't see the results I'm expecting (f.e. memory is not the same before loading when unloading, though it does go down).
I profiled with the Memory Profiler and got the following results.
The Event Viewer releases the resources correctly (there's only the InitializationObjectsOperation where I don't know what it is and how to get rid of it, I'm not using InstantiateAsync).
The class has the following methods for loading and unloading (coupled with an object pool that instantiates a pool whenever a game object addressable is loaded by using the result of the handle, and destroy the game objects and the pool when unloading is required).
private IEnumerator LoadObjects<TObject>(IList<object> keys, Addressables.MergeMode mergeMode = Addressables.MergeMode.Union)
{
var locations = Addressables.LoadResourceLocationsAsync(keys, mergeMode, typeof(TObject));
yield return locations;
foreach (var location in locations.Result)
{
if (_allObjectAsyncOperationHandlesByLocationKey.ContainsKey(location.PrimaryKey))
{
continue;
}
var asyncOperationHandle = Addressables.LoadAssetAsync<TObject>(location);
asyncOperationHandle.Completed += obj =>
{
if (obj.Status == AsyncOperationStatus.Succeeded)
{
_allObjectAsyncOperationHandlesByLocationKey.Add(location.PrimaryKey, obj);
_allAddressableLocationKeysByObject.Add(obj.Result, location.PrimaryKey);
if (obj.Result is GameObject gameObj) OnGameObjectLoaded?.Invoke(gameObj);
}
else
{
// TODO:
}
};
}
Addressables.Release(locations);
}
I am trying to implement skill based matchmaking using Photon in Unity. It seems
I got most of this code from the documentation and it works but not well.
The problem is that you can't use JoinOrCreate() with the sql lobby type so my logic here is try and find a room, if it fails create one.
void init()
{
_client = Game.Context.GetComponent<SocketConnectionManager>().client;
joinRoom();
}
public void joinRoom()
{
TypedLobby sqlLobby = new TypedLobby("skillLobby", LobbyType.SqlLobby);
string sqlLobbyFilter = "C0 BETWEEN 100 AND 200";
_client.OpJoinRandomRoom(null, MatchMaker.MaxPlayers, MatchmakingMode.FillRoom, sqlLobby, sqlLobbyFilter);
}
public void createRoom()
{
RoomOptions o = new RoomOptions();
o.MaxPlayers = MatchMaker.MaxPlayers;
o.CustomRoomProperties = new Hashtable() { { "C0", Game.Me.getInt("trophies") } };
o.CustomRoomPropertiesForLobby = new string[] { "C0" }; // this makes "C0" available in the lobby
TypedLobby sqlLobby = new TypedLobby("skillLobby", LobbyType.SqlLobby);
_client.OpCreateRoom("", o, sqlLobby);
}
private void onEvent(EventData obj)
{
if (_client.CurrentRoom != null)
{
if (_client.CurrentRoom.PlayerCount >= _client.CurrentRoom.MaxPlayers)
{
// sweet I am good to go.
}
}
else
{
createRoom();
}
}
The problem is this is pretty unreliable. Say two players try to find a game at the same time they will both search fail and then both create. Now I have two players sitting in empty rooms instead of playing each other.
Any ideas on a better system?
Thanks all.
Thank you for choosing Photon!
First of all, there are few things that you should understand about Photon:
you can't use JoinOrCreate() with the sql lobby type
This is not correct.
Where did you read such thing?
Did you test this yourself? What did you test exactly?
onEvent (LoadBalancingClient.OnEventAction) callback cannot be used to be notified of a failed join random room operation. Instead, you should make use of the LoadBalancingClient.OnOpResponseAction callback, as follows:
private void OnOpResponse(OperationResponse operationResponse)
{
switch (operationResponse.Code)
{
case OperationCode.JoinRandomGame:
if (operationResponse.ReturnCode == ErrorCode.NoMatchFound)
{
createRoom();
}
break;
}
}
To detect a join event inside a room (local or remote player entered a room):
private void onEvent(EventData eventData)
{
switch (eventData.Code)
{
case EventCode.Join:
int actorNr = (int)eventData[ParameterCode.ActorNr];
PhotonPlayer originatingPlayer = this.GetPlayerWithId(actorNr);
if (originatingPlayer.IsLocal)
{
}
else
{
}
break;
}
}
To answer your question:
Say two players try to find a game at the same time they will both
search fail and then both create.
Any ideas on a better system?
No.
This issue happens only during the development phase where you use a few clients to run some tests. Once you have enough user base you won't notice this issue.
So, this is the problem I am stuck at for a few weeks.
I am developing an Eclipse plugin which fills in a View with custom values depending on a particular StackFrame selection in the Debug View.
In particular, I want to listen to the stackframe selected and would like to get the underlying IStackFrame object.
However, I have tried more than a dozen things and all of them have failed. So I tried adding DebugContextListener to get the DebugContextEvent and finally the selection. However, the main issue is that ISelection doesn't return the underlying IStackFrame object. It instead returns an object of type AbstractDMVMNode.DMVMContext. I tried getting an adapter but that didn't work out too. I posted this question sometime back also:
Eclipse Plugin Dev- Extracting IStackFrame object from selection in Debug View
Since then, I have tried out many different approaches. I tried adding IDebugEventSetListener (but this failed as it cannot identify stack frame selection in the debug view).
I tried adding an object contribution action but this too was pointless as it ultimately returned me an ISelection which is useless as it only returns me an object of class AbstractDMVMNode.DMVMContext and not IStackframe.
Moreover, I checked out the implementation of the VariablesView source code itself in the org.eclipse.debug.ui plugin. It looks like a few versions back (VariablesView source code in version 3.2), the underlying logic was to use the ISelection and get the IStackFrame. All the other resources on the internet also advocate the same. However, now, this scheme no longer works as ISelection doesn't return you an IStackFrame. Also, the source code for the latest eclipse Debug plugin (which doesn't use this scheme) was not very intuitive for me.
Can anyone tell how I should proceed ? Is hacking the latest Eclipse source code for VariablesView my only option ? This doesn't look like a good design practice and I believe there should be a much more elegant way of doing this.
PS: I have tried all the techniques and all of them return an ISelection. So, if your approach too return the same thing, then it is most likely incorrect.
Edit (Code snippet for trying to adapt the ISelection):
// Following is the listener implemnetation
IDebugContextListener flistener = new IDebugContextListener() {
#Override
public void debugContextChanged(DebugContextEvent event) {
if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
contextActivated(event.getContext());
}
};
};
// Few things I tried in the contextActivated Method
//Attempt 1 (Getting the Adapter):
private void contextActivated(ISelection context) {
if (context instanceof StructuredSelection) {
Object data = ((StructuredSelection) context).getFirstElement();
if( data instanceof IAdaptable){
System.out.println("check1");
IStackFrame model = (IStackFrame)((IAdaptable)data).getAdapter(IStackFrame.class);
if(model != null){
System.out.println("success" + model.getName());
}
}
}
}
// Attemp2 (Directly getting it from ISelection):
private void contextActivated(ISelection context) {
if (context instanceof StructuredSelection) {
System.out.println("a");
Object data = ((StructuredSelection) context).getFirstElement();
if (data instanceof IStackFrame) {
System.out.println("yes");
} else {
System.out.println("no" + data.getClass().getName());
}
}
// This always execute the else and it prints: org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode.DMVMContext
}
// Attemp3 (Trying to obtain it from the viewer (similiar to object action binding in some ways):
private void contextActivated(ISelection context) {
VariablesView variablesView = (VariablesView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(IDebugUIConstants.ID_VARIABLE_VIEW);
if (variablesView != null) {
Object input = ((TreeViewer) variablesView.getViewer()).getInput();
if(input != null) System.out.println(input.getClass().getName());
if (input instanceof IStackFrame) {
System.out.println("success");
} else if (input instanceof IThread) {
System.out.println("success");
try {
IStackFrame[] stackFrames = ((IThread) input).getStackFrames();
for (IStackFrame iStackFrame : stackFrames) {
printVariables(iStackFrame);
}
} catch (DebugException e) {
e.printStackTrace();
}
}
}
}
While I am building this view to work with both JDT & CDT, I am testing it out on the C project. So, this might be the reason why I always get the returned object type as AbstractDMVMNode.DMVMContext. Should my implementation be different to handle both these cases ? I believe I should be building a generic view. Also, if AbstractDMVMNode.DMVMContext is CDT specific, I should I go about implementing it for the CDT case?
I started using Parse on Unity for a windows desktop game.
I save very simple objects in a very simple way.
Unfortunately, 10% of the time, i randomly get a 404 error on the SaveAsynch method :-(
This happen on different kind of ParseObject.
I also isolated the run context to avoid any external interference.
I checked the object id when this error happen and everything looks ok.
The strange thing is that 90% of the time, i save these objects without an error (during the same application run).
Did someone already got this problem ?
Just in case, here is my code (but there is nothing special i think):
{
encodedContent = Convert.ToBase64String(ZipHelper.CompressString(jsonDocument));
mLoadedParseObject[key]["encodedContent "] = encodedContent ;
mLoadedParseObject[key].SaveAsync().ContinueWith(OnTaskEnd);
}
....
void OnTaskEnd(Task task)
{
if (task.IsFaulted || task.IsCanceled)
OnTaskError(task); // print error ....
else
mState = States.SUCEEDED;
}
private void DoTest()
{
StartCoroutine(DoTestAsync());
}
private IEnumerator DoTestAsync()
{
yield return 1;
Terminal.Log("Starting 404 Test");
var obj = new ParseObject("Test1");
obj["encodedContent"] = "Hello World";
Terminal.Log("Saving");
obj.SaveAsync().ContinueWith(OnTaskEnd);
}
private void OnTaskEnd(Task task)
{
if (task.IsFaulted || task.IsCanceled)
Terminal.LogError(task.Exception.Message);
else
Terminal.LogSuccess("Thank You !");
}
Was not able to replicate. I got a Thank You. Could you try updating your Parse SDK.
EDIT
404 could be due to a bad username / password match. The exception messages are not the best.
I am a newbie in writing linux device driver, forgive me if anything stupid a asked and my poor English^^
I am trying to write a driver for a touch panel, which communicate with CPU via I2C.
I tried to add a device driver into linux platform, and the register was success, I mean the driver was loaded, but the probe function didn't fired up!!
Above is partial code of the driver i wrote.
static int i2c_ts_probe(struct i2c_client *client, const struct i2c_device_id * id) {
/* ... */
}
static int i2c_ts_remove(struct i2c_client *client) {
/* ... */
}
static const struct i2c_device_id i2c_ts_id[] = {
{"Capacitive TS", 0},
{ }
};
MODULE_DEVICE_TABLE(i2c, i2c_ts_id);
static struct i2c_driver i2c_ts = {
.id_table = i2c_ts_id,
.probe = i2c_ts_probe,
.remove = i1c_ts_remobe,
.driver = {
.name = "i2c_ts",
},
};
static int __init i2c_ts_init(void) {
return i2c_add_driver(&i2c_ts);
}
static int __init i2c_ts_exit(void) {
return i2c_del_driver(&i2c_ts);
}
module_init(i2c_ts_init);
module_exit(i2c_ts_exit);
Above is partial code in platform (/kernel/arch/arm/mach-pxa/saarb.c) used for registering the i2c device.
static struct i2c_board_info i2c_board_info_ts[] = {
{
.type = i2c_ts,
.irq = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO0)),
},
};
static void __init saarb_init(void) {
...
i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info_ts));
...
}
any suggestion and comment will be welcome, thanks^^
So that the linux device/driver model can probe your driver, there must be a device requesting it: this is achieved by comparing the name of the driver ("i2c_ts") and the type of the device in the i2c_board_info struct. In your case I guess the type is not equal to "i2c_ts".
So I would suggest that you use the I2C_BOARD_INFO macro to instantiate your device, as documented in Documentation/i2c/instantiating_devices.
static struct i2c_board_info i2c_board_info_ts[] = {
{
I2C_BOARD_INFO("i2c_ts", 0x12),
.irq = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO0)),
},
};
static void __init saarb_init(void) {
...
i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info_ts));
...
}
You had also not given an address to your device, and I2C_BOARD_INFO needs it. Read the datasheet of your touchscreen to know what that address is.
Finally, as suggested above, be sure that i2c_ts_id is correct. I am not sure it plays a role in the device/module association mechanism in the kernel, but I would say it's far less confusing it they all share the same name.
Probe method will only be called when the device matches the driver name.As you have mentioned your driver name as 'i2c_ts' please check your device tree for the device name.Both should be same.