reactiveui / splat Goto Github PK
View Code? Open in Web Editor NEWMakes things cross-platform
License: MIT License
Makes things cross-platform
License: MIT License
Xamarin does not include System.Drawing in its list of supported .Net assemblies, so projects that depend on Splat (notably also those that use RxUI) are stuck having to hand-edit .csproj files in order to point to the right version of assemblies. This is a major PITA and trolls new people.
Might be useful to have Splat downsize the image using inSampleSize to minimize memory usage for the desired output size.
Something along the lines of how this works:
https://github.com/thest1/LazyList/blob/master/src/com/fedorvlasov/lazylist/ImageLoader.java
I tried to download the following file: http://pbs.twimg.com/profile_images/488751537720922112/8tBkI3WN_normal.jpeg
It then gets saved in a IBitmap, but is obviously an html page. I then had a check in my code that see's if the IBitmap instance is null (which it's not) and then checks that the Width and Height are greater than 0. Splat then throws an exception when trying to work out the Width and Height.
You should have a property in IBitmap called IsValid or something for the user to check that the IBitmap is in fact a proper image. At least then when Width or Height throws an exception it's easy enough to figure out that IsValid is indeed false. Or return null from BitmapLoader if image is not valid.
byte[] data = await DownloadImage(url, token);
IBitmap item = await BitmapLoader.Current.Load(new MemoryStream(data), null, null); // does not return a valid image
WrappingFullLogger
always prefixes log entries, which can be annoying if you're writing your own logger and don't want said prefixes.
Two possible solutions I can think of:
includePrefix
optional argument to the WrappingFullLogger
constructorWrappingPrefixLogger
which just implements ILogger
. Then change DefaultLogManager
so that it wraps the given ILogger
inside WrappingPrefixLogger
, then wraps that inside WrappingFullLogger
.Will PR both options.
Creating a new instance of DebugLogger
and calling DebugLogger.Write(message, level)
doesn't print anything to the console. If I copy the implementation and paste it into the current project, and use that instance instead, everything works fine.
Is it an issue that you're building the Splat libraries in Release mode and thus Debug.WriteLine
is being omitted from the IL? Would using Trace.WriteLine
solve this issue? or maybe defining the DEBUG symbol within Logging.cs so that the Debug calls are left alone?
Literally not a real issue per-se, as it can be remedied by re-implementing ILogger in a small amount of lines, but it did leave me dumbfounded for a good few minutes while trying to learn ReactiveUI with Splat's logging.
The IFullLogger
interface lacks any IsXxxEnabled
properties, such as IsDebugEnabled
. This makes it more difficult for client code to selectively skip logging statements. As such, it becomes harder to skip logging in performance sensitive scenarios.
A real-world motivating example can be found in this ReactiveUI code, copied here for convenience:
this.Log().Info("Item hash: 0x{0:x}", toTrack.GetHashCode());
This code appears in the bowels of ReactiveList
. Every time an item is tracked, its hash is calculated purely for the purposes of logging, even when Info
-level logging has been disabled. What I'm proposing is to at least facilitate the following:
if (this.Log().IsInfoEnabled)
{
this.Log().Info("Item hash: 0x{0:x}", toTrack.GetHashCode());
}
It's still up to client code to decide whether it is worth wrapping the logging call in an if
, but at least the option would be there.
I just tried to add a nuget reference to Splat from a iOS and Android PCL and received the error "Could not install package 'Splat 1.3.1'. You are trying to install this package into a project that targets 'portable-net45+sl50+MonoAndroid10+MonoTouch10', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author." I setup my PCL to just target Android and iOS and it included .Net 4.5 and Silverlight 5 by default. Would you be able to add support for this configuration?
Reproduce by creating a new Blank Page project (applies to both Windows 8 and Windows 8.1 preview), taking this bmp file, drop it into Assets/failure.bmp, and then putting this code into MainPage.xaml.cs.
It proceeds to explode with this exception:
An exception of type 'System.Exception' occurred in mscorlib.dll but was not handled in user code
Additional information: The image is unrecognized. (Exception from HRESULT: 0x88982F60)
And with pre-0.3.0 code:
An exception of type 'System.Exception' occurred in mscorlib.dll but was not handled in user code
Additional information: The component cannot be found. (Exception from HRESULT: 0x88982F50)
This is probably more of a WinRT issue (I feel for you with those comments you've written), though I'm not getting my hopes up too much for it to be fixed on the WinRT side at this point in time
(copied from reactiveui/Akavache#169)
I installed Akavache 4.0 via nuget, and with this code, I get the exception (WP8.1 WinRT project):
var image = new BitmapImage();
var source = ...
var sb = await BlobCache.LocalMachine.LoadImageFromUrl(source);
using (var ms = new MemoryStream())
{
await sb.Save(CompressedBitmapFormat.Png, 1.0f, ms);
image.SetSource(System.IO.WindowsRuntimeStreamExtensions.AsRandomAccessStream(ms));
}
Exception details:
{System.TypeInitializationException: The type initializer for 'Akavache.BlobCache' threw an exception. ---> System.IO.FileLoadException: Could not load file or assembly 'Splat, Version=1.3.3.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
at System.Type.GetType(String typeName, Boolean throwOnError)
at Akavache.DependencyResolverMixin.InitializeAkavache(IMutableDependencyResolver This)
at Akavache.BlobCache.<.cctor>b__0()
at Splat.Locator.RegisterResolverCallbackChanged(Action callback)
at Akavache.BlobCache..cctor()
--- End of inner exception stack trace ---
at Akavache.BlobCache.get_LocalMachine()
at (my program here)
The "The located assembly's manifest definition does not match the assembly reference." part is likely the issue here. I'm using Splat
in the source, and I see Splat in my project references, and I have Splat.dll
in packages\Splat.1.3.3\lib\Portable-Win81+Wpa81
, but when I inspect the file, it's not version 1.3.3.0, it's version 0.0.0.0:
I was having issues with a ReactiveList complaining about there being no dispatcher on the current thread. After digging a bit, I checked to see how ReactiveUI was deciding what schedulers to use for unit testing. That lead me to splat. The below test fails:
[TestMethod]
public void ShouldBeInUnitTestRunner()
{
ModeDetector.InUnitTestRunner().Should().BeTrue("this is a unit test");
}
This is a full framework WPF application running against .NET 4.5.2, and i am using mstest for my test assembly.
My questions:
In Splat\WinRT\Bitmaps.cs, on line 36, it states that alpha is "decoder.BitmapAlphaMode", which for my PNGs seems to be "BitmapAlphaMode.Ignore". Changing it to "BitmapAlphaMode.Premultiplied" allows my PNGs' alpha channels to work as expected.
↑ above. Its white text, which doesn't show up on a white background.
[Get("/api/users/{userid}/profileImage")]
Task<HttpResponseMessage> GetProfileImage(string userId, [Header("Authorization")] string authorization);
/// <summary>
/// Gets the current user's profile image
/// </summary>
/// <returns></returns>
public async Task<IBitmap> GetCurrentUsersProfileImage()
{
var response = await Api.GetProfileImage("current", AuthorizationHeader);
var stream = await response.Content.ReadAsStreamAsync();
return await BitmapLoader.Current.Load(stream, null, null);
}
This code gives the exception:
A first chance exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll
Additional information: This Freezable cannot be frozen.
Platform details:
Calling
this.Log().Debug(
"Set value of {0}.{1} (#{2:x8}) to '{3}'",
this.GetType().Name,
property.Name,
this.GetHashCode(),
value);
Gives the following exception:
An unhandled exception of type 'System.Reflection.TargetParameterCountException' occurred in mscorlib.dll
Additional information: Parameter count mismatch.
Stacktrace:
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Splat.WrappingFullLogger.Debug(String message, Object[] args) in z:\github\splat\Splat\Logging.cs:line 270
at Perspex.PerspexObject.SetValue(PerspexProperty property, Object value) in d:\projects\Perspex\Perspex\PerspexObject.cs:line 412
at Perspex.PerspexObject.SetValue[T](PerspexProperty`1 property, T value) in d:\projects\Perspex\Perspex\PerspexObject.cs:line 461
at Perspex.Controls.TemplatedControl.set_Template(Func`2 value) in d:\projects\Perspex\Perspex\Controls\TemplatedControl.cs:line 29
at Perspex.Controls.TemplatedControl..ctor() in d:\projects\Perspex\Perspex\Controls\TemplatedControl.cs:line 23
at Perspex.Controls.ContentControl..ctor() in d:\projects\Perspex\Perspex\Controls\ContentControl.cs:line 18
at Perspex.Windows.Window..ctor() in d:\projects\Perspex\Perspex.Windows\Window.cs:line 34
at TestApplication.Program.Main(String[] args) in d:\projects\Perspex\TestApplication\Program.cs:line 48
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
What are people's thoughts on clipboard support? It seems easy enough theoretically.
So it turns out Windows Phone only supports write-only, text-only access.
I'm guessing that the design of Splat right now is that everything that is provided should be usable, instead of needing to if (Foo.CanPerformThisAction(HugeEnum.Format))
, so maybe this is out of scope?
Using splat on the beta channel of Xamarin right now with Unified Xamarin.Mac 1.12.0.4 and Color is no longer an understood reference. Note that it IS available on the stable channel (1/29/15) Unified Xamarin.Mac 1.10.0.18. But Xamarin support says this was removed in 1.12 as part of the ongoing transition of the Mac stuff to Unified.
I think the fix may be to include the Colors folder into the Splat-XamarinMac project. But then Splat will not build due to the TypeForwardedTo's in TypeForwardedSystemDrawing.cs. Could change the preprocessor logic there to "#if !UNIFIED" but that raises the larger question of all the places where "#if UIKIT" kinds of things are going on. Maybe they all should be just based on UNIFIED going forward, not sure yet.
I read the Logging part of Readme.md, but I still don't know how to use it. Could you be more specific? Or give me a sample?
As well as resizing images, is there a way to reduce the quality or change the quality setting that is used when resizing? (i.e. if it is a JPEG)
I am looking for a way to shrink the photos taken with the camera before sending to my API. I've seen several libraries that shrink photos and some that compress them, but so far haven't seen any that do both,
This library looks very full featured, but I couldn't see how to do this. Or maybe I'm missing the point here and compression is not really needed?
Cheers,
Rob
Hi, I'm interested in using splat but is it portable? When I try to nuget it doesn't show up for my portable library.
Update. I see the problem, I was supporting Silverlight 5 in my portable class. Any way to make splat also work with this? For now I have unchecked SL5.
I suspect it's because the library was built for release, and Debug.WriteLine is culled from the resulting binary.
Looks like there's some issues with using this with MonoMac instead of Xamarin.Mac. I know the readme doesn't list MonoMac support, but I thought I'd raise the issue to see if it's worth fixing. So there's a few things:
I tried using this addin to install via NuGet into a MonoMac project and got the WPF version. Not sure where the source of the issue would be.
Then tried manually changing the reference to ..\packages\Splat.0.3.3\lib\MonoMac\Splat.dll
, but it seems that it's the Android version (dependency on Mono.Android)
Finally tried referencing the monomac csproj, and needed to change the XamMac reference to MonoMac. It looks like NSColor.FromSrgb is exclusive to XamMac however, so I've tried changing this to use NSColor.FromDeviceRgba
. I'm guessing that's probably not a good idea (possible colour space conversion?)
I can't step into splat - I can with Reactive UI, etc., and when I tell it to load symbols it claims "splat.pdb" couldn't be found.
Hi Paul!
Was trying out Splat... while using Bitmap.Save() I got a nasty exception (COM exception giving no information whatsoever)... after debugging I figured out that the ImageQuality encoding property is not supported when using the PNG format. For a list of supported shizzle... see: https://msdn.microsoft.com/en-us/library/windows/apps/jj218354.aspx
It seems the ImageQuality is only supported when using JPG. I confirmed this when switching to saving to JPG format... it works!
If I find some spare time, I'll create a PR for this. Do you agree that the fix is to not use the ImageQualtity when PNG is selected? So introduce a variable for the list of encoding options. An if-statement to check if JPG, and if so, add the image qualtity option. Otherwise, it will just be the empty list of encoding options
It just took me 1 hour to realize why DebugLogger
doesn't log anything (it's because it uses Debug.WriteLine
which gets thrown away when compiling in release mode). Maybe the default logger should be NullLogger
and DebugLogger
should be internal?
I heard you like threads in Windows.
BlobCache.LocalMachine.LoadImageFromUrl()
"Invalid cross-thread access."
at MS.Internal.XcpImports.CheckThread()
at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)
at System.Windows.Media.Imaging.BitmapImage..ctor()
at Splat.PlatformBitmapLoader.<>c__DisplayClass2.<Load>b__0()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Reactive.PlatformServices.ExceptionServicesImpl.Rethrow(Exception exception)
at System.Reactive.ExceptionHelpers.ThrowIfNotNull(Exception exception)
at System.Reactive.Subjects.AsyncSubject`1.GetResult()
at ThePaperWall.Core.Downloads.AsyncDownloadManager.<DownloadImage>d__4.MoveNext()
Unless I'm missing something, the LogHost.suppressLogging
field is never set to true
. Seems the whole concept could be culled.
I'm experimenting with using full linking on Xamarin. Ideally splat would include LinkerOverrides similar to ReactiveUI to prevent reflection exceptions. See below:
MonoDroid] UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for ReactiveUI.RxApp ---> System.TypeInitializationException: An exception was thrown by the type initializer for Splat.LogHost ---> System.TypeLoadException: Could not load type 'Splat.WrappingFullLogger' from assembly 'Splat, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
[MonoDroid] --- End of inner exception stack trace ---
[MonoDroid] at ReactiveUI.RxApp..cctor () [0x00000] in <filename unknown>:0
[MonoDroid] --- End of inner exception stack trace ---
[MonoDroid] at ReactiveUI.IReactiveObjectExtensions/ExtensionState`1
Hi,
I tried to download the Data using Splat library.
The sample code I used,
var wc = new WebClient();
byte[] imageBytes = await wc.DownloadDataTaskAsync("http://octodex.github.com/images/Professortocat_v2.png");
However, I am getting null data in the imageBytes variable. My network is using proxy. I tried to call by including proxy information also. But no luck.
The code with proxy info:
WebClient client = new WebClient();
WebProxy wp = new WebProxy("http://192.xxx.uu.yyy:zzzz");
client.Proxy = wp;
string str = client.DownloadString("http://www.google.com"); //works well. getting data
byte[] imageBytes = await client.DownloadDataTaskAsync("http://octodex.github.com/images/Professortocat_v2.png"); //receives null
Given that both Load and LoadFromResource are not actually async but rather run as tasks on the threadpool (at least on android/xaml) would be it possible to offer two versions of these APIs:
The main rationale is that if the code you are executing is already on a background thread or eventloop(wink) where you can block the thread safely, the cost of the context switch to the threadpool out weights the benefit of being async.
Also reading through the iOS code, I was curious why the work to load the image was being dispatched to the main thread. UIImage appears to be threadsafe (http://stackoverflow.com/questions/10645307/thread-safety-of-uiimage) and the APIs to load images block afaict. Why not run these on threadpool similar to android?
Is it a concern that IBitmap width/height doesn't report the real pixel width/height but instead it's dpi/platform/config dependent?
These two 512x512 pngs were extracted from an icns file: Image one (72dpi) Image two (144dpi)
Using WPF:
async void Blah()
{
var dlg = new Microsoft.Win32.OpenFileDialog();
dlg.Filter = "PNG Files (*.png)|*.png";
var result = dlg.ShowDialog();
if (result == true)
{
// Open document
string filename = dlg.FileName;
using (var stream = new FileStream(filename, FileMode.Open))
{
var bitmap = await Splat.BitmapLoader.Current.Load(stream, null, null);
MessageBox.Show("width " + (int)bitmap.Width + " height " + (int)bitmap.Height);
}
}
}
This reports 682x682 and 341x341 respectively at 100% DPI.
Using Cocoa:
async void Blah()
{
var openPanel = new NSOpenPanel();
openPanel.ReleasedWhenClosed = true;
openPanel.AllowedFileTypes = new[] { "png" };
var result = openPanel.RunModal();
using (var stream = new System.IO.FileStream(openPanel.Url.Path, System.IO.FileMode.Open))
{
var bitmap = await Splat.BitmapLoader.Current.Load(stream, null, null);
var alert = new NSAlert();
alert.MessageText = "width " + (int)bitmap.Width + " height " + (int)bitmap.Height;
alert.AddButton("OK");
alert.RunModal();
}
}
This reports 512x512 and 256x256 respectively at 200% DPI.
Hi,
I am writing a PCL making use of Splat System.Drawing.Color.
I am unit testing it in a .NET 4.5.1 test project. In my test method I initialize a test color so have a reference to the .NET Framework System.Drawing assembly in my test project as well as Splat 1.6.0.0 ( the .NET 4.5 version)
When my test goes into my PCL method and tries to construct a color I get the following Exception:
System.MissingMethodException Method not found: 'System.Drawing.Color System.Drawing.Color.FromKnownColor(System.Drawing.KnownColor)'.
Have I done something wrong? or is this a bug?
Hi! I have a little proposal for splat-2 logging facilities:
What do you think about replacing IFullLogger
methods like this
void ErrorException([Localizable(false)] string message, Exception exception);
by methods like this
void Error(Exception exception, [Localizable(false)] string message, params object[] args);
In my opinion it has two advantages: 1) there is no need to use String.Format
inside ErrorException
call and actual formatting could be done by wrapped logging library (that is quite important for Serilog) and 2) these methods don't need Exception
suffix.
After testing akavache successfully, I'm starting to use Splat in our mvvmcross based project. It has a core project that is a PCL (profile78) with an ios "app" project linked to it. Without any IBitmaps in the PCL code - it works and I can get IBitmaps (and use ToNative() on them) in the iOS side. However,
if I even declare a single variable in the PCL project as an IBitmap, I get the following error(s):
Missing method ToNative in assembly /Users/PATHTOAPP/MyAppName.app/MyAppName.exe, type Splat.BitmapMixins
(and a while later in the midst of some mvvmcross debug spam)
TypeLoadException: Could not load type 'Splat.BitmapMixins' from assembly 'MyAppName'
I'm not even using the variable, just declared it. Using IBitmaps and those from the Akavache.LoadImage() functions did but only on the iOS side. The reference in the PCL side is:
F:\PATHTOAPP\packages\Splat.1.4.1\lib\Portable-net45+win+wpa81+wp80\Splat.dll
and the reference on the iOS side is:
F:\PATHTOAPP\packages\Splat.1.4.1\lib\monotouch\Splat.dll
Akavache nuget added it to the project. And I have also added the splat reference before adding akavache to both the PCL and iOS project... I also removed all those references and re-added them to both PCL and iOS projects, Am I doing that wrong? What is the proper order to add them? Kind of dead in the water at the moment any help would be appreciated.
(EDITED in response to slodge pointing out a typo)
Running in a PCL under Xamarin Studio:
public void RectangleFContainFail() {
RectangleF big = new RectangleF(0, 0, 100, 100);
RectangleF small = new RectangleF(50, 50, 1.0000003f, 1.0000003f);
bool contains = big.Contains(small);
if (contains) {
PCLDebug.WriteLine ("contains");
} else {
PCLDebug.WriteLine ("Does not contain");
}
}
Output is "Does not contain".
Cant find any examples on the web.
in this example on the readme
var wc = new WebClient();
var imageBytes = await wc.DownloadDataTaskAsync("http://octodex.github.com/images/Professortocat_v2.png");
ProfileImage = await BitmapLoader.Current.Load(imageBytes, null /* Use original width /, null / Use original height */);
What is the type of ProfileImage?
What type is the ToNative method on?
Presumably the type that has the ToNative method is what i need to setup as a property in my view model?
What does ToNative return?
How do i feed the result of ToNative into an android image view?
Your libraries are really good and useful but so hard to use as the examples leave out context and dont follow through. Just a thought :)
Thanks,
Harry
In the ServiceLocation.InitializeSplat
method is this:
This.Register(() => new DebugLogger(), typeof(ILogger));
Of course, this results in a new DebugLogger
instance being created for every Log
call. Not only is this potentially wasteful for performance, but it also means this outwardly intuitive attempt to set the log level does not work:
Locator.Current.GetService<ILogger>().Level = LogLevel.Warn;
Is there a reason it can't be registered as a constant:
This.RegisterConstant(new DebugLogger(), typeof(ILogger));
I have created a class derived from IMutableDependencyResolver that resolves against Autofac. It works fine without replacing the logging.
I then replaced the logging library by implementing a full logger using NLog. The log manager has the following GetLogger:
public IFullLogger GetLogger(Type type)
{
return new NLogLogger(NLog.LogManager.GetCurrentClassLogger(type));
//return new NLogLogger(NLog.LogManager.GetLogger(type.FullName));
}
The uncommented line using GetCurrentClassLogger throws when trying to get a logger for Splat.LogHost. Here is the relevant exception info:
InnerException: NLog.NLogConfigurationException
_HResult=-2146233088
_message=Cannot access the constructor of type: Splat.LogHost. Is the required permission granted?
HResult=-2146233088
IsTransient=false
Message=Cannot access the constructor of type: Splat.LogHost. Is the required permission granted?
Source=NLog
StackTrace:
at NLog.Internal.FactoryHelper.CreateInstance(Type t)
at NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey)
at NLog.LogFactory.GetLogger(String name, Type loggerType)
at NLog.LogManager.GetCurrentClassLogger(Type loggerType)
at MyApp.Extensions.Splat.SplatNLogManager.GetLogger(Type type) in c:\Users\david\MyApp\Extensions\Splat\SplatNLogManager.cs:line 34
at Splat.LogHost.get_Default() in z:\code\paulcbetts\splat\Splat\Logging.cs:line 197
at ReactiveUI.RxApp..cctor()
If I remove Autofac, and just use the NLogLogger, it works. If I disable the NLogLogger, and keep autofac, it works. If I use the commented out line which gets a logger by name instead of type, it also works. So the resolution of the Type by NLog.GetClassLogger() seems to be an issue but only when using Autofac.
David
public void Debug()
{
var logger = Locator.Current.GetService<ILogManager>().GetLogger(typeof(ClassWithExistingField));
logger.Debug("jjh {0}", new object[]{ 1});
}
causes this
System.ArgumentException : Object of type 'System.Int32' cannot be converted to type 'System.Object[]'.
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Splat.WrappingFullLogger.Debug(String message, Object[] args) in Logging.cs: line 270
so in WrappingFullLogger
i thinks this
public void Debug(string message, params object[] args)
{
var sfArgs = new object[args.Length + 2];
sfArgs[0] = CultureInfo.InvariantCulture; sfArgs[1] = message;
Array.Copy(args, 0, sfArgs, 2, args.Length);
string result = (string)stringFormat.Invoke(null, sfArgs);
_inner.Write(prefix + result, LogLevel.Debug);
}
should be this
public void Debug(string message, params object[] args)
{
var sfArgs = new object[args.Length + 2];
sfArgs[0] = CultureInfo.InvariantCulture;
sfArgs[1] = message;
sfArgs[2] = args;
string result = (string)stringFormat.Invoke(null, sfArgs);
_inner.Write(prefix + result, LogLevel.Debug);
}
Let's say I have a bitmap picture:
Splat.IBitmap picture = ....
calling the Save method ends in a cross thread violation crash:
System.IO.Stream pictureStream = new System.IO.MemoryStream();
await picture.Save(Splat.CompressedBitmapFormat.Jpeg, 1.0f, pictureStream);
also, shouldn't the Save method return the Task to be awaited for?
lines 36 and 34 of Splat/Android/Bitmaps.cs:
BitmapFactory.DecodeStream(sourceStream).FromNative()
BitmapFactory.DecodeStream will return null if loading from a stream fails. See: http://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeStream(java.io.InputStream)
Since FromNative() doesn't verify that the argument is not null, this results in null pointer exceptions in user code when bitmap loading fails. Better behavior would be to cause the task returned by PlatformBitmapLoader.Load(Stream sourceStream) to fail with an IOException.
I would like to use this library in Xamarin Mac but looks like it is referencing PresentationCore, is it possible to not do so? Wait, I just noticed there is a monomac project. Does it work?
What do you think about adding an API to spawn additional event loop threads? The use case is to allow the dispatching of certain asynchronous work on to a single background thread, where it can benefit from having thread affinity for non-thread safe operations while not having to worry about executing work that could block the UI thread. Common use case would be making networking calls and then parsing response data on the thread. This works particularly nicely with F# Async workflows that make thread hopping trivial. I've included a potential API below, and could provide a PR with an Android implementation. Are there any cross platform issues, specifically for windows phone?
Potential API surface:
namespace Splat
{
public interface IEventLoop : IDisposable
{
SynchronizationContext Context { get; }
}
public static class EventLoop
{
Task<IEventLoop> Create()
{
throw new Exception("Could not create EventLoop. This should never happen, your dependency resolver is broken");
}
}
}
"This should never happen, your dependency resolver is broken"
I am not using a dependency resolver. Shouldn't the library be resolving this for me.
Have i missed something?
The calling code is in a test.
Console.WriteLine it or something on every platform that can Read Good And Do Other Stuff Good (aka not WinRT)
On WP8 the save function blows up with:
An exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.ni.dll but was not handled in user code
at MS.Internal.XcpImports.CheckThread()
at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)
at System.Windows.Media.Imaging.WriteableBitmap..ctor(BitmapSource source)
at Splat.BitmapSourceBitmap.<>c__DisplayClass1.<Save>b__0()
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at ThePaperWall.WP8.ViewModels.MainPageViewModel.<OnActivate>d__4.MoveNext()
I know. You're thrilled.
I don't think the BitmapLoader Load method actually resizes images in iPhone.
In iPhone I'm looking through the source code of Bitmaps.cs for Cocoa and there is no code using the two size variables.
I'm trying to use Akavache with Splat for image caching in a Xam Forms project. When unit testing, I kept getting the following error any time I access the cache:
Unexpected token while deserializing object: PropertyName. Path 'Value.Width'.
I created a simple console app that experiences the same problem when using the GetImage method or gets an invalid image exception when using GetImage2. The image is a just a sample I pulled from Google images, but is a valid image. The example App can be found in my Git repo
Hi Paul,
I'm so sorry for asking you this, since I know how much you love this platform, but I was wondering how are you using IBitmap. Let me explain how I tried using it and where it goes wrong.
I began with using Akavache to load an IBitmap in my view model from the cache using an url. This works, no problem. The image loads from the cache (and again from the web) and is displayed on the screen. But when my ListView is starting to get a lot of images, it crashed due to an OutOfMemoryException.
I tried detecting a potential memory leak; the WriteableBitmaps seems not to be released. So, I tried disposing them manually when the image goes out of the visual area, but disposing the IBitmap actually means that the stream is closed, and when you scroll back so that the image is visible again, there is no image loaded. Makes sense. So, disposing the image doesn't seem to work if you need to show (reload) the image again.
I tried implementing some data virtualization so that it only loads items visible and disposed those who are not, but Windows Phone is really vague here; you need to implement some weird interface, which isn't described in detail anywhere, nor anyone has an implementation. So, that's not an option as well.
Back to the OutOfMemoryException... the IBitmap is loaded in my viewmodel. When I don't show the image on screen, but just load it, I do run out of memory. So even just loading it, and keeping it in memory, is a problem. When I load it, and then immediately dispose it, the memory is stable again.
So, should I actually load the IBitmap in my viewmodel in the first place? It seems that this is not the way to go. But if I don't, what's the use of having a xplat bitmap implementation?
The Portable-Win81+Wpa81
folder in the NuGet package for Splat 1.3.1 contains the Profile78
assembly.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.