-
Notifications
You must be signed in to change notification settings - Fork 44
Conversation
This is actually quite a bit of changes under the hood, but for the sake of keeping stable commits I'm going to put it all together. * Adopt Butterknife's approach to making all generates classes implement a IBarbershopInterface, and do class lookups of this interface rather than method lookups * Fix inheritance by determining if a generated class has a parent and then extending from the parent instead of implementing the IBarbershopInterface. This way, style() can just call super.style() to ensure that the entire hierarchy runs
I'm not convinced that calling Using the example in your When I have some time I'll try to adapt your test case to illustrate this (it's still speculation at this point). |
Hmm, you might be right. When I expanded the tests a bit, it now starts to fail. My guess is that the only solution here is that the generated class has to know the Would really rather prefer to keep the API the same if at all possible right now, or at least have it just be deprecated for a couple releases. I did look at adding class annotations to specify this up front, but Java doesn't like this because it doesn't consider Any ideas? |
I have an idea. Since So going on that, we could make
This way, the |
That could work, but it would come at the expense of the current caching On Wed, Mar 4, 2015 at 4:29 AM Denley Bihari notifications@github.com
|
I did take into consideration that Keep in mind that each target object can only be styled once in its entire existence, since it happens in the constructor. The There is a performance drawback, which is that it would hold a reference to every |
so the set would just continue to grow and grow through the app's lifecycle as more instances are used? I've been tinkering with this today, and there's kind of a catch 22 regarding the two approaches. One is to cache the class like I mentioned and create a new instance of it when called, but this results in all I'm leaning pretty hard toward doing something to include the |
This is correct, but in practice it can actually never be called again on the same target. The Based on this, we might even be able to get away with this instead:
While I think the above solution would work, I think you're probably right to lean toward having the user specify the The downside is that it means deprecating the |
Yeah, I'm going to give your suggestion a try before deciding anything. Unfortunately, your |
This adds some checking and methods to do so. Essentially, each $$Barbershop instance has a WeakReference<T> field that holds a reference to the last target styled (which should fall through from parent to children). If a style() method is called, it will only call the super's style method if the parent hasn't been styled yet, otherwise it proceeds as normal and updates the current last target styled with itself. This however isn't threadsafe
So that solution worked (including using weakreferences). Since the code is there and ready, I'd like to run with this if possible. It's not too much added work/code, but another issue is that it isn't thread-safe. This normally wouldn't be an issue for probably 95% of use cases since most drawing is done on the UI thread. There are cases though where you construct a view off of the UI thread though (such as pre-loading view or for taking snapshots). Going to think on this some more tonight. |
Hmm, you're right. It seems that array parameters for annotations must not just be constants, but they must actually be an array of constants declared inside the annotation. I guess it's because it has to be used at compile time, and even values inside array constants can be changed at runtime. On that note, this complete joke of code will actually compile: Anyway, back to the topic at hand. For your latter approach, I think that you will have trouble determining the package name of At runtime, you could use Maybe the The threading issue you mentioned is a very good point. Maybe using |
Well, the Barbershop does fortunately know the class name at compile time, so it wouldn't be too difficult. Basically just default to doing something like |
I meant that you won't be able to reference |
Ah, yeah I see what you mean |
The package of the target class is not necessarily the same as the package of the Android project. |
Yeah I realized what you meant right after I posted, edited my comment already :P |
This *should* make things threadsafe, as each reference can only check against parents using the same refs. WeakHashSet is nice because it also automatically prunes itself of stale references.
I think I got it working in multithreaded situations using a WeakHashSet implementation, similar to what you were describing earlier in the thread. It automatically prunes itself as well. @denley @emilsjolander please take a look if you have time, hopefully should be ready to merge at this point |
Nice work. I think that hits the nail on the head. My only other thought it that it might be prudent to do some check to make sure that |
Yeah I'm not sure how that implementation would work off the top of my head. I think I'm just going to merge this as-is for now and can revisit that if anyone actually runs into that issue. |
LGTM |
This should address #4. I was thinking I could get around this by using parameterized classes, and to my good fortune it turned out Butterknife had a pretty decent solution for this. @emilsjolander would you mind taking a look and see what you think? @denley you as well if you're interested, since you opened the issue.
style()
methods run.This functionally works, but I'm slightly concerned about one thing that I'm going to mull over tomorrow. Right now, it traverses the entire hierarchy. So if you have a parent with a child and grandchild, you conceivably could have the parent getting styled three times (that is, once for the parent's constructor, once for the child's, and one more for the grandchild). I'm not sure how to get around this yet though, if at all.I should write better tests.Now, if you have a
TestView
andChildTestView
that extends it, Barber will generate code that looks like this: